| ELJonline: Using GTK+/X as an Embedded GUI |
Chuck Groom (January, 2002)
X Windows and GTK+ are not the bloated monsters you think they are. Here's how we modified GTK+/X for our device's GUI.
Consumer embedded devices require a graphical user interface (GUI) tailored to specific device characteristics. To offer a handful of examples: - Touchscreens should use large buttons to accommodate the width of fingers and inaccurate measurements
- Softkeys (general-purpose buttons next to the screen) require a dedicated on-screen softkey region
- A keyboard-centric device should organize data into vertical lists whereas a mouse-centric device may organize data by geographic space
- Devices with low-contrast screens should avoid swaths of gray
A major factor in the success of Palm Pilots is a UI paradigm designed to fit the Palm device. The plain widget look provides on-screen simplicity, the menu system offers a good compromise between offering user options and optimizing screen real estate, and the applications are designed around stylus input. One of the reasons why WinCE and Palm-sized PC devices did not initially do as well is that a general-purpose GUI design borrowed from desktop paradigms is not appropriate for embedded devices.
A Linux GUI consists of several individual parts, some of which may be interchangeable. The GUI provided by desktop Linux distributors like Red Hat, SuSE, or Debian includes a windowing system for basic drawing and overlapping window support, a widget set (or sets) for applications to use, a window manager to implement windowing policies and to decorate windows, and a desktop environment to tie everything together into a coherent whole. For an embedded GUI, the windowing system and widget set are the most important components.
There are several embeddable widget sets for Linux, including Qt/E, FLTK, and GTK+. These can run on several possible windowing systems, including the X Window System and a direct framebuffer interface. An embedded systems developer must ask: Which combination of options is right for my system? Which widget toolkit should I adopt? How much engineering effort is needed to tweak to spec? What footprint will all this require?
This article describes our experience designing and implementing a custom GUI for a consumer Linux device. We decided to use GTK+ running on the X Window System. It took five engineer-months to produce our stable, customized and reduced-footprint GUI totaling 2.9MB (including X).
Custom UI
We designed a custom UI to match our device's I/O characteristics. Our device has a small, low-quality screen and no mouse. A row of softkeys under the screen provides primary user input (Figure 1). The bottom 14 pixel region of the screen is reserved for displaying monikers above softkeys. This is the softkey bar.
 Figure 1: Device mockup.
Rather than create new paradigms that would confuse users, the rest of the UI is drawn as a typical point-and-click interface, complete with buttons and scrollbars. We maintain the user's control metaphor of physically "pushing" widgets by substituting "push-via-softkey" for "point-and-click". Each button is arranged horizontally with an arrow dropped under it that extends across the window border into the softkey bar. Figures 2-5 show the elements of our UI design, including buttons.
 Figure 2: Buttons extend an arrow into the softkey bar. While pressed, the button and its arrow are filled with gray.
 Figure 3: Text entry fields use a bold-face font for the label and a plain-face font for the user's text. This uses minimal screen real estate to differentiate between the two elements.
 Figure 4: Scrollbars visually fit into the scrolled panes they control, giving an uncluttered look.
