The Ghost of PicoGUI Past
- "Those who cannot remember the past are condemned to repeat it."
- -- George Santayana
These days it's easy to describe PicoGUI as a system designed for writing applications for multiple embedded and conventional platforms, a GUI with good theme support, or a highly configurable GUI for systems with varying memory requirements. It's origins were far different.
In winter of 1999, I was working on my first embedded system powerful enough to run Linux: the Kiwi, a messy wire-wrapped board with a Motorola Dragonball 68EZ328 processor. The specs were pitiful by today's standards- 16MHz, 8MB of DRAM, 240x64 pixel grayscale LCD, no touchscreen. Once I wrote a bootloader and got it running uCLinux, I started looking for a GUI. I had experience with PalmOS development, and had always hated it's GUI. Any resolution other than 160x160 would completely disrupt most applications. Since I planned on increasing it's LCD resolution for the next prototype, I wanted software that would be flexible enough to handle that with style. At the time, I was also planning on making the GUI entirely keyboard driven. The Kiwi was intended as an extremely affordable device high school students could use to take notes and organize them, so a touchscreen would have been wasted expense. However, as with the LCD, I wanted to leave the option open to use a touchscreen in the future.
I honestly don't remember why I didn't settle on an existing GUI like Microwindows at the time, but for better or worse PicoGUI was born. After only a weekend or two of coding, in March of 2000, I set up the CVS repository on Sourceforge. Since this CVS history has been preserved in the migration to Subversion, you can still easily check out the original code.
If you did so, odds are you wouldn't recognize much. PicoGUI wouldn't have it's current autoconf/automake build system for another 6 months or so. There was no sign of the current pseudo-modular video, input, and font driver layers. Event handling was completely nonexistent. There were no real client libraries, just a few tests written in Perl. Perhaps the one thing that's survived this whole time has been PicoGUI's layout system- and it's that layout system that has shaped PicoGUI into what it is today.
If it wasn't for the vision PicoGUI's layout system inspired in me, PicoGUI probably would have just ended up as one of countless hobby GUIs that were used for one project then discarded, never developing the critical mass of features needed for general-purpose use. Instead, I lost interest in the Kiwi project and PicoGUI's goal shifted.
Many companies and individuals became interested in PicoGUI. It gained several nifty subsystems- the "hotspot" mechanism for keyboard navigation, input filters, the theme language, its flexible video driver layer. However, the fundamentals of PicoGUI's layout and rendering haven't changed. This layout system provided the inspiration to make PicoGUI the scalable GUI that it strives to be today, but also restricted PicoGUI's development as we will see below.
- "Plan to throw one away."
- -- Fred Brooks
Looking back on PicoGUI, it's clear that it suffered from being the product of my blind ambition rather than calculated steps toward a goal. I worked on it because it was fun, and occasionally useful. Normally large-scale software projects tossed together under such a methodology die quickly due to lack of interest, but for some reason PicoGUI retained my interest far longer than expected.
To be successful, an Open Source software project needs a critical mass of functionality and interest that compells people to contribute to it. PicoGUI's huge scope consequently gives it a huge critical mass that must be reached before many developers would think of contributing. Throughout most of PicoGUI's life, I've been single-handedly pushing it toward this critical mass. Eventually it gets close enough that people get interested in PicoGUI and start contributing, but this happens late enough that any fundamental flaws never see a second set of eyes.
This is a short catalog of the flaws I see in the current PicoGUI design:
- Designed in a vacuum
- This can be seen as the root cause of most of these flaws. For a long time I was the only person developing PicoGUI, and I generally didn't research other GUI systems. In some ways this helped- PicoGUI's theme and layout systems probably would n't have been nearly as interesting to me if I hadn't used a very unconventional design. Most of the time though, this just blinded me to the innovations and failures already made in GUIs of the past.
- Monolithic server
- The PicoGUI server's monolithic design combined with a thick coating of compile-time configuration was intended to allow arbitrary complexity in the server while only compiling those features necessary for a particular device. The resulting code would be compact and run fast. Unfortunately, this did nothing to improve the maintainability of the server. Very few people understand the server's internals, because the only clearly defined interface is that between the client and server. Most importantly, this is the cause of the huge critical mass PicoGUI would need in order to be successful.
- Overly simplistic rendering engine
- Originally I thought that by keeping PicoGUI's rendering engine simple, and avoiding such commonplace features as nonrectangular clipping regions, I could keep the code small, simple, and fast. This instead made much of the rendering code more complex than it needed to be due to lack of proper abstraction layers. Additionally, it made PicoGUI completely incapable of rendering proper translucency or overlapping. There were plans for a rendering engine rewrite that would fix some of these problems.
- Too low-level
- PicoGUI tries to make as few assumptions about the display as possible, but there are still some big ones the current system. Everything deals with 2-dimensional integer coordinates directly- there's no abstraction for dealing with basic shapes. This will make it impossible for the current design to do real scalable graphics, or to handle 3D drawing without a mess of ugly hacks. Ther e is no abstraction for a drawable- just separate objects for bitmaps and fillstyles. Video drivers make their output device a special case of bitmaps, even when that isn't a useful representation. This makes it impossible to handle vector graphics properly, causing the monstrous kludge that is PicoGUI's canvas widget.
- PicoGUI has never concentrated on being compatible with existing systems, but if it is ever to be useful in PDAs or desktop computers, it needs to be able to interoperate with other GUI systems as well as possible. The rootless mode already supported is a large part of this, but to be truly useful PicoGUI needs to be able to run X applications in a "rootless" fasion, and map other widgets sets like Gtk and Qt onto PicoGUI widgets as well as possible. Of course the mapping couldn't be perfect, but it would be a great transitional step. The current design's layout engine made this very hard.
- PicoGUI's server requires all widgets, video drivers, input drivers, and font engines to be compiled in to the binary. It would be possible to implement a way to load modules from shared objects, but it isn't possible in the current design to implement new widgets on the client side.
- Lack of client/server flexibility
- Even though PicoGUI places the client/server split at a more useful place than the X Window System, it is still restricted to being in only one place. Some applications may work better if you could run a little client code on the server side. You could do this by adding a script interpreter to the server, but the current design would make that clumsy and hard to properly sandbox. It would be much better for the server to be broken up into a constellation of modules, with interprocess or intermachine boundaries placed anywhere.
- "Experience is the name everyone gives to their mistakes."
- -- Oscar Wilde
- "It's a curious thing about our industry: not only do we not learn from our mistakes, we also don't learn from our successes."
- -- Keith Braithwaite
Of course it would be possible to incrementally fix these flaws in the current code- but some of them would require changing very basic components relied on by the entirety of the server, like the layout engine or the object model. In the end, most of the code would be rewritten and the product would be inferior to what would result if the entire thing was redesigned coherently. Therefore, I proposed that the current code be put into a maintenance-only mode of development and released as PicoGUI 1.0, while we start developing a completely new codebase in paralell, to be eventually released as PicoGUI 2.0. The rest of this document describes the planned architecture for "pg2", rather than the current design.
This raises many questions. Perhaps the most important is one of duplication of effort: This plan basically means starting another new GUI system from scratch. Why not just improve another GUI system to meet PicoGUI's goals?
Fresco has many goals in common with PicoGUI: portability, modularity, standalone operation, consistency, language transparency. It's designed around a scene graph that makes its client/server relationship very similar to PicoGUI's. However, there is a critical difference between PicoGUI and Fresco.
Fresco is essentially a device abstraction layer. The programmer, via a WidgetKit, creates Graphics in its scene graph that represent a widget. Fresco's job is to make sure those Graphics appear the same on any device. This is great for representing graphics. Most GUIs, though, primarily display information rather than a specific graphic. Just like the X Window System allows application authors to choose an additional layer to represent widgets, Fresco allows application authors to choose an additional layer to represent information.
Even if a standard way of representing GUI information at a semantic level was introduced into Fresco, its design doesn't meet PicoGUI's goals for embedded systems. Most important is speed and code size- Fresco uses features like C++ and floating point math that are slow or unavailable on many embedded systems. Even if you disregard speed and size, assuming that the hardware will eventually catch up- Fresco's design would make it very hard to implement some of the key features I want PicoGUI to have.
Consider a PIM application running on a PDA. The user brings the PDA home or to work, and wishes to edit its information on a desktop computer. Traditionally, you would have to have two separate implementations of the same software for the desktop and the PDA, and a way to synchronize data between them. This makes it clumsy to write good PDA software.
If the PIM was a PicoGUI app, with PicoGUI running on both the PDA and the Desktop, (not necessarily displacing X or Win32- remember PicoGUI can run inside a host GUI system) you could simply display the PDA's PIM application on the desktop. This is something that any client/server GUI can do though- how is this justification for a new GUI system?
On any current system, including X, PicoGUI 1.x, and Fresco, you would have to terminate the PIM application, then restart it with a remote display on the desktop. It would then, in the case of Fresco or PicoGUI, inherit the look and feel of the desktop system. The information would still be fundamentally laid out the same as on a PDA, so the desktop user would be presented with a very cramped little window that would make them regret having tried the procedure at all.
With the new pg2 design, you could attach a new layout server and I/O server running on your desktop to the application and "Object Kernel" running on the PDA. The application would be simultaneously usable from both devices, with the information presented in ways most appropriate for both. This wouldn't be possible in the current Fresco design. If the application stored all its data via the Object Kernel, you might even be able to transfer a running application from the PDA to the desktop and back. It would revolutionize mobile computing.
For me at least, the possibility of doing something great combined with the opportunity to start over with a fresh and coherent design is more than enough motivation to rewrite PicoGUI.