Pulled documentation into new repository.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Notes.txt Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,3 @@
+- Shouldn't the imgCache in SunToolkit be in AppContext rather than static field?
+- Same for the locks and probably a couple of more static fields there (mPeer, startupLocale)?
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/OpenJDK-proposal.txt Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,151 @@
+Draft proposal
+--------------
+
+
+ Portable GUI Backends
+
+ Roman Kennke and Mario Torre
+ aicas GmbH
+
+
+0. Summary
+----------
+
+In order to support the spread of Java for graphical applications,
+particularly in embedded systems, aicas proposes to improve the AWT and
+Java2D in OpenJDK to enable easier porting of AWT to new platforms.
+
+1. Introduction
+---------------
+
+The AWT is designed as an abstract toolkit (hence the name: abstract
+windowing toolkit). There is a public Java API, which is the same
+across all platforms, and platform specific implementation code for each
+supported platform. These two parts are isolated from each other
+through the AWT peer interface. This basically comprises the classes
+java.awt.Toolkit, java.awt.GraphicsEnvironment, the interfaces in
+java.awt.peer (which are not part of the spec), and a couple of related
+classes. By implementing these interfaces, it should be possible to
+create new backend implementations for AWT and (by extension) Java2D.
+
+Unfortunately, the current implementations do not abide by this
+interface. In various places in Swing and AWT, this interface is
+circumvented and OpenJDK specific implementation classes
+(e.g. SunToolkit, SunGraphics2D) are called directly. This defeats the
+whole purpose of having such an interface in the first place and makes
+porting AWT to new platforms unnecessarily hard or impossible without
+modifying Swing and AWT themselves. Not only does the code simply
+assume that the current implementation is the OpenJDK implementation,
+but the interface itself is often incomplete.
+
+To make things even worse, there is not an interface for font
+implementations. Instead, there is only one font implementation tied
+into various places in OpenJDK. Using this implementation in a new AWT
+backend implementation should, in theory a least, be possible; but again,
+the font implementation is so tied to internal implementation classes
+(e.g. SunGraphicsEnvironment) that this would not work either. Having a
+cleanly separated interface for the font implementation would enable
+reusing the existing implementation in a new AWT backend, or even for
+replacing the font implementation, e.g., with a platform-specific one.
+
+At a lower level in the Java2D stack, there are various interfaces and
+extension points which enable easy porting of the graphics stack. The
+OpenJDK Java 2D implementation has a rendering pipeline with various
+generic pipes and render loops, which make porting the graphics stack as
+easy as providing a render loop for setting and getting single pixels
+from the render surface, but still can be optimized by providing more
+powerful primatives. Usually graphics primitives such as lines,
+rectangles, and circles are needed for good performance, but one can
+also include more sophisticated operations such as blits, compositing,
+and transparency. This is generally a very well thought out design, but
+is also not without its problems. Because nobody seems to have ever
+created a AWT/Java2D port to another platform, the architecture does not
+allow for flexible extension at some points, e.g., volatile images[1].
+
+
+2. Goals and Deliverables
+-------------------------
+
+The project will have two parts. The first one focuses on the extending
+the external interface. The second on documenting and cleaning up the
+internal Java2D interface. In the end, it should be much easier to port
+to a new platform. This will be demonstrated with a concrete example.
+
+2.1 Extenal AWT/Java2D Peer Interface
+-------------------------------------
+
+As described above, it is currently not possible to provide an
+external implementations for the AWT and Java2D peer interfaces. The
+first goal of this project is to clean up the interface and the Swing
+and AWT implementation, so that it is possible to create an AWT
+backend without changing any details in Swing or elsewhere. It is
+important to note that there already are a couple of such
+implementations. For example, the FBToolkit project [2] and the Escher
+and GTK based peers in GNU Classpath [3], all of which require hacks
+and patches to OpenJDK code to actually work with OpenJDK. This
+subproject would cover the following tasks.
+
+- Improve Swing and AWT, so that they do not rely on specific
+ implementation details.
+
+- Add functionality to the AWT peer interface where necessary.
+
+- Propose a new interface for font implementations. This should at
+ least enable the reuse of existing font implemenation in new AWT
+ stacks. Ideally one could even use an external implementation for
+ fonts.
+
+- Document all the necessary interfaces which are required to port AWT
+ backends.
+
+- Create a proof-of-concept AWT/Java2D peer implementation that makes
+ use of these public interfaces (and not the internal implementation
+ classes).
+
+- Provide test cases for changed and new code.
+
+2.2 Internal Java2D Interfaces
+------------------------------
+
+Implementing a whole complete and compatible Java2D stack is a huge
+task, and not feasible for small to midsized projects. Considering
+that there are already all the necessary pieces in OpenJDK, it would
+be nice to make it possible to reuse these in new ports of AWT/Java2D
+backends. As described above, the general architecture does seem to
+enablle that, but has small problems in various places. Also, there is
+practically no documentation on how to implement an external rendering
+pipeline. This part of the project should improve this through the
+following tasks.
+
+- Extend the Java2D architecture to be reusable in new AWT/Java2D ports.
+
+- Document the architecture and interfaces to be used, including
+ an architectural overview, API documentation, and a tutorial.
+
+- Create a proof-of-concept implementation that makes use of OpenJDKs
+ rendering pipeline.
+
+- Provide test cases for changed and new code.
+
+
+3. Previous work
+----------------
+
+Mr. Kennke is the author of the Escher based toolkit in GNU Classpath,
+and has helped with the GTK based toolkit in GNU Classpath. Both of
+these implement the public interfaces only and work with Classpath's
+Swing. The authors have created (very) prototypical ports of these to
+OpenJDK [4] and create a very early prototype for a Java2D port based on
+the internal Java2D interfaces [5]. This work should demonstrate that
+the proposed project is feasible, and it will serve as a basis for
+further development.
+
+
+References:
+-----------
+
+[1] http://mail.openjdk.java.net/pipermail/2d-dev/2008-February/000142.html
+[2] https://fbtoolkit.dev.java.net/
+[3] http://www.gnu.org/software/classpath/
+[4] http://kennke.org/blog/2007/06/21/gtk-peers-on-openjdk/
+[5] http://kennke.org/blog/2008/02/25/escher-on-openjdk-graphics/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Portable AWT Backends Doku.txt Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,28 @@
+Relevant classes for porting AWT:
+
+External:
+
+java.awt.peer.*
+java.awt.Toolkit
+java.awt.GraphicsEnvironment
+ - java.awt.GraphicsDevice
+ - java.awt.GraphicsConfiguration
+java.awt.Graphics2D
+
+
+Internal:
+
+sun.awt.SunToolkit
+sun.java2d.SunGraphicsEnvironment
+sun.java2d.SunGraphics2D
+sun.java2d.SurfaceData
+sun.java2d.loops.Blit
+sun.awt.FontConfiguration
+sun.font.FontManager
+sun.java2d.pipe.PixelDrawPipe
+sun.java2d.pipe.PixelFillPipe
+sun.java2d.pipe.ShapeDrawPipe
+sun.java2d.pipe.GlyphListPipe
+sun.java2d.SurfaceManagerFactory
+sun.awt.image.VolatileSurfaceManager
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Tutorial_External_Interfaces.html Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,321 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+<title>Portable GUI Backends (The Caciocavallo project)</title>
+</head>
+<!--
+
+This is a nice recipe for preparing a great italian dish called
+"Linguine al Nero di Seppia" (linguine is a kind of pasta, nero di
+seppia is the black ink from the cuttlefish, or sepia).
+
+You need some seafood, but not much, then good italian linguine and the ink.
+You can find the ink in some specialized shop, try to get the good one. If you are lucky,
+you can even do it by yourself, from the cuttlebone ink bags (my granfather did it that way,
+and is the best way).
+
+First, the seafood.
+
+1. Some pieces of cuttlefish.
+2. Very few clams take 5 at most of dish.
+3. Very few mussels, like 3, 4 for dish.
+4. Maybe a couple of shrimps, small.
+
+You don't need much of all these, infact you can even not use them at all, so be conservative :)
+
+Now, fry in good olive oil a little piece of garlic. As soon as the garlic becomes golden, throw it away.
+Make the oil to cool down a little and then sprinkle some white wine on the oil and mix it.
+
+Add the cuttelfish and the shrimps and turn the fire on again. After a while, add the
+clams and the mussels, as they take less to cook. More or less at 3/4 of the cooking (you can spot it!)
+add the ink with some water. The final result should be dense, but not gluey. Turn off the fire.
+
+Pasta: Linguine, no discussion over this :)
+
+Just prepare them the usual (italian) way. When they are done, take out the water, turn on the fire under the pot with the ink
+and seafood, and put the pasta into it, mixing carefully, for one minute or less.
+
+If you like, you can add some olive oil on top. Instead of salting the water for the pasta, you can use
+"colatura di alici". Google for it, but I doubt you can find it outside Cetara/Salerno/Napoli.
+
+Serve on pasta dishes, with a leaf of parsley.
+
+-->
+
+<body>
+
+<h1>OpenJDK Challenge</h1>
+
+<h1>External Toolkit Implementation, a walkthrough</h1>
+
+<h2>Introduction</h2>
+<p>
+Using the public and semipublic peer interfaces it is
+possible to implement graphics backends for AWT and Java2D.
+This requires the implementation of the complete graphics stack, including the Toolkit,
+Graphics, and part of or all of fonts and image support.
+This can be quite a large task, but has the advantage that there are no assumptions about the underlying platform.
+</p>
+<p>
+This tutorial illuminates the external interfaces and
+classes that are relevant for implementing a graphics backend for a
+new system. A JavaDoc description of the API is available as part of the
+project.
+</p>
+
+<h2>Summary</h2>
+<ul>
+
+ <li>
+ Toolkit implementation
+ </li>
+
+ <li>
+ Provide top level AWT widget peers
+ </li>
+
+ <li>
+ Provide AWT widget peers
+ </li>
+
+ <li>
+ Provide a GraphicsEnvironment
+ </li>
+
+ <li>
+ Provide a graphics pipeline
+ </li>
+
+ <li>
+ VolatileImage support
+ </li>
+
+ <li>
+ Provide font implementation or configuration List of Classes
+ </li>
+</ul>
+
+<h2>Toolkit implementation</h2>
+
+<p>
+The starting point for implementing a graphics backend is the
+<code>java.awt.Toolkit</code>.
+</p>
+
+<p>
+The <code>Toolkit</code> abstract class provides many abstract methods that are
+meant to create the native peers for the AWT widgets and implement
+general toolkit functionality such as image handling, some font support,
+and some printing support.
+</p>
+
+<p>
+A large part of implementing <code>java.awt.Toolkit</code> is the
+implementation of the AWT peer interfaces in the package
+<code>java.awt.peer</code>. One should follow the API documentation
+for <code>Toolkit</code> and the required peer interfaces.
+</p>
+
+<p>
+In order to use a new <code>Toolkit</code> implementation, pass a system
+property to the VM like this:
+</p>
+
+<code>
+java -Dawt.toolkit=your.toolkit.Classname
+</code>
+
+<p>
+<strong>Note:</strong> that one may also need to provide a
+dedicated <code>GraphicsEnvironment</code>.
+</p>
+
+<h2>
+GraphicEnvironent, GraphicsDevice and GraphicsConfiguration
+</h2>
+
+<p>
+The <code>java.awt.GraphicsEnvironment</code> class is the other central entry
+point for implementing a graphics backend. It provides the
+graphics devices and graphics configuration information.
+</p>
+
+<p>
+In order to implement <code>java.awt.GraphicsEnvironment</code>, you will also have
+to provide implementations of <code>java.awt.GraphicsDevice</code> and
+<code>java.awt.GraphicsConfiguration</code>. Please review the API documentation
+for those classes as reference.
+</p>
+
+<p>
+In order to use your own <code>GraphicsEnvironment</code>, pass a system property
+to the VM like this:
+</p>
+
+<code>
+java -Djava.awt.graphicsenv=your.graphicsenv.ClassName
+</code>
+
+<p>
+<strong>Note:</strong> that you will most likely also want to use your own <code>Toolkit</code>
+implementation.
+</p>
+
+<h2>
+Graphics2D
+</h2>
+
+<p>
+As part of implementing the AWT peers and the <code>GraphicsEnvironment</code>, one
+also must provide an implementation for <code>java.awt.Graphics</code>, to be
+able to draw on the AWT components or images. While the API only mandates
+implementing <code>java.awt.Graphics</code>, it is very advisable to actually
+provide a <code>java.awt.Graphics2D</code> implementation, because many
+applications expect the <code>Graphics</code> object to actually be a <code>Graphics2D</code>
+object. Please refer to the API documentation of these two
+abstract classes for reference.
+</p>
+
+<h2>
+Fonts
+</h2>
+
+<p>
+The <code>Toolkit</code> is also resposible for creating a <code>Font</code> peer. However, this
+interface is not actively used anymore. There is an internal API for
+implementing fonts, which consist of a couple of classes and
+interfaces:
+</p>
+
+<pre>
+<code>
+sun.font.Font2D
+sun.font.FontManager
+sun.awt.FontConfiguration
+</code>
+</pre>
+
+<p>
+In order to implement a new font backend one has to provide a
+<code>FontManager</code> and all the referenced support classes.
+</p>
+<p>
+It is possible to reuse part of the existing <code>FontManager</code>
+code even in newly written toolkit, even if this is not portable to different
+implementation (see the internal interfaces documentation). For the
+most portable approach, just implement the methods described in the
+FontManager interface. Currently, there is an ongoing project to make
+this interface more portable and improve its documentation.
+</p>
+
+<p>
+<strong>Note</strong> that there is no public/semipublic API (like the AWT widget
+peers) for fonts right now.
+</p>
+<p>
+To use a new <code>FontManager</code> implementation,
+pass a system property to the VM:
+</p>
+
+<code>
+java -Dsun.font.fontmanager=your.fontmanager.ClassName
+</code>
+
+<p>
+it is also possible to set this property in the static initializer of the
+<code>GraphicsEnvironment</code> implementation:
+</p>
+<pre>
+<code>
+ static
+ {
+ System.setProperty("sun.font.fontmanager", "your.fontmanager.ClassName");
+ }
+</code>
+</pre>
+
+<h2>
+KeyboardFocusManagerPeer
+</h2>
+
+<p>
+It is possible to reuse the <code>FocusManagerPeer</code> in OpenJDK.
+Currently, a process is underway to make it more portable and this functionality
+should be ported into the <code>Toolkit</code>. For now, if one would like to provide a
+<code>KeyboardFocusManager</code>, one can set the <code>"sun.font.keyboardfocusmanager"</code>
+system property to point to a valid implementation of
+<code>KeyboardFocusManagerPeer</code>.
+</p>
+
+<h2>
+Further Readings
+</h2>
+
+<p>
+Please, refer to the <a href='Tutorial_Internal_Interfaces.html'>Internal Toolkit Implementation Tutorial</a> for more details on how to implement
+the <code>Toolkit</code> Interface, without needing to reimplement
+everything from scratch, and reuse most of the existing code in
+OpenJDK. Refer to the API documentation of the relevant classes and
+interfaces for details of the implementation.
+</p>
+
+<h2>
+Relevant classes
+</h2>
+
+<pre>
+<code>
+java.awt.Toolkit
+java.awt.GraphicsEnvironment
+java.awt.GraphicsDevice
+java.awt.GraphicsConfiguration
+java.awt.Graphics
+java.awt.Graphics2D
+sun.font.Font2D
+sun.font.FontManager
+sun.awt.FontConfiguration
+sun.awt.KeyboardFocusManagerPeerImpl
+</code>
+</pre>
+
+<p>
+in <code>java.awt.peer</code>:
+</p>
+
+<pre>
+<code>
+ButtonPeer
+CanvasPeer
+CheckboxMenuItemPeer
+CheckboxPeer
+ChoicePeer
+ComponentPeer
+ContainerPeer
+DesktopPeer
+DialogPeer
+FileDialogPeer
+FontPeer
+FramePeer
+KeyboardFocusManagerPeer
+LabelPeer
+LightweightPeer
+ListPeer
+MenuBarPeer
+MenuComponentPeer
+MenuItemPeer
+MenuPeer
+MouseInfoPeer
+PanelPeer
+PopupMenuPeer
+RobotPeer
+ScrollbarPeer
+ScrollPanePeer
+SystemTrayPeer
+TextAreaPeer
+TextComponentPeer
+TextFieldPeer
+TrayIconPeer
+WindowPeer
+</code>
+</pre>
+</body>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/Tutorial_Internal_Interfaces.html Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,859 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+<title>Portable GUI Backends (The Caciocavallo project)</title>
+</head>
+<body>
+
+<h1>OpenJDK Challenge</h1>
+
+<h1>Internal Toolkit Implementation Tutorial</h1>
+
+<h2>Introduction</h2>
+
+<p>
+By using the public and semipublic peer interfaces, it is possible to
+implement graphics backends for AWT and Java2D, as described
+in <a href='Tutorial_External_Interfaces.html'>External Toolkit
+Implementation, a walkthrough</a>. However, this requires
+implementing the complete graphics stack, including the Toolkit,
+Graphics, and a part of or all of fonts and image support. This can
+be quite a large task. On the other hand, OpenJDK already has a lot of code
+that can be reused to implement most of the above mentioned
+subsystems. This tutorial describes the internal interfaces and
+classes that are relevant for implementing a graphics backend for a
+new system.
+</p>
+
+<h2>Summary</h2>
+
+<ul>
+ <li>Provide a Toolkit implementation</li>
+ <li>Provide top level AWT widget peers</li>
+ <li>Provide AWT widget peers</li>
+ <li>Provide a GraphicsEnvironment</li>
+ <li>Provide a graphics pipeline</li>
+ <li>VolatileImage support</li>
+ <li>Provide font implementation or configuration</li>
+</ul>
+
+<h2>Toolkit implementation</h2>
+
+<p>
+The starting point for implementing a graphics backend should be to
+implement <code>java.awt.Toolkit</code>. In OpenJDK there is a base
+implementation of this class called <code>sun.awt.SunToolkit</code>,
+from which all of the internal toolkit implementations are derived,
+and upon which new implementations may be based. This provides
+implementations for the image subsystem as well as a couple of useful
+default implementations for other areas. It is still necessary to
+provide implementations for most of the AWT widget peers. (However, it
+will be possible in the future to plug in portable platform
+independent Swing based widget peers.)
+</p>
+
+<h2>Methods with usable default implementation in SunToolkit</h2>
+
+<pre>
+ <code>
+ public FontMetrics getFontMetrics(Font font);
+ public String[] getFontList();
+ </code>
+</pre>
+
+<p>
+Those two methods provide the necessary font support and hook into the
+font subsystem of OpenJDK. This only needed to be implemented when a new font subsystem is needed.
+</p>
+
+<pre>
+ <code>
+ public PanelPeer createPanel(Panel target);
+ public CanvasPeer createCanvas(Canvas target);
+ </code>
+</pre>
+
+<p>
+These calls provide default implementations for the <code>Panel</code>
+and <code>Canvas</code> peers. Both use the default peers for
+lightweight components, so the functionality might be limited. Some
+applications expect <code>Panel</code> and <code>Canvas</code> to be
+real heavyweights, so one might need to override this.
+</p>
+
+<pre>
+ <code>
+ public Image getImage(String filename);
+ public Image getImage(URL url);
+ public Image createImage(String filename);
+ public Image createImage(URL url);
+ public Image createImage(byte[] data, int offset, int length);
+ public Image createImage(ImageProducer producer);
+ public int checkImage(Image img, int w, int h, ImageObserver o);
+ public boolean prepareImage(Image img, int w, int h, ImageObserver o);
+ </code>
+</pre>
+
+<p>
+These methods implement the image related methods of <code>java.awt.Toolkit</code>
+and hook into the image subsystem of OpenJDK. Unless a new image subsystem is needed,
+these methods need not be override.
+</p>
+
+<pre>
+ <code>
+ protected EventQueue getSystemEventQueueImpl();
+ </code>
+</pre>
+
+<p>
+This method provides a default system event queue, that should be
+perfect for most toolkit implementations.
+</p>
+
+<pre>
+ <code>
+ protected synchronized MouseInfoPeer getMouseInfoPeer();
+ </code>
+</pre>
+
+<p>
+This provides a default <code>MouseInfoPeer</code>
+implementation. However, this is implemented to map to native methods
+which need to be implemented by each backend. It is a good idea to
+override this and provide a custom <code>MouseInfoPeer</code>.
+</p>
+
+<pre>
+ <code>
+ public boolean isModalityTypeSupported(Dialog.ModalityType modalityType);
+ public boolean isModalExclusionTypeSupported(Dialog.ModalExclusionType exclusionType);
+ </code>
+</pre>
+
+<p>
+These predicates provide default implementation for both abstract methods in
+<code>java.awt.Toolkit</code>. One may override
+these, depending on the modality support in the backend.
+</p>
+
+<pre>
+ <code>
+ public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException;
+ </code>
+</pre>
+
+<p>
+This creates a default <code>KeyboardFocusManagerPeer</code>, which might or might
+not be ok for a new backend.
+</p>
+
+<pre>
+ <code>
+ public Dimension getScreenSize();
+ </code>
+</pre>
+
+<p>
+This provides a default implementation
+of <code>getScreenSize()</code>. However, it only maps to two new
+abstract methods <code>getScreenWidth()</code>
+and <code>getScreenHeight()<code>, which one needs to implement.
+</p>
+
+<h2>Additional abstract methods in SunToolkit</h2>
+
+<p>
+<code>SunToolkit</code> also defines a couple of additional abstract methods over
+<code>java.awt.Toolkit</code> for extended functionality. One needs to provide
+implementation of those methods in a new backend. The following lists
+summarizes the new abstract methods.
+</p>
+
+<pre>
+ <code>
+ public abstract TrayIconPeer createTrayIcon(TrayIcon target)
+ throws HeadlessException, AWTException;
+ public abstract SystemTrayPeer createSystemTray(SystemTray target);
+ public abstract boolean isTraySupported();
+ <code>
+</pre>
+
+<p>
+These methods provides tray icon support. For systems without tray icon support, it
+is ok to return false in <code>isTraySupported()</code>, and null in
+the other two methods.
+</p>
+
+<pre>
+ <code>
+ protected abstract int getScreenWidth();
+ protected abstract int getScreenHeight();
+ </code>
+</pre>
+
+<p>
+Determines the screen width and height.
+</p>
+
+<pre>
+ <code>
+ protected abstract boolean syncNativeQueue(final long timeout);
+ </code>
+</pre>
+
+<p>
+Platform toolkits need to implement this method to synchronize with
+the native queue. Refer to the API documentation for details.
+</p>
+
+<pre>
+ <code>
+ public abstract void grab(Window w);
+ public abstract void ungrab(Window w);
+ </code>
+</pre>
+
+<p>
+Implements mouse grabbing and ungrabbing for Swing's PopupMenu. Refer
+to the API documentation for details.
+</p>
+
+<pre>
+ <code>
+ public abstract boolean isDesktopSupported();
+ </code>
+</pre>
+
+<p>
+This predicate should return <code>true</code> if the Desktop API is
+supported, <code>false</code> otherwise. When the Desktop API is not
+supported, the method <code>createDesktopPeer()</code> (declared
+abstract by <code>java.awt.Toolkit</code>) can return <code>null</code>.
+
+<h2>Provide top level AWT widget peers</h2>
+
+<p>
+As part of implementing the <code>Toolkit</code>, one also has to provide peer
+implementations for the 3 top level AWT widgets:
+</p>
+
+<pre>
+ <code>
+ public abstract WindowPeer createWindow(Window target)
+ throws HeadlessException;
+ public abstract FramePeer createFrame(Frame target)
+ throws HeadlessException;
+ public abstract DialogPeer createDialog(Dialog target)
+ throws HeadlessException;
+ </code>
+</pre>
+
+<p>
+These are mandatory, because without top level widgets it is not
+possible to create a graphical application. Please refer to the API
+documentations of the widget peers
+and <a href='Tutorial_External_Interfaces.html'>External Toolkit
+Implementation, a walkthrough</a> for details.
+</p>
+
+<p>
+It should be noted, that the top level widgets also provide the entry
+points for the graphics pipeline.
+</p>
+
+<p>
+There is no common base implementation for these interfaces.
+</p>
+
+<h2>Provide AWT widget peers</h2>
+
+<p>
+Also, as part of implementing the <code>Toolkit</code>, one can
+provide AWT widget peers for all other AWT components. This is only
+needed for supporting the AWT widgets. For Swing
+applications these are not used. Refer to the API documentation for
+details.
+</p>
+
+<p>
+In the future, it will be possible to use portable Swing based widget
+peers.
+</p>
+
+<h2>Providing a GraphicsEnvironment</h2>
+
+<p>
+The other central entry point for implementing a graphics backend is
+the <code>java.awt.GraphicsEnvironment</code> and its related classes
+<code>java.awt.GraphicsDevice</code>
+and <code>java.awt.GraphicsConfiguration</code>. In OpenJDK there is
+a common base implementation for <code>java.awt.GraphicsEnvironment</code>, called
+<code>sun.java2d.SunGraphicsEnvironment</code>, which provides convenient default
+implementations for a couple of subsystems. For the other two classes
+there is no default implementation.
+</p>
+
+<h2>Useful default implementations</h2>
+
+<pre>
+ <code>
+ public synchronized GraphicsDevice[] getScreenDevices();
+ public GraphicsDevice getDefaultScreenDevice();
+ </code>
+</pre>
+
+<p>
+These provide default implementations for screen device creation and handling. These
+use the two new abstract methods <code>getNumScreens()</code> and
+<code>makeScreenDevice()</code> to actually create the screen devices.
+</p>
+
+<pre>
+ <code>
+ public Graphics2D createGraphics(BufferedImage img);
+ </code>
+</pre>
+
+<pr>
+This method creates a <code>Graphics2D</code> for drawing
+on <code>BufferedImages</code>. This hooks into the graphics pipeline
+of OpenJDK. This does not need to be overridden, unless one provides
+a <code>BufferedImage</code> implementation in the
+<code>GraphicsConfiguration.createCompatibleImage()</code> methods,
+that are not compatible with the standard pipeline.
+</p>
+
+<pre>
+ <code>
+ public Font[] getAllFonts();
+ public String[] getAvailableFontFamilyNames(Locale requestedLocale);
+ public String[] getAvailableFontFamilyNames();
+ </code>
+</pre>
+
+<p>
+These routines Implement font support of the <code>GraphicsEnvironment</code>
+class. This hooks into the font subsystem of OpenJDK, and does not
+need to be overridden, unless one provides a new font subsystem.
+</p>
+
+<h2>New abstract methods</h2>
+
+<pre>
+ <code>
+ protected abstract int getNumScreens();
+ protected abstract GraphicsDevice makeScreenDevice(int screennum);
+ </code>
+</pre>
+
+<p>
+These are used to create the screen devices.
+</p>
+
+<pre>
+ <code>
+ public abstract boolean isDisplayLocal();
+ </code>
+</pre>
+
+<p>
+This is used to determine if a display is local or remote.
+</p>
+
+<h2>GraphicsDevice and GraphicsConfiguration</h2>
+
+<p>
+As part of implementing the <code>GraphicsEnvironment</code>, one also
+must provide implementations of <code>java.awt.GraphicsDevice</code> and
+<code>java.awt.GraphicsConfiguration</code>. There are no common base
+implementations for these two classes, so one must follow the API
+specification for the public classes.
+</p>
+
+<h2>Implement graphics pipeline</h2>
+
+<p>
+<code>ComponentPeer</code> (especially a new <code>WindowPeer</code>
+implementation) requires the implementation of <code>getGraphics()</code>:
+</p>
+
+<pre>
+ <code>
+ Graphics getGraphics();
+ </code>
+</pre>
+
+<p>
+The declaration of this method is slightly misleading, because most
+applications expect the subclass <code>Graphics2D</code>, so
+it makes sense to provide a <code>Graphics2D</code> object
+here. (It makes sense in future versions of the peer
+interface to require <code>Graphics2D</code>).
+</p>
+
+<p>
+In theory, it is possible to implement a
+<code>Graphics</code>/<code>Graphics2D</code> based solely on the
+public API specification (as shown in the Caciocavallo prototype for
+the external API). However, this is a really huge task. It makes a lot
+of sense to reuse existing code from the OpenJDK graphics pipeline
+because a lot of portable generic and less generic rendering loops
+already exist.
+</p>
+
+<p>
+The central class of the graphics pipeline
+is <code>SunGraphics2D</code>, a concrete final implementation of
+<code>java.awt.Graphics2D</code>, which implements a lot of generic
+functionality (bookkeeping of graphics state) and hooks into a
+rendering pipeline for actual rendering.
+</p>
+
+<p>
+The usual implementation of getGraphics() looks like this:
+</p>
+
+<pre>
+ <code>
+ public Graphics getGraphics()
+ {
+ SunGraphics2D sg2d = new SunGraphics2D(surfaceData, foreground, background,
+ font);
+ return sg2d;
+ }
+ </code>
+</pre>
+
+<p>
+where foreground and background are <code>java.awt.Color</code> objects specifying
+the foreground and background colors respectively and font is a
+<code>java.awt.Font</code> object specifying the font. The most
+important argument here is the surfaceData object, which is an
+implementation of <code>sun.java2d.SurfaceData</code>.
+</p>
+
+<h2>Implement SurfaceData</h2>
+
+<p>
+<code>SurfaceData</code> is the central class that defines the rendering pipeline
+for a specific drawing surface. A drawing surface is usually something
+like an on-screen window area, an off-screen backing image (volatile
+image) or similar. Each drawing surface usually has exactly one
+<code>SurfaceData</code> object associated.
+</p>
+
+<h2>Abstract methods to be implemented by specific SurfaceData implementations</h2>
+
+<pre>
+ <code>
+ public abstract GraphicsConfiguration getDeviceConfiguration();
+ </code>
+</pre>
+
+<p>
+This must return a <code>GraphicsConfiguration</code> object that describes the
+graphics configuration of the destination drawable.
+</p>
+
+<pre>
+ <code>
+ public abstract Rectangle getBounds();
+ </code>
+</pre>
+
+<p>
+Returns the bounds of the drawable.
+</p>
+
+<pre>
+ <code>
+ public abstract Object getDestination();
+ </code>
+</pre>
+
+<p>
+Returns the destination, that is either the AWT component or the image
+to which this <code>SurfaceData</code> draws. This is used only by Swing's
+<code>RepaintManager</code>.
+</p>
+
+<pre>
+ <code>
+ public abstract SurfaceData getReplacement();
+ </code>
+</pre>
+
+<p>
+Changes in the configuration of a surface require the invalidation and
+creation of a new <code>SurfaceData</code> object. Please refer to the API
+documentation of this method for details. This probably do not have to
+be changed.
+</p>
+
+<pre>
+ <code>
+ public abstract Raster getRaster(int x, int y, int w, int h);
+ </code>
+</pre>
+
+<p>
+This method returns a <code>Raster</code> object which provides access to the
+pixel data of the surface. This probably do not need to be provided, as
+long as all rendering with new rendering loops. However, if one would like
+to use the (slow) generic loops that operate
+on <code>Rasters</code>, then one can save time by provding this.
+</p>
+
+<h2>Pipes and Loops</h2>
+
+<p>
+Most likely want, <code>validatePipe()</code> will need to be overriden in a new <code>SurfaceData</code>
+subclass:
+</p>
+
+<pre>
+ <code>
+ public void validatePipe(SunGraphics2D sg2d);
+ </code>
+</pre>
+
+<p>
+This method is supposed to setup the various XXXpipe objects in the
+<code>SunGraphics2D</code> instance.
+</p>
+
+<h3>
+What are pipes and loops?
+</h3>
+
+<p>
+To put it simple, pipes are objects that are used
+by <code>SunGraphics2D</code> to perform the actual rendering. Pipes
+can do the rendering directly, i.e., <code>EscherRenderer</code> is
+a <code>PixelDrawPipe</code> that implements primitive drawing
+operations by calling directly into
+the <a href='http://escher.sf.net'>Escher X11</a> API, or they can
+apply some transformation to the drawing call and delegate to some
+other pipe. This usually happens in complex drawing calls. Some pipes
+use loops for rendering. Loops are generic (or less generic)
+implementations for some rendering primitives like lines, rectangles,
+etc.
+</p>
+
+<p>
+The method <code>validatePipe()</code> should check the state of
+the <code>SunGraphics2D</code> object (the various state fields) and
+setup the pipeline accordingly. Usually, in the primitive case (no
+composite, paint, etc) one would setup drawpipe and fillpipe that use
+graphics primitives of the graphics backend. In the complex cases, one
+usually wants to use the pipes that are setup by the superclass.
+</p>
+
+<p>
+It is most useful to study existing implementations of this method,
+for example the <code>XDrawableSurfaceData.validatePipe()</code> of the
+Caciocavallo-NG prototype or the implementations included in OpenJDK.
+</p>
+
+<h3>Setup blit loops</h3>
+
+<p>
+There is one special type of loops that one needs to take care of, that
+are the blit loops (defined
+by <code>sun.java2d.loops.Blit</code>). <code>Blits</code> perform
+copying of rectangles of pixels from one surface to another (or within
+one surface). This is used by <code>copyArea()</code>, the
+various <code>drawImage()</code> methods and some of the other loops.
+</p>
+
+<p>
+One detail sets blits apart from other loops. They are not simply
+installed as a value of a certain field; they are registered into a
+special datastructure, which enables them to be looked up by the
+rendering pipeline, according to their supported source and
+destination surface types. This registry data structure is a kind of
+hierarchy. The top node is always a generic (but slow) blit
+registered, which serves as fallback if no other blit operation can
+take over a certain operation. Then, one can register blit operations
+for more specific surface types.
+</p>
+
+<p>
+One can reuse a set of standard surface types (defined in
+<code>sun.java2d.loops.SurfaceType</code>) when they match a given surface,
+or one can derive new subtypes for surfaces that are not predefined. This is done <strong>not</strong>
+by subclassing <code>SurfaceType</code>, but rather by
+calling <code>deriveSubType()</code> on an
+existing <code>SurfaceType</code>, such as in the following code (from the Caciocavallo
+prototype):
+</p>
+
+<pre>
+ <code>
+ static final SurfaceType Escher =
+ SurfaceType.Any.deriveSubType(DESC_ESCHER_INT_RGB);
+ static final SurfaceType EscherInt =
+ Escher.deriveSubType(DESC_ESCHER_INT);
+ static final SurfaceType EscherIntRgb =
+ EscherInt.deriveSubType(DESC_ESCHER_INT_RGB);
+ </code>
+</pre>
+
+<p>
+This defines a subhierarchy, that uses the type <code>'Any'</code> as
+supertype (this is the most generic type), and derives a
+generic <code>'Escher'</code> supertype (for all Escher-based
+surfaces) as well as more generic subtypes <code>'EscherInt'</code>
+and <code>'EscherIntRgb'</code> (for integer-based and
+integer-based-RGB Escher types).
+</p>
+
+<p>
+To register specific <code>Blit</code> loops, one can call in the
+static initializer of <code>SurfaceData</code> subclass a static
+<code>register()</code> method of a new <code>BlitLoops</code> class
+like this (from <code>XDrawableSurfaceData.java</code>):
+</p>
+
+<pre>
+ <code>
+ static
+ {
+ EscherBlitLoops.register();
+ }
+ </code>
+</pre>
+
+<p>
+and then define this register method like this (from
+<code>EscherBlitLoops.java</code>):
+</p>
+
+<pre>
+ <code>
+ static void register()
+ {
+ GraphicsPrimitive[] primitives =
+ {
+ new EscherBlitLoops(XDrawableSurfaceData.EscherIntRgb,
+ XDrawableSurfaceData.EscherIntRgb, true),
+ new EscherBlitLoops(SurfaceType.Any, XDrawableSurfaceData.EscherIntRgb, true)
+ };
+ GraphicsPrimitiveMgr.register(primitives);
+ }
+ </code>
+</pre>
+
+<p>
+This creates an array with blit loops to be registered. In this case
+one has one loop that is specific to copy from <code>EscherIntRgb</code> to
+<code>EscherIntRgb</code> surfaces only, and one more generic loop to
+transfer from any other surface (e.g. <code>BufferedImage</code>) to an
+<code>EscherIntRgb</code> surface. Finally, the blit loops are
+registered by calling <code>GraphicsPrimitiveMgr.register()</code>
+with this array as argument.
+</p>
+
+<h2>Volatile image support</h2>
+
+<p>
+The <code>ComponentPeer</code> interface also mandates the implementation of
+createVolatileImage(int,int):
+</p>
+
+<pre>
+ <code>
+ VolatileImage createVolatileImage(int width, int height);
+ </code>
+</pre>
+
+<p>
+as does the <code>GraphicsConfiguration</code> class:
+</p>
+
+<pre>
+ <code>
+ public VolatileImage createCompatibleVolatileImage(int width, int height);
+ </code>
+</pre>
+
+<p>
+Infact, the authors recommend implementing the <code>ComponentPeer</code> method as follows:
+</p>
+
+<pre>
+ <code>
+ @Override
+ public VolatileImage createVolatileImage(int width, int height)
+ {
+ GraphicsConfiguration gc = awtComponent.getGraphicsConfiguration();
+ return gc.createCompatibleVolatileImage(width, height);
+ }
+ </code>
+</pre>
+<!--
+We love Neil Young!
+see http://www.neilyoung.com/lwwtoday/index.html
+-->
+<p>
+However, the <code>GraphicsConfiguration</code> method
+<code>createCompatibleVolatileImage()</code> is not an abstract method, so it is
+not necessary to override it. The default implementation creates a
+<code>SunVolatileImage</code> which in turn uses
+a <code>VolatileSurfaceManager</code> to perform its platform specific
+tasks.
+</p>
+
+<code>
+So in order to support <code>VolatileImages</code>, one only need create a
+subclass of <code>sun.awt.image.VolatileSurfaceManager</code> and a subclass of
+<code>sun.java2d.SurfaceManagerFactory</code>. Then one only needs to tell the
+<code>SurfaceManagerFactory</code> to use the new factory to create
+<code>VolatileSurfaceManager</code> instances for the new volatile
+images. The authors recommend doing this in the static initializer of a new
+<code>GraphicsEnvironment</code> implementation:
+</code>
+
+<pre>
+ <code>
+ static {
+ SurfaceManagerFactory.setInstance(new MySurfaceManagerFactory());
+ }
+ </code>
+</pre>
+
+<p>
+The <code>VolatileSurfaceManager</code> class declares the following abstract
+methods:
+</p>
+
+<pre>
+ <code>
+ protected abstract boolean isAccelerationEnabled();
+ </code>
+</pre>
+
+<p>
+to determine if acceleration is enabled or not;
+</p>
+
+<pre>
+ <code>
+ protected abstract SurfaceData initAcceleratedSurface();
+ </code>
+</pre>
+
+<p>
+to initialize and return the accelerated surface;
+</p>
+
+<pre>
+ <code>
+ public abstract SurfaceData getPrimarySurfaceData();
+ </code>
+</pre>
+
+<p>
+to returns the <code>SurfaceData</code> object that is used to draw on the volatile
+image; and
+</p>
+
+<pre>
+ <code>
+ public abstract SurfaceData restoreContents();
+ </code>
+</pre>
+
+<p>
+to restore the content if it has become invalid.
+</p>
+
+<p>
+There are also a lot of other useful methods that one might or might
+not want to override. See the excellent API documentation for
+<code>VolatileSurfaceManager</code> for details.
+</p>
+
+<h2>Fonts</h2>
+
+<p>
+The <code>Toolkit</code> is also resposible for creating
+a <code>Font</code> peer. However, this interface is not actively used
+anymore. There is an internal API for implementing fonts, which
+consist of a couple of classes and interfaces:
+</p>
+
+<pre>
+ <code>
+sun.font.Font2D
+sun.font.FontManager
+sun.awt.FontConfiguration
+ </code>
+</pre>
+
+<p>
+In order to implement a new font backend one must provide a
+<code>FontManager</code> and all the referenced support classes.
+</p>
+
+<p>
+It is possible to reuse most of the existing <code>FontManager</code>
+code. For the most portable approach, just implement the methods
+described in the <code>FontManager</code> interface. Currently, there
+is an ongoing work to make this interface more portable and more
+documented.
+</p>
+
+<p>
+To use the new <code>FontManager</code> implementation, pass a system
+property to the VM:
+</p>
+
+<pre>
+ <code>
+java -Dsun.font.fontmanager=your.fontmanager.ClassName
+ </code>
+</pre>
+
+<p>
+One can also set this property in the static initializer of a
+<code>GraphicsEnvironment</code> implementation:
+</p>
+
+<pre>
+ <code>
+ static
+ {
+ System.setProperty("sun.font.fontmanager", "your.fontmanager.ClassName");
+ }
+</code>
+</pre>
+
+<h2>Relevant classes</h2>
+
+<pre>
+<code>
+java.awt.GraphicsConfiguration
+java.awt.GraphicsDevice
+java.awt.peer.WindowPeer
+java.awt.peer.FramePeer
+java.awt.peer.DialogPeer
+java.awt.peer.*
+sun.awt.SunToolkit
+sun.awt.KeyboardFocusManagerPeerImpl
+sun.awt.image.(Volatile)SurfaceManager
+sun.java2d.SunGraphicsEnvironment
+sun.java2d.SurfaceData
+sun.java2d.loops.Blit
+sun.java2d.pipe.PixelDrawPipe
+sun.java2d.pipe.PixelFillPipe
+sun.java2d.pipe.ShapeDrawPipe
+sun.java2d.pipe.GlyphListPipe
+sun.java2d.SurfaceManagerFactory
+sun.font.FontManagerBase
+sun.awt.FontConfiguration
+</code>
+</pre>
+
+</body>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/What we did.txt Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,53 @@
+fontmanager.patch
+=================
+
+The FontManager class has been a final class with lots of static methods in it, mixing Solaris, Windows and generics code. The first step of refactoring was to make the FontManager an abstract class, with most static methods now instance methods, and moving some platform specific things to a subclass (DefaultFontManager only for now).
+
+j2d-localdisplay.patch
+======================
+
+In SwingUtilities2.isLocalDisplay(), there have been some platform checks to determine if a display is local or not. Worse: In the Linux/Solaris case it uses reflection to directly access X11GraphicsEnvironment. This doesn't work for graphics backends on Linux that don't use the X11GraphicsEnvironment. We've introduced a new method isDisplayLocal() in SunGraphicsEnvironment, which can be implemented by the backend. When a backend doesn't use SGE, it is assumed that the display is local.
+
+j2d-fontmanager2.patch
+======================
+
+More FontManager related refactoring. Another bunch of static methods and fields have been changed to instance methods and fields, and access to them now goes over the factory method.
+
+fontmanager3.patch
+==================
+
+All font related methods from SunGraphicsEnvironment and platform specific subclasses have been moved to FontManager and platform specific subclasses.
+
+
+fontmanager4.patch
+==================
+
+Some remaining things (fields, inner classes) from SGE have been moved to FontManager too.
+
+RepaintManager.patch
+====================
+
+In RepaintManager we found some direct casts to SunToolkit, which doesn't work if the implementing TK is not a STK. We added instanceof checks, assuming appropriate default behaviour if the TK isn't a STK.
+
+cleanawtpeer.patch
+==================
+
+Some old duplicate methods in the interfaces have been removed and replaced by their newer counterparts.
+
+documentawtpeer.patch
+=====================
+
+Documents all the interfaces in java.awt.peer.*
+
+fontmanager5.patch & fontmanager6.patch
+=======================================
+
+Moved FM instantiation into its own factory. Make FontManager an interface. Some more static methods have been converted to instance methods. Implementation has been split out into FontManagerBase and FontConfigManager.
+
+openjdk-splashscreen.patch
+==========================
+
+In java.awt.Window, the splashscreen has been closed by using the static method SunToolkit.closeSplashScreen(). Not only is this bad for portability (how can a TK implement this??), it's also a duplicated piece of code, because all
+the necessary functionalitly is already in SplashScreen.close(). We have made Window use the official API and be happy.
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/challenge_caciocavallo_project.html Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,453 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+
+<head>
+<title>Portable GUI Backends (The Caciocavallo project)</title>
+</head>
+<body>
+<h1>OpenJDK Challenge</h1>
+
+
+<h1>Portable GUI Backends (The Caciocavallo project)</h1>
+
+
+<p>Roman Kennke and Mario Torre</p>
+<p>aicas GmbH</p>
+
+<h2>Introduction</h2>
+
+<p>
+In order to support the spread of Java for graphical applications, particularly
+in embedded systems, aicas GmbH proposed to improve the AWT and Java2D in
+OpenJDK to enable easier porting of AWT to new platforms.
+</p>
+<p>
+The assumption was that despite the name of the <code>Toolkit</code> interface (Abstract
+Windowing Toolkit) and its design that provides a public API and a series of
+abstract classes meant to be used by the specific platforms, the current
+implementation in OpenJDK is a mix of platform specific code, non portable code
+that relies on non documented features, and code that explicitly casts
+back to Sun internal classes.
+The code simply defeats the whole purpose of having such an interface in
+the first place and makes porting AWT to new platforms unnecessarily hard or
+impossible without modifying Swing and AWT themselves.
+</p>
+<p>
+The Project was accepted as part of the OpenJDK Challenge 2008, with the code
+name Caciocavallo (due to <a href='http://www.flickr.com/photos/neugens/2293854588/in/set-72157603988201422/'>some nice dinners</a>
+with the <a href='http://www.flickr.com/photos/neugens/2293861884/in/set-72157603988201422/'>Italian cheese that the
+authors had together with some Sun developers at Fosdem 2008</a>).
+Caciocavallo consist of two main subprojects, one called "internal"
+implementation and the other "external".
+</p>
+<p>
+The Internal implementation is meant to reuse as much code as possible from the
+existing peers. It does it by subclassing the Sun internal classes, like
+<code>SunToolkit</code>, <code>SunGraphicsEnvironment</code>, <code>SunGraphics2D</code>. It then defines a Java2D
+pipeline for its rendering.
+</p>
+<p>
+The External implementation, on the contrary, tries to not depend on
+internal code. This is the main source of refactoring for the AWT
+peers in OpenJDK. Every time a dependency was found in internal
+code, it has been fixed or worked around so that the code is not
+implementation dependent. Hence, the refactored code can now use
+different code paths, one "optimized", when a <code>SunToolkit</code> is
+detected, and one that leaves everything to the peer implementors.
+</p>
+<p>
+Caciocavallo, and Caciocavallo-NG are the names of the Peers, where the NG
+version refers to the Internal subproject.
+</p>
+<p>
+The project presents also an additional level of refactorisation, the
+Sun Font API.
+This is a special case, as there is no real API defined for the
+internal implementation of the Font system, but a final class that
+acts like a sort of catch all. The authors tried to refactor this class to make
+it possible to just "hook" in a new implementation, maybe reusing
+only some bits of code.
+</p>
+<p>
+This subproject was needed to help to assure the portability of the Toolkit
+API, but was considered an extra task. The current status is that most of the
+final class <code>FontManager</code> was refactored into an Interface called <code>FontManager</code>,
+while the implementation was moved down to a class FontManagerBase. Also, all
+the code that referenced the <code>FontConfig</code> library (that before was part of
+<code>FontManager</code>) was moved to a different class, <code>FontConfigManager</code>. For the
+external project, this resulted in implementing a <code>FontManager</code> subclassing and
+then implementing only three methods.
+It is possible to get an instance of <code>FontManager</code> via a factory class, <code>FontManagerFactory</code>.
+</p>
+<h2>OpenJDK Patches</h2>
+
+<p>
+Another component that is part of the project is the Mercurial Patch Queue
+repository the project used. At the time of this writing, the MQ repository is
+located at the address:
+
+<pre>
+http://hg.openjdk.java.net/caciocavallo/caciocavallo/
+</pre>
+
+and
+
+<pre>
+http://kennke.org/~hg/hgwebdir.cgi/openjdk-patches/
+</pre>
+
+To help easy testing, the authors maintain a separate OpenJDK branch on a
+private server:
+
+<pre>
+http://kennke.org/~hg/hgwebdir.cgi/openjdk-tip-b7474b739d13-caciocavallo-branch/
+</pre>
+
+<p>
+One can directly use this branch, cloning the entire forest instead of the
+single patches or the MQ repository. This branch also contains few patches to
+make the build possible with a GCC 4.3 compiler (as of tip b7474b739d13, as
+hotspot does not compile on GCC 4.3 in both Fedora and Ubuntu Linux.
+This problem should be fixed in more recent version, thus provided no
+patches to upstream).
+</p>
+<p>
+There are several important patches from the patch queue.
+This list may change as further refactoring or better
+organisation of the patches is performed.
+
+<ul>
+<li>
+fontmanager.patch:
+
+The <code>FontManager</code> class was a final class with lots of static methods in it,
+mixing Solaris, Windows, and generics code. The first step of refactoring was to
+make the FontManager an abstract class, with most static methods now instance
+methods, and moving some platform specific things to a subclass
+(DefaultFontManager only for now).
+</li>
+<li>
+j2d-localdisplay.patch:
+
+In <code>SwingUtilities2.isLocalDisplay()</code>, there were some platform checks to
+determine if a display is local or not. Worse, in the Linux/Solaris case, it uses
+reflection to directly access <code>X11GraphicsEnvironment</code>. This does not work for
+graphics backends on Linux that do not use the <code>X11GraphicsEnvironment</code>. The authors
+introduced a new method <code>isDisplayLocal()</code> in <code>SunGraphicsEnvironment</code>, which can
+be implemented by the backend. When a backend does not use SGE, it is assumed
+that the display is local.
+</li>
+<li>
+j2d-fontmanager2.patch:
+
+For the <code>FontManager</code>, another set of static methods and fields
+has been changed to instance methods and fields, and access to them now goes
+over the factory method.
+</li>
+<li>
+fontmanager3.patch:
+
+All font related methods from <code>SunGraphicsEnvironment</code> and platform specific
+subclasses have been moved to <code>FontManager</code> and platform specific subclasses.
+</li>
+<li>
+fontmanager4.patch:
+
+Some remaining things (fields, inner classes) from <code>SunGraphicsEnvironment</code> have
+been moved to <code>FontManager</code> too.
+</li>
+<li>
+RepaintManager.patch:
+
+In <code>RepaintManager</code>, there were some direct casts to <code>SunToolkit</code>, which does not work
+if the implementing <code>Toolkit</code> is not a <code>SunToolkit</code>. The authors added instanceof checks,
+assuming appropriate default behaviour if the <code>Toolkit</code> is not a <code>SunToolkit</code>.
+</li>
+<li>
+cleanawtpeer.patch:
+
+Some old duplicate methods in the interfaces have been removed and replaced by
+their newer counterparts.
+</li>
+<li>
+documentawtpeer.patch:
+
+Documents all the interfaces in <code>java.awt.peer.*</code>
+</li>
+<li>
+fontmanager5.patch, fontmanager6.patch:
+
+Moved FM instantiation into its own factory. Make <code>FontManager</code> an interface.
+Some more static methods have been converted to instance methods.
+Implementation has been split out into <code>FontManagerBase</code> and <code>FontConfigManager</code>.
+</li>
+<li>
+caciocavallo-GenericKeyboardFocusManagerprovide.patch:
+
+<code>KeyboardFocusManager</code> instantiate a <code>KeyboardFocusManagerPeerProvider</code>.
+This patch resulted from discussion on one the OpenJDK mailing list.
+The authors opine that the correct approach is still to make this API part of the
+Toolkit Interface. Without this patch, the authors were forced to implement a
+<code>KeyboardFocusManagerPeerProvider</code> directly in the new Toolkit, even for the
+external project, despite that the interface never mandates it. While this is
+clearly a hack, it is still better than the current situation, thus the patch
+is included to show a cleaner interface with a proof of concept for the
+<code>createKeyboardFocusManagerPeer</code> method in the Toolkit API.
+</li>
+<li>
+openjdk-splashscreen.patch:
+
+In <code>java.awt.Window</code>, the splashscreen was closed by using the static
+method <code>SunToolkit.closeSplashScreen()</code>. Not only is this bad for portability
+(how can a TK implement this??), it is also a duplicated piece of code, because
+all the necessary functionalitly is already in <code>SplashScreen.close()</code>.
+Window now uses the official API.
+</li>
+<li>
+windows-fontmanager.patch, windows-fontmanagerfactory.patch:
+
+There are a few cleanups for the Windows build, though this has not yet been tested.
+</li>
+<li>
+SunGraphicsEnvironment-cleanup.patch:
+
+There are some more cleanups to fix some very dumb error from previous refactorings.
+</li>
+</ul>
+<h2>Getting the code</h2>
+
+<p>
+The easiest way to get the code is to clone the complete OpenJDK forest from the private repository:
+</p>
+
+<pre>
+hg fclone http://kennke.org/~hg/hgwebdir.cgi/openjdk-tip-b7474b739d13-caciocavallo-branch openjdk-caciocavallo
+</pre>
+
+<p>
+If only single patches are of interest, one can just check out the relevant patch queue:
+</p>
+
+<pre>
+hg clone http://kennke.org/~hg/hgwebdir.cgi/openjdk-patches/
+</pre>
+
+<p>
+This patch queue is only guaranteed to apply cleanly on the ChangeSet
+b7474b739d13 of the subrepository <em>jdk</em> of the official OpenJDK
+forest.
+</p>
+
+
+<h2>Building</h2>
+
+The Caciocavallo OpenJDK forest is built just like every other OpenJDK
+forest, so please follow
+the <a href="http://hg.openjdk.java.net/jdk7/jdk7/raw-file/tip/README-builds.html">official build instructions</a>.
+
+<h2>Testing the code</h2>
+
+<p>
+To test the project, one needs to download some extra code, that for various
+reason could not be hosted on the OpenJDK website.
+</p>
+<p>
+As said in the introduction, the authors have two actual proof of concept
+implementations, named Caciocavallo and Caciocavallo-ng.
+</p>
+
+<p>
+These are available on the private website:
+</p>
+
+<pre>
+<code>
+http://kennke.org/~hg/hgwebdir.cgi
+</code>
+</pre>
+
+<p>
+just checkout (hg clone) the specific repository needed, e.g.
+</p>
+
+<pre>
+<code>
+# hg clone http://kennke.org/~hg/hgwebdir.cgi/caciocavallo/
+</code>
+</pre>
+
+or
+
+<pre>
+<code>
+# hg clone http://kennke.org/~hg/hgwebdir.cgi/caciocavallo-ng/
+</code>
+</pre>
+
+<p>
+One then needs a copy of the Escher library:
+</p>
+
+<pre>
+<code>
+# hg clone http://kennke.org/~hg/hgwebdir.cgi/escher-trunk
+</code>
+</pre>
+
+<p>
+An X11 Server is also required. The authors tested the Escher library, as well as the
+default Escher Peers from GNU Classpath, on Windows using a Windows version of
+the X11 Server, but currenty the Windows build of OpenJDK does not take
+full advantage of the refactoring and is not tested.
+</p>
+<p>
+Please, note, the peers themselves are prototypes only and may not work
+with all applications. For testing, the SwingDemo from GNU
+Classpath was used a lot, as well as the SwingSet2 demo from the JDK, and the
+graphical frontend of FindBugs.
+</p>
+<p>
+The Classpath SwingDemo is available as jar package from this link:
+</p>
+
+<pre>
+<a href="http://www.limasoftware.net/neugens/downloads/classpath/caciocavallo/examples.jar">http://www.limasoftware.net/neugens/downloads/classpath/caciocavallo/examples.jar</a>
+</pre>
+
+<p>
+As an alternative, is possible to download pre-build binaries for all the software from this link:
+<a href='http://kennke.org/~hg/packages/'>http://kennke.org/~hg/packages</a>
+</p>
+
+<p>
+To run the demo with the Caciocavallo peers, a few properties need to be passed
+to the java command, as shown in the following bash script:
+</p>
+
+<pre>
+#!/bin/sh
+# testescher.sh
+OPENJDK_DIR=/path/to/your/openjdk/build/linux-i586/j2sdk-image/
+BOOTCLASSPATH=/path/to/escher.jar:/path/to/caciocavallo/dist/echer-peer.jar
+TOOLKIT=gnu.java.awt.peer.x.XToolkit
+GRAPHICSENV=gnu.java.awt.peer.x.XGraphicsEnvironment
+FONT_MANAGER=gnu.java.awt.peer.x.EscherFontManager
+
+# change to suit your needs, we like to use the classpath code
+CLASSPATH=/path/to/examples.jar
+MAIN=gnu.classpath.examples.swing.Demo
+
+$OPENJDK_DIR/bin/java -Xbootclasspath/a:$BOOTCLASSPATH \
+ -Dswing.metalTheme=steel \
+ -Dawt.toolkit=$TOOLKIT -Djava.awt.graphicsenv=$GRAPHICSENV \
+ -Dsun.font.fontmanager=$FONT_MANAGER -cp $CLASSPATH $MAIN
+</pre>
+
+<p>
+Of course, the paths must be changed for the test environment.
+</p>
+
+<p>
+<strong>Note</strong>: the escher library needs tcp access to the X11 server. It may also be necessary to allow permission with the xhost command.
+This is a bug in the version of Escher currently used. To workaround it, it should be enough to just run: <code>xhost + 127.0.0.1</code> on the command line.
+</p>
+
+<p>
+For findbugs, the authors host a modified verison, the only difference being a file named
+findbugs_caciocavallo in the findbugs bin directory. As the paths are hardcoded, they need to be changed at
+the end of the bash script:
+</p>
+<pre>
+fb_jvmargs="$user_jvmargs $debug_arg $conservespace_arg $workhard_arg
+ $user_props $ea_arg -Dswing.metalTheme=steel
+ -Dsun.font.fontmanager=gnu.java.awt.peer.x.EscherFontManager
+ -Dawt.toolkit=gnu.java.awt.peer.x.XToolkit
+ -Djava.awt.graphicsenv=gnu.java.awt.peer.x.XGraphicsEnvironment
+ -Xbootclasspath/a:/path/to/escher/build:/path/to/caciocavallo-ng/dist/echer-peer.jar"
+</pre>
+<p>
+This verision is located <a href='http://kennke.org/~hg/packages/findbugs/findbugs-1.3.2-caciocavallo.tar.bz2'>at this address</a>.
+</p>
+
+<h2>Problems and Conclusions</h2>
+
+<p>
+The proof of concept was designed with Linux in mind, due to the limited time
+and the big issues the project presents. The authors tried hard to make the Windows
+build to at least compile, preserving the original code path so that things
+continue to work, but this can not be guarantee at the moment.
+The Solaris build shares all the refactored code with the Linux one.
+</p>
+<p>
+Caciocavallo (the external prototype) is currently not very stable.
+All the demos could be run, but there are some repainting issues,
+especially when dealing with viewports. The code for the scanline is
+currently disabled, this means that one cannot draw many shapes
+correctly. There are problems related to the implementation of the peer
+code that have nothing to do with the refactoring process. Also,
+implementing a complete new AWT/Java2D backend without using OpenJDK's
+pipeline and existing code is a gigantic piece of work, not something that
+is possible to come close in 4 months of work.
+</p>
+<p>
+Caciocavallo-ng is much
+more complete, as it makes use of a lot of existing code from
+OpenJDK. This is currently able to run quite well the SwingSet2, the
+Classpath SwingDemo and Findbugs.
+</p>
+<p>
+The authors believe that the Caciocavallo project was an important
+experience and want to thank Sun for giving the opportunity to work
+closely on this project. They learned a lot about the internals of
+OpenJDK, and the difficulties that developers have to face when
+developing on the JDK in general and Java2D/AWT/Swing in particular.
+They were able to spot and fix various problems in OpenJDK's
+AWT/Java2D implementation, and now there is an implementation that is
+much more portable than before.
+</p>
+<h2>Ideas and future development</h2>
+<p>
+The Challenge provided a couple of interesting ideas for
+future projects. These are a logical continuation of the Challenge project.
+</p>
+<h3>Fonts</h3>
+
+<p>While a significant part of the font implementation was refactored,
+this is by no means all that has to be done. The FontManager interface
+so far is only a plain refactored interface from the orginal final
+class, without having changed the semantics of the original
+code. However, this interface can not yet be considered a clean API
+which can serve for implementing a new font backend. It can and should
+be developed further into a clean interface that is actually usable.
+</p>
+<p>
+The code for finding fonts on a particular platform is very system
+specific and relies on properties files, which point to the specific
+font files and directories. This code could (in part) make use of the
+FontConfig library. In fact, since FontConfig is based on a couple of
+XML configuration files in defined directory locations, it should not
+be too hard to implement a 100% Java FontConfig library, which could
+then be used by the Font2D code to determine the locations of fonts at
+runtime.
+</p>
+<p>
+Another nice to have feature for fonts would be the ability to read
+fonts from input streams or generic buffers somehow, instead from
+memory mapped files only. This would make it easier to support fonts
+on platforms that do not support memory mapping files (i.e. systems
+without MMU), and would make it possible to provide fonts via the
+classpath and load them
+using <code>ClassLoader.getResourceAsStream()</code>.
+</p>
+<h3>AWT peers based on Swing</h3>
+<p>
+Another future project is the implementation of a set of generic AWT
+peers, which would use Swing for rendering and handling the logic of
+the AWT components. The Caciocavallo prototypes already contain such
+an implementation but it has its problems (namely bad
+heavyweight/lightweight behaviour). In the future, the authors want to implement
+such peers from scratch, pulling together the XAWT architecture with
+ideas from the "old" Swing peers from the prototypes.
+</p>
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/index.html Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+<title>Portable GUI Backends (The Caciocavallo project)</title>
+</head>
+<body>
+<h1>Portable GUI Backends (The Caciocavallo project)</h1>
+
+<center>
+Roman Kennke and Mario Torre<br />
+aicas GmbH<br />
+</center>
+<p>
+The Caciocavallo project is one of the projects accepted for
+the <a href="http://openjdk.java.net/challenge/">OpenJDK Innovators
+Challenge</a>. Its aim is to improve OpenJDK's graphics stack to
+enable the use of external implementations of
+AWT/Java2D backends, to be able to leverage the existing graphics pipeline for partial reimplementations, and to generally improve the portability of the
+graphics stack. The original proposal can be found on <a href="http://mail.openjdk.java.net/pipermail/challenge-discuss/2008-March/000082.html">the challenge discussion list</a>.
+</p>
+
+<h2>Resources</h2>
+<h3>Documentation</h3>
+<p>
+<ul>
+<li><a href="challenge_caciocavallo_project.html">General documentation on getting the code, building, testing, etc</a></li>
+<li><a href="Tutorial_External_Interfaces.html">Tutorial for implementing graphics backend based on external APIs</a></li>
+<li><a href="Tutorial_Internal_Interfaces.html">Tutorial for implementing graphics backend by reusing existing OpenJDK code</a></li>
+</ul>
+</p>
+
+<h3>Mercurial repositories</h3>
+<p>
+<ul>
+<li>Official patches and documentation repository:
+<pre>
+http://hg.openjdk.java.net/caciocavallo/caciocavallo/
+</pre>
+</li>
+<li>Caciocavallo branch of OpenJDK forest (use fclone for cloning!):
+<pre>
+http://hg.openjdk.java.net/caciocavallo/jdk7/
+</pre>
+</li>
+<li>Prototype using the external API:
+<pre>
+http://kennke.org/~hg/hgwebdir.cgi/caciocavallo/ (not maintained anymore)
+</pre>
+</li>
+<li>Prototype using the internal API:
+<pre>
+http://hg.openjdk.java.net/caciocavallo/ng/
+</pre>
+</li>
+<li>The Escher library (needed by both prototypes):
+<pre>
+http://kennke.org/~hg/hgwebdir.cgi/escher-trunk/
+</pre>
+</li>
+</ul>
+</p>
+
+<h3>Generated API Javadoc</h3>
+
+<p>
+<a href="http://kennke.org/~hg/apidocs/">API documentation of relevant classes and interfaces</a>
+</p>
+
+<h3>Example code</h3>
+<p>
+<ul>
+<li><a href="http://www.limasoftware.net/neugens/downloads/classpath/caciocavallo/examples.jar">GNU Classpath Swing demo</a></li>
+<li><a href="http://kennke.org/~roman/SwingSet2.jar">SwingSet2 demo</a> (also part of standard JDK distributions, but not OpenJDK)</li>
+<li><a href="http://kennke.org/~hg/findbugs/findbugs-1.3.2-caciocavallo.tar.bz2">FindBugs</a> (the graphical frontend of FindBugs was used for testing.)</li>
+</ul>
+</p>
+
+<p>
+For convenience, a version of these projects is located on this site: <a href='http://kennke.org/~hg/packages/'>http://kennke.org/~hg/packages/</a>
+</p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/index.html.orig Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,73 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
+<html>
+<head>
+<title>Portable GUI Backends (The Caciocavallo project)</title>
+</head>
+<body>
+<h1>Portable GUI Backends (The Caciocavallo project)</h1>
+
+<center>
+Roman Kennke and Mario Torre<br />
+aicas GmbH<br />
+</center>
+<p>
+The Caciocavallo project is one of the projects accepted for
+the <a href="http://openjdk.java.net/challenge/">OpenJDK Innovators
+Challenge</a>. Its aim is to improve OpenJDK's graphics stack to
+enable the use of external implementations of
+AWT/Java2D backends, to be able to leverage the existing graphics pipeline for partial reimplementations, and to generally improve the portability of the
+graphics stack. The original proposal can be found on <a href="http://mail.openjdk.java.net/pipermail/challenge-discuss/2008-March/000082.html">the challenge discussion list</a>.
+</p>
+
+<h2>Resources</h2>
+<h3>Documentation</h3>
+<p>
+<ul>
+<li><a href="challenge_caciocavallo_project.html">General documentation on getting the code, building, testing, etc</a></li>
+<li><a href="Tutorial_External_Interfaces.html">Tutorial for implementing graphics backend based on external APIs</a></li>
+<li><a href="Tutorial_Internal_Interfaces.html">Tutorial for implementing graphics backend by reusing existing OpenJDK code</a></li>
+</ul>
+</p>
+
+<h3>Mercurial repositories</h3>
+<p>
+<ul>
+<li>Caciocavallo peer framework:
+<pre>
+http://hg.openjdk.java.net/caciocavallo/ng/
+</pre>
+</li>
+<li>Official documentation repository:
+<pre>
+http://hg.openjdk.java.net/caciocavallo/caciocavallo/
+</pre>
+</li>
+<li>The Escher library (optional, needed for the example implementation):
+<pre>
+http://kennke.org/~hg/hgwebdir.cgi/escher-trunk/
+</pre>
+</li>
+</ul>
+</p>
+
+<h3>Generated API Javadoc</h3>
+
+<p>
+<a href="http://kennke.org/~hg/cacio/apidocs/">API documentation of relevant classes and interfaces</a>
+</p>
+
+<h3>Example code</h3>
+<p>
+<ul>
+<li><a href="http://www.limasoftware.net/neugens/downloads/classpath/caciocavallo/examples.jar">GNU Classpath Swing demo</a></li>
+<li><a href="http://kennke.org/~roman/SwingSet2.jar">SwingSet2 demo</a> (also part of standard JDK distributions, but not OpenJDK)</li>
+<li><a href="http://kennke.org/~hg/findbugs/findbugs-1.3.2-caciocavallo.tar.bz2">FindBugs</a> (the graphical frontend of FindBugs was used for testing.)</li>
+</ul>
+</p>
+
+<p>
+For convenience, a version of these projects is located on this site: <a href='http://kennke.org/~hg/packages/'>http://kennke.org/~hg/packages/</a>
+</p>
+
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/tasks_openjdk_challenge.txt Wed Mar 04 17:11:38 2009 +0100
@@ -0,0 +1,30 @@
+- Refactor FontManager into abstract class with concrete
+ (platform-specific) subclasses. Right now, the FontManager class is
+ a completely static class. Refactoring into an abstract class,
+ turning all public methods into abstract instance methods and moving
+ stuff into platform specific subclasses shouldn't be hard.
+
+- Implement font reading via InputStreams or (better yet) channels. At
+ the moment, the File.create() methods pass a filename string to the
+ FontManager, which opens a file, makes a channel of it and reads
+ from that. However, for Font.create(InputStream) this means copying
+ the stream into a temporary file, and passing in that file. It would
+ be much more efficient to create the channel in the Font class, and
+ pass this channel into FontManager for reading. This avoids the
+ copy, and more importantly, it allows fonts to be built into
+ applications (JARs or binaries). However, this proves to be
+ difficult, because the font stuff relies on FileChannel, some of
+ which's operations cannot be mapped on InputStream easily
+ (i.e. position() ). FreeType can't read from streams like they work
+ in java, FreeType needs buffer-like access (i.e. with offset and
+ length).
+
+- Move font stuff out of SunGraphicsEqnvironment. This helps
+ separating font stuff from the rest of AWT/Java2D, and ultimately
+ enables external GraphicsEnvironments to be used. Seems like this
+ stuff could be moved into FontManager, or one of its platform
+ specific subclasses, when the above refactoring has been done.
+
+- Write howto for internal interface. Collect API documentation for
+- internal interface.
+