Figure 5: Application windows and dialogs are shaped and drawn with different titlebar designs. The topmost window gets the softkey bar.
After several rounds of testing the usability and aesthetic appeal of various mockups, we hammered out this UI design and the accompanying developer style guide. Our relief in finishing the design was cut short with thoughts of actually putting the UI together. We had conscientiously avoided considering implementation when drafting this UI. What programmer in his right mind would WANT shaped windows, arrows spanning several widgets, and numerous fonts? Now it was time to roll up our sleeves, pick a GUI, and get to work.
Choosing GTK+/X
Linux has never adopted any One True UI. There is a myriad of interfaces for both desktop and embedded products. While this fragmentation has been an obstacle in standardizing a Linux desktop, Linux's detachment from its UI has been a benefit to embedded devices. Old UIs are easily removed and newer ones are readily adopted. When designing a device requiring a custom interface, it is good to have a wide range of UI options.
A quick survey of embeddable Linux widget sets gives a list including Gtk+, Qt/E, FLTK, OpenGUI, MiniGUI, PicoGUI, and PicoTK. Most of these toolkits require a separate windowing and/or display system like X Windows, Microwindows, or direct framebuffer access.
Our GUI requirements include: - Full-featured widget set
- Display several applications simultaneously
- Allow third-party add-on applications
- License is compatible with proprietary software
- Stable enough to withstand buggy applications
- Codebase that we can modify as needed
- Royalty-free, without license costs to us or after-market developers
Additionally, we would prefer to use a mature GUI with a sizable application base. This gives a pool of applications that could be easily adapted to the device, as well as a large community of after-market developers.
Using the above criteria, we narrowed our GUI choices to GTK+ or Qt/E.
Qt is a GUI recently developed by TrollTech and used by the KDE desktop. Is has an OOP-intensive C++ framework. Qt/Embedded (Qt/E) is a reduced version of Qt that runs on a framebuffer. It sports a clean widget set, a signal/slot architecture, and graphics abilities including TrueType fonts and alpha blending. The Qt Palmtop Environment (QPE) is an application infrastructure that includes Qt/E running on a framebuffered client/server windowing architecture, along with a host of PIM applications.
GTK+ is a GUI with a C-based object-oriented architecture. The GNOME desktop uses GTK+. GTK+ features clean abstractions between the GTK+ library which manages widgets and signals, the Gdk library which manages windowing and drawing, and the Glib library which provides low-level data structures and utilities. GTK+ was developed on the X Window System, but has been ported to many systems, including a framebuffer (GTK+/fb) and Microwindows, a small windowing system (see Introduction to Microwindows Programming Jan/Feb 2001).
We briefly toyed with the idea of using GTK+/fb or GTK+/Microwindows. There are two problems with GTK+/fb: (1) applications cannot share the display, and as a consequence (2) if an application crashes, it brings down the entire GUI. Compiling applications together into a monolithic single framebuffered application only exacerbates (2), and makes it hard to allow add-on applications. While using Microwindows would dodge these problems, it is not yet mature.
We refined our decision to Qt/E running within QPE versus GTK+ running on the X Window System. The decision to consider X may surprise many embedded developers.
X is a 20+ year old network-transparent client-server windowing system. A single "display server" manages client display requests through an interprocess communication protocol. This makes it remarkably crash-proof. X does not include any widgets, but underlies many popular widget toolkits. Although it is well-established and well-supported, it is often assumed that X is bloated and incurs too much overhead to be useful in embedded devices. Jim Gettys, an original X author, rejects this belief, saying "most of what you hear about X being too big are from people who know little or nothing about the topic" (further info).
Recent efforts to streamline X have been successful, giving good performance on embedded hardware. We selected Keith Packard's TinyX, now a part of the standard XFree86 source tree, as our flavor of X.
We ultimately chose GTK+ 1.2.8 running on X Windows, in turn running on a framebuffer. The decision to use GTK+ instead of Qt/E was primarily a conservative preference to stick with a proven solution, but it was also informed by key differences between GTK+ and Qt/E . . . - Ownership: All things being equal, we prefer to place our trust in publicly-maintained codebases. TrollTech owns Qt/E and develops it internally without public exposure. GTK+ and XFree86 are highly visible Open Source projects with large, active development communities.
- License: GTK+ is licensed under the LGPL. This allows proprietary 3rd-party software to use our derived GUI. Qt/E is released under a dual-license scheme which either releases it under the GPL or requires licensing and royalties. These terms would prevent us and other developers from releasing proprietary software for our device without paying TrollTech.
- Size: Although TrollTech claims that Qt/E can be as small as 1MB, internal dependency conflicts prevented it from compiling at this size. The iPaq QPE distribution includes a 3.3MB Qt/E library and a 718KB QPE library (analogous to Xlib). TinyX and our modified GTK+ required 2.9MB (compiled for the same architecture).
- Stability: Although Qt is a mature widget set, Qt/E is still not entirely stable. The QPE demo is good, but applications and QPE itself occasionally crash. GTK+ rarely crashes, but when it does X is unaffected.
- Language: In our experience, C is a better language than C++ for small teams working on embedded devices. Qt/E is written in C++. GTK+ and X are written in C.
C vs. C++ on Embedded Devices
X
There has been a surge of interest and work in making X appropriate for embedded devices. Jim Gettys defended the future of PDAs running X, stating that "I believe very strongly that either GTK+/fb or Qt/E are dead ends" for PDAs because they cannot easily share applications with desktop systems and lack network transparency. He goes on to describe the ongoing work to put Xlib "on a diet."
The standard TinyX distribution worked perfectly on our device. To further reduce the size of TinyX, we moved the color management system (CMS) into its own library. Not using the CMS saves 86KB. Other planned reductions include removing unused, large functions like arcs and widelines, and converting macros into functions.
Tailoring GTK+ -- "Tailoring" is a good description for the next stage of our UI process. We started with the standard distribution of GTK+ 1.2.8 and snipped away excess, altered existing code, and added some new features. These modifications ranged from minor to extreme. Some even broke core GTK+ assumptions. Footprint
After the dust had settled from the frenzy of implementing our UI, we were left with a stable system that looked and behaved exactly like our draft UI.
Compiled for the ARM architecture, our GUI's footprint is:

