A small step for me

… but a big step for OpenJDK. OpenJDK can now officially claim to have non-Sun committers! 🙂 Ok, I’m not the first one, but most (or all?) non-Sunnies I’ve seen committing have been ex-Sun-employees.

That was good timing. Not that I care much if I do the commit or some guy inside Sun, as long as I can get a good patch in, but it is a big nice step in the right direction.

Things left to do for OpenJDK:

  • Fix the bug database.
  • Fix the bug database.
  • Really. Do it.

😉

Is it possible to setup Bugzilla that it can have a parent-child relationship with another Bug-DB? Maybe the Bugzilla could be a child of the Sun-internal DB, representing the FOSS subset of bugs of OpenJDK, while Sun internal gets both the stuff from commercial customers and the FOSS bugs, the latter preferably feeded into the Sun DB automatically (by email notification?).

Anyway. I’m quite happy now and celebrate with a beer. Prosit!

Caciocavallo for the masses

Some exiting things happened during the last two weeks in the Caciocavallo project, namely two new AWT widgets based on swing, merging back patches from the Cacio branch to main JDK7 and more font refactoring work.

Mario Torre implemented two new widgets for Cacio’s AWT peers, namely the TextFieldPeer and a first prototype of the TextAreaPeer (minus the scrollbars: you guess it, that’s the tricky part). We’ll be posting screenshots soon.

I posted a couple of patches from the Cacio HG to the appropriate groups for review. One (the isDisplayLocal patch) is already in the J2D workspace, another one (AWT peers cleanup) is currently in review and another one (some RepaintManager fixlets) seems to be stuck somehow. /me bumbs the Swing-dev list. 😉

I also continued with The Big Font Refactoring in Caciocavallo. The plan is to enable replacing of the font implementation, which is currently not at all possible. The font subsystems basically has 3 ‘sides’: to AWT it shows a rather high-level view and basically cares about mapping Font objects (family name, size, style) to Font2D objects (which hook into the font subsystem for real) and handling the metrics. Then there is the rasterizer, which needs to get bitmasks or alpha masks of rasterized glyphs to render. And finally, of course, there is the actual font scaler/rasterizer implementation which is currently done by FreeType on OpenJDK. Most of the things that talk to AWT are currently done in the big mess that is the FontManager class, plus some bits in SunGraphicsEnvironment subclasses. The FontManager is a kitchen sink for all kinds of tasks, including Windows and Solaris specific handling, all ‘nicely’ munched in a big all-static utility class with no way of providing alternative implementations. In Caciocavallo, we refactored this into a FontManager interface with a corresponding factory, and moved all the platform specific stuff in platform specific implementations of this interface. This way it should be possible to provide an alternative implementation of mapping fonts to system specific resources and hooking into the Font2D system. I don’t think that I will provide an interface to the rasterizer though: I assume that the rasterizer and the font implementation should go hand in hand anyway, and know about each other somehow. (Update: Duh. Of course, there already is such an interface in OpenJDK, to support both FreeType and the old non-free thing in there.) I would like to use the 100% Java TrueType implementation of GNU Classpath as a proof-of-concept for all this work, but I’m not sure how to handle the legal stuff (this code was originally contributed to GNU Classpath by Sascha Brawer, and I don’t think I’ll ask him to sign the SCA and all that). Maybe I simply put that in my own repository outside of OpenJDK.

Cacio Swing AWT peers

The last couple of days, I was shitting out^W^W writing some new interesting stuff for Caciocavallo. Inspired by the old Swing based AWT peers of GNU Classpath, and the X11 peers of OpenJDK, here comes the shiny new Swing based AWT peers of Caciocavallo and OpenJDK.

The idea

.. is this: implement a set of AWT widget peers, which are not backed up by Motif, Win32, GTK or Qt (the traditional implementations of (Open)JDK and GNU Classpath), but, as the names says, by Swing! This probably sounds a little weird. Isn’t Swing built on top of AWT? How can I then build AWT on top of Swing? Yeah, I admit, there’s some magic and wizardry involved here, but the general idea is this: Swing is not really based on AWT (as: AWT, the widget set), Swing basically only uses the Java2D implementation and the toplevel widgets (Window, Frame and Dialog) from AWT. All the widgets (buttons, labels, textareas, etc) are implemented separately (using only a little bit of common infrastructure from Component, Container and for the event handling). So it should be possible to build AWT peers, that use Swing components for drawing and for handling the logic. This is particularily cool for platforms that don’t have any native widget set (that is, most of the platforms I usually work on: they only barely have a screen to draw on, no desktop, no widgets, etc).

For people that followed my blog in the past, this should not be so much news. In GNU Classpath we already had an implementation of this idea for a long time, and it was working quite well – to some degree. At some point, some problems were popping up, which were related to some special behaviour of heavyweight components. Back then, I added some workarounds to ’emulate’ this behavious, but it was becoming worse and worse. Examples of this behaviour are: Making a component invisible must expose the underlying heavyweight. Lightweights are always painted on top of their containing heavyweight (try mixing Swing and AWT widgets in a hierarchy – it’s fun!)

I was ‘enlightened’ when I studied OpenJDK’s X11 peers. The trick was to make all AWT components live in their own (X11) window! This was the missing piece of the puzzle. Unfortunately, the X11 peers were not designed with portability in mind, but instead are designed to be very closely tied to X11. They even use some Swing stuff for text components!

The implementation

So, what were are doing now is pulling together these two ideas: Let all AWT components live in their own native window, and use Swing for drawing and handling the logic. The implementation of this idea looks like this: At the top of the peer hierarchy is the CacioComponentPeer class. This class implements all of the common infrastructure that is shared by all components. And since all components are now real windows, this class also implements the windowing behaviour. The tricky part is, how to make this portable? On different platforms we want to replace how the native windows are implemented. Subclassing is not an option, because we want to subclass the other widget peers from the CacioComponentPeer. A reasonable solution is to not actually implement the windowing behaviour in the CacioComponentPeer, but delegate all this behaviour to a delegate object. I called it ‘PlatformWindow’ and created a nice clean interface for that. This looks very much like the WindowPeer interface, but has some additional stuff in it. In order to port AWT, it would only be necessary to implement this one interface, and get all the AWT widgets for free (because they use this interface only, plus Swing for the rest).

Now the widget peers: they are of course subclasses of CacioComponentPeer. The CacioButtonPeer for example: it subclasses CacioComponentPeer, and thus inherits the fact that it lives in a window. It also has a Swing component ‘inside’, to which the painting and event handling is delegated. I had to do some tricks there: for example, the Swing component must not be connected to the component hierarchy (applications must not see it!), but it must still think it has a parent. So I override getParent() in this Swing component to give it the ‘containing’ AWT component as parent. From the AWT hierarchy POV, there is no Swing component, but from the Swing component POV, there is a valid hierarchy. This is only an example of the tricks that are necessary inside.

So far, I have some working proof-of-concept code in the Caciocavallo-NG repository. It is already possible to open up an AWT frame with an AWT Button, Label and Canvas inside – which look exactly like Swing components:

Caciocavallo Swing peers prototype

Even some event handling already works: I can click on the button and activate it using the space bar.

The best thing from my point of view is the great portability of this solution: in order to port AWT, it’s only necessary to implement a Java2D pipeline (which is not so difficult because it’s possible to reuse a lot of code in OpenJDK) and the PlatformWindow interface for the native windowing support as well as the usual suspects like Toolkit (actually, better to subclass CacioToolkit now) and GraphicsEnvironment. That should make my life (and hopefully the life of other developers who want to port AWT to their favorite platform) much easier. Get the code from from the Cacio-NG repository.