Inside SWT

Wednesday, July 05, 2006

How does anything work?

When I think about all the places SWT runs and the things we do to make it work, it blows my mind.

Windows flavours include Windows 98, CE, NT, 2000, ME, XP and soon Vista. The win32 API has two identical calls for everything, one for ANSI and one for Unicode. Windows 98 and ME support only ANSI, while CE supports only Unicode. Windows NT, 2000, XP and Vista support both. This means no single API is available on all Windows platforms. C programs are supposed to compile for one or the other. Instead, we build one set of jars and native libraries for both and call the right API on the fly. It's ugly, but it works.

GTK is version hell. We run all the way back to 2.0.6. Lots of new API has been added since then so we look them up dynamically because Linux won't load a shared library with unsatisfied references. Somehow, when an operating system API isn't there, we run alternate code or fail gracefully. Whew!

Mozilla is it's own nightmare. Until recently, rather than using the Mozilla that you had installed on your machine, expected you to ship a copy of Mozilla statically linked to your application. Somehow we don't do this, find the installed Mozilla and use it. We work with Mozilla versions as old as 1.2 all the way up to 1.8, which was the latest at the time this article was written. The Linux C++ binary format changed somewhere along the way, breaking us. We detect the right version dynamically and load the one of two identical libraries, compiled differently. Wow.

Advanced graphics on Linux uses the cairo graphics library but this doesn't ship with the current Linux distributions, so we compile and ship our own, just in case. On the fly, we detect whether you already have cairo installed and use that one. Otherwise, we use the one we compiled. It's magic.

The Macintosh comes with two complete and separate native toolkits, carbon and cocoa. We use carbon, the C based API. However, new features in the operating system are very often only available in cocoa. Cocoa is Objective C, not C. Safari, the Mac browser, is written in cocoa. So we call it, leading to wild clipping problems and all sorts of amazing interop issues that we work around. Did I mention that Macintosh controls didn't clip against each other until a few years ago so we had to roll our own sibling and parent clipping code?

AWT is a free threaded widget toolkit that comes with it's own event loop. On Windows, we hook into the event queue and cross post keystrokes. On Motif and GTK, life is easier, we implement the XEmbed protocol, which is a bunch of low level X windows calls. On the Mac, after being broken for ages, we got help from Apple. The Mac operating system has no concept of multiple event loops. Somehow, Apple found a way to make it work. The icing on the cake is that AWT is implemented in cocoa, not carbon.

On the Java side, we need 1.2 VM's or greater and run on J2SE and J2ME. If you recompile the native libraries, we'll run on 1.1.8.

My gawd.



  • WOW

    By Blogger RefuX, at 9:39 PM  

  • If only you used a portable toolkit like QT... I'm sure licensing agreements of some sort could have been made. And paying the devel licences for QT would have been a lot more cost effective than paying developers for 4 different toolkits.

    By Anonymous Anonymous, at 3:44 AM  

  • QT won't do. It's an emulation of the platform (except on Linux of course). Since being native is a design point of SWT, it's a non-starter.


    By Blogger Steve, at 9:42 AM  

  • How do custom controls implemented with paint listeners translate into native OS resources ? When I do a gradient fill, how efficient is it?

    Advanced graphics on Windows use what implementation ?

    By Anonymous Aaron, at 10:37 AM  

  • On Windows, a paint event is issued by SWT for WM_PAINT messages, on X/Motif, a paint event is send for XExpose event's and so on.

    Gradient fills and other advanced graphics operations are implemented directly in the operating system in the same manner. For example, GDI or GDI+ is called directly on Windows when you invoke the equivalent operation on an SWT GC.


    By Blogger Steve, at 12:16 PM  

  • QT is not an emulation. Where do you get that kind of information from?

    It uses the native theme engine of each platform to draw.

    By Anonymous Anonymous, at 4:00 PM  

  • Drawing using the theme engine does is emulating.


    By Blogger Steve, at 6:06 PM  

  • @Anonymous: Swing on Windows XP uses the theme engine to draw components too (it'd be illegal for it to *include* Windows XP widget graphics since they are copyrighted).

    You're going to say Swing is native?

    By Blogger Nicolas, at 1:25 PM  

  • Eh?

    You are native if you are running the native widget code for everything. At that point, you are feature for feature, bug for bug compatible. You are the platform, not an emulation of it.

    By Blogger Steve, at 1:36 PM  

Post a Comment

<< Home