GTK+ still includes code that we will never use and could be removed. We estimate that another engineer-month of effort will reduce GTK+ to 850KB, bringing the GUI footprint to 2.8MB.
Performance
Our UI gives reasonable run-time performance on an ARM7 CPU (roughly equivalent to a 75MHz Pentium). Widget response time to user events is lightning fast. New screens are built and drawn at acceptable speeds.
We have been plagued by slow launch times. Our most complicated application takes as long as 2.4 seconds to load and display. Of this, 1.5 seconds are spent building and displaying the UI.
This lag stems from running GTK+ on X, which writes to a framebuffer, on under-powered hardware. No one factor is to blame. When we ran applications on our desktop machines displaying remotely to the device, initialization and drawing times were negligible. Conversely, there was good performance when running applications on the device displaying remotely to our desktop machines. Neither packet transmission, nor drawing to the framebuffer, nor GTK+'s computations were a bottleneck. The slowdown appears to be a consequence of these factors in tandem. We probably max out the under-powered CPU. It is also likely that there are also memory bandwidth constraints. At initialization time, GTK+ constructs many objects, GTK+ and X are communicating via shared memory, X is writing to the framebuffer, and the framebuffer is constantly written to the display. The memory bus runs at 18MHz and the framebuffer claims fully one quarter of this bandwidth, so the memory-intensive operations of initialization are understandably slow.
Of course, the obvious but pricey solution would be to use better hardware. We estimate that on an iPaq (100MHz memory bus, 206MHz StrongARM) applications would load 2.5 times faster, giving a respectable 1 second worst-case launch time. But since our normal operation is perfectly reasonable, we will try other solutions first.
X is costly at at initialization time. The client GTK+ application connects with the server, authenticates itself, and negotiates bit depth and other resources. The benefits of using X outweigh this overhead. X provides a robust client-server model that allows add-on applications. We can show different applications' windows at the same time, which cannot be done for most framebuffered solutions like GTK+/Fb (QPE is a notable exception).
A 2.4 second lag is not the end of the world. On a 700MHz Windows NT machine, neither Word, nor Excel, nor Internet Explorer loads in less than 1.5 seconds. 'Kedit', a KDE application, loads in 1.37 seconds on a 500MHz PIII (http://www.suse.de/~bastian/Export/linking.txt). We realize this may not be a legitimate comparison, however. Users accept lag on powerful desktop machines but expect an instant response on portable devices.
Why can PalmOS launch applications instantly? PalmOS achieves excellent speed on a small scale by using a thin OS running everything in a single address space. These are limiting factors for creating complex software. An application can crash the OS. There is no multitasking, hence no multiprocess solutions to problems. A modern operating system like Linux enables development of the complex software we want to create, but the trade-off is system overhead which is more visible on slower hardware.
We have adopted two interim strategies for dealing with the launch time problem. The first strategy is to amuse the user with eye candy as the application launches. A slow response can be forgiven as long as something happens to show that the computer is working on your behalf. The other strategy is to predictively launch commonly-used applications in the background.
Optimizations
We were able to target a few areas of GTK+ for future optimization.
We profiled the effect of removing floating point calculations from GTK+. Our ARM7 lacks an FPU so floating point calculations are a big performance hit. GTK+ uses floating point variables in a few, but commonly-used, widgets. We concluded that removing these calculations would give a 3-12% speed improvement, depending on the application.
Pixmap-rich applications were unacceptably slow. Upon investigation, we discovered that the problem was largely caused by inefficient pixmap handling methods in GTK+ and X. The X pixmap (XPM) format is designed for compatibility, not for speed, and GTK's handling of it is not fully optimized. More importantly, the pixmaps are passed from the GTK client to the X server one pixel at a time. It would be far more efficient for the client to pass the pixmap by reference to the X server, allowing direct display of a precalculated binary image.
We fixed obvious pixmap problems with GTK+ and wrote a temporary hack to grab post-rendered pixmaps from the X server and use the raw data as a replacement to XPMs. These raw images could be forcibly written to the X server. While this is an ugly solution that nobody in his right mind should use, it was 80% faster than using XPMs and demonstrates that an alternate pixmap solution could yield much better performance.
Conclusion
Consumer devices deserve a lovingly hand-crafted GUI. The Linux community has produced a number of Open Source GUIs that can be easily tailored to meet even the most bizarre design. The real difficulty is in selecting a GUI; after this, the implementation follows requirements in a fairly straightforward manner.
GTK+ was the best GUI toolkit for our needs, and X Windows provided a stable client/server model that was worth the cost of footprint and launch speed. While we are proud that we got a 2.9MB custom GUI up and running on our hardware with five engineer-months of effort, most of the credit is due to an Open Source community that produces fine software that can be squished and prodded into embedded devices.
About the author: Chuck Groom (cgroom@bluemug.com) is a project engineer for Blue Mug, Inc. One of his pet peeves is that too many embedded devices are technically brilliant but useless. He ponders ways that free software can make the world a better place.
Copyright © 2001 Specialized Systems Consultants, Inc. All rights reserved. Embedded Linux Journal Online is a cooperative project of Embedded Linux Journal and LinuxDevices.com.
(Click here for further information)
|
|
|
FUEL Database on MontaVista Linux
Whether building a mobile handset, a car navigation system, a package tracking device, or a home entertainment console, developers need capable software systems, including an operating system, development tools, and supporting libraries, to gain maximum benefit from their hardware platform and to meet aggressive time-to-market goals.
Breaking New Ground: The Evolution of Linux Clustering
With a platform comprising a complete Linux distribution, enhanced for clustering, and tailored for HPC, Penguin Computing¿s Scyld Software provides the building blocks for organizations from enterprises to workgroups to deploy, manage, and maintain Linux clusters, regardless of their size.
Data Monitoring with NightStar LX
Unlike ordinary debuggers, NightStar LX doesn¿t leave you stranded in the dark. It¿s more than just a debugger, it¿s a whole suite of integrated diagnostic tools designed for time-critical Linux applications to reduce test time, increase productivity and lower costs. You can debug, monitor, analyze and tune with minimal intrusion, so you see real execution behavior. And that¿s positively illuminating.
Virtualizing Service Provider Networks with Vyatta
This paper highlights Vyatta's unique ability to virtualize networking functions using Vyatta's secure routing software in service provider environments.
High Availability Messaging Solution Using AXIGEN, Heartbeat and DRBD
This white paper discusses a high-availability messaging solution relying on the AXIGEN Mail Server, Heartbeat and DRBD. Solution architecture and implementation, as well as benefits of using AXIGEN for this setup are all presented in detail.
Understanding the Financial Benefits of Open Source
Will open source pay off? Open source is becoming standard within enterprises, often because of cost savings. Find out how much of a financial impact it can have on your organization. Get this methodology and calculator now, compliments of JBoss.
Embedded Hardware and OS Technology Empower PC-Based Platforms
The modern embedded computer is the jack of all trades appearing in many forms.
Data Management for Real-Time Distributed Systems
This paper provides an overview of the network-centric computing model, data distribution services, and distributed data management. It then describes how the SkyBoard integration and synchronization service, coupled with an implementation of the OMG¿s Data Distribution Service (DDS) standard, can be used to create an efficient data distribution, storage, and retrieval system.
7 Advantages of D2D Backup
For decades, tape has been the backup medium of choice. But, now, disk-to-disk (D2D) backup is gaining in favor. Learn why you should make the move in this whitepaper.
|
|
|
|
|