old-www/LDP/LG/issue35/icaza.html

613 lines
28 KiB
HTML

<!--startcut ==========================================================-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<title>The GNOME Project LG #35</title>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#A000A0"
ALINK="#FF0000">
<!--endcut ============================================================-->
<H4>
"Linux Gazette...<I>making Linux just a little more fun!</I>"
</H4>
<P> <HR> <P>
<!--===================================================================-->
<font color="navy">A <I>Linux Journal</I> Preview</font>:
This article will appear in the February 1999 issue of <I>Linux Journal</I>.
<P> <HR> <P>
<center>
<H1><font color="maroon">The GNOME Project</font></H1>
<H4>By <a href="mailto:miguel@gnu.ai.mit.edu">Miguel de Icaza</a></H4>
</center>
<P> <HR> <P>
GNOME is an acronym for GNU's Network Object Model Environment. GNOME
addresses a number of issues that have not previously been addressed
in the UNIX world:
<p>
<ul>
<li> Providing a consistent user interface.
<li> Providing user friendly tools and making them powerful by
leveraging the UNIX foundation.
<li> Creating a UNIX standard for component programming and
component reuse.
<li> Providing a consistent mechanism for printing.
</ul>
GNOME's main objective is to provide a user-friendly suite of applications
and an easy-to-use desktop. As with most GNU programs, GNOME has been designed to
run on almost all strains of UNIX-like operating systems.
<p>
<h3>History of GNOME</h3>
<p>
The GNU GNOME project was initially announced in August, 1997, and after
just one year of development, approximately two hundred programmers
worldwide are involved in the project.
<p>
The original announcement called for developers in a number of forums,
shaping the GNOME project: the GNU announce mailing lists; the
Guile mailing list; and the GTK+ and GIMP mailing lists. The
programmers and people who influenced the project were mainly free
software enthusiasts with diverse areas of expertise, including
graphics programming and language design.
<p>
The GNOME team has been working steadily toward creating a foundation
for future free software development. GNOME provides the toolkit and
reusable component set to build the end-user free software the world
so badly needs.
<p>
Our recent releases of the GNU Network Object Model Environment have
been: GNOME 0.20, the first version of GNOME that showed signs of
integrations, released in May 1998; The Drooling Macaque 0.25 release,
with more features; and finally our latest public release, GNOME 0.30,
code named Bouncing Bonobo.
<p>
The GNOME 0.20 release was the first release included in a CD-ROM
distribution: Red Hat 5.1 shipped with a technology preview of the
GNOME desktop environment, and it was first demonstrated at the 1998
Linux Expo in North Carolina.
<p>
Before the Drooling Macaque release, the GNOME software releases were
coordinated by two or three people on the team. This became a
significant burden, as precious time was being used coordinating each
release. We have been trying to make the release process more modular
and have assigned different modules to package maintainers. Each
package maintainer is responsible for packing, testing and
releasing their packages independently of the main distribution, which
we consider to be the core libraries and the core desktop
applications. So far, we have had some success, but there is still
room for improvement. We will continue to polish the release
process to make it simpler.
<p>
The most recent GNOME release, Bouncing Bonobo, is the first to
feature the GNOME spreadsheet, Gnumeric.
<p>
<h3>Red Hat Advanced Development Labs</h3>
<p>
In January 1998, Red Hat announced the creation of the Red Hat
Advanced Development Laboratories (RHAD). The initial objective of Red Hat
Labs would be to help the GNOME effort by providing code and programmers
and by helping us manage the project resources.
<p>
All code contributed by Red Hat Advanced Laboratories to GNOME has
been provided under the terms of the GNU GPL and the GNU LGPL licenses.
Several GTK+ and GNOME developers have been hired by Red Hat, and they
have rapidly provided the GNOME project with a number of important
features.
<p>
For example, Rasterman has implemented themes for GTK+; the GTK+
themes allow the user to change the appearance of the widgets. This
is done by abstracting the widget drawing routines from the toolkit,
and putting those drawing routines in modules that can be loaded at
runtime. Thus, the user can change the appearance of applications
without shutting them down or restarting the desktop.
<p>
GTK+ themes are fully working, and so far a number of theme front-ends
have been written. At the time of this writing, the available themes
include Motif, Windows95, Metal, native-GTK+ and a general purpose
Bitmap-based engine (see Resources). The web site http://gtk.themes.org/
keeps an up-to-date list with many contributed themes from which to choose.
<p>
Various important changes to the GTK+ toolkit required for
the GNOME project, such as the menu keyboard navigation code and the
enhanced ``Drag and Drop'' protocols (XDND and Motif DND), were written by
Owen Taylor, a famous GTK+ hacker now working for Red Hat Labs.
<p>
Assorted applications were created or are maintained nowadays by the
GNOME team at RHAD as well: the Ghostscript front end (by Jonathan
Blandford), the GNOME Help Browser and the GNOME RPM interface (Marc
Ewing and Michael Fullbright), the GNOME Calendar and GNOME Canvas
(Federico Mena) and the ORBit CORBA 2.2 implementation (Elliot Lee).
<p>
<h3>Other Donations</h3>
<p>
The GNOME project received a monetary donation from the GNU/Linux
Debian team in the early stages of the project, as well as an Alpha
board from Quant-X Service and Consulting G.m.b.H. We are very
grateful for their contributions.
<p>
<h3>Some Key GNOME Features</h3>
<p>
The GNOME libraries provide a framework to create
consistent applications and to simplify the programmer's task. More
of the features of the GNOME libraries are described
later. Some of the most important current developments in the GNOME
libraries are discussed here.
<p>
<b>Metadata</b>
<p>
One of the problems that a desktop environment faces is the fact
that it is usually necessary to have a mechanism for storing
information about a file's properties. For example, applications
might want to bind an icon for a specific executable file or bind a
small thumbnail image for a graphic produced by a graphics program.
These icons should be semantically attached to the main file.
<p>
The Macintosh OS, for example, provides a way to store this information in
the file as its ``resource fork''. This mechanism would be
awkward at best to implement in a UNIX environment. The main problem
is that non-metadata-aware application can cause the metadata
information to get out of sync.
<p>
The GNOME metadata was implemented by Tom Tromey at Cygnus, given
a number of design constraints and tradeoffs (described in detail
on their web site). The following is a list of the GNOME metadata features:
<p>
<ol>
<li> Binding the information on a per-file basis is a
per-user setting, and each user keeps track of its own
bindings. System defaults apply on top of these.
<li> Binding information by file content is done according to the type of the
file using file signatures, similar to the UNIX <b>file</b> command.
<li> Binding information by a regular expression: for example,
a default icon for gif files would be provided by the regular
expression <tt>.*\.gif$</tt>.
<li> The metadata system is optimized to provide a coherent GUI
solution, rather than as a compromise or kludge to existing command line tools.
<li> Most ordinary uses of files will continue to work without
metadata, just as they do now.
</ol>
A number of standard properties for file metadata are available in
GNOME. For example, ``View'' stores the action for viewing the file
contents; ``Open'' stores analogous action for editing;
``Icon'', which contains the icon, is used for displaying the file
on the desktop.
<p>
Metadata types are MIME types.
<p>
<b>Canvas</b>
<p>
GNOME provides a <b>Canvas</b> widget, patterned after Tk's excellent
canvas. This widget simplifies the programming of applications that
need control over graphical components. The most noticeable feature
of the GNOME Canvas is that it provides a flicker-free drawing area
where high-level objects can be inserted and manipulated. Basic zoom
and scroll facilities are also a part of the canvas.
<p>
The high-level objects inserted into the canvas behave like regular
widgets. They can receive X events, they can grab the focus, and they
can grab the mouse just like a regular widget. As with their Tk
counterparts, the GNOME Canvas items can have their properties changed
at runtime with a Tk-like configuration mechanism.
<p>
The GNOME Canvas ships with a number of items derived from the
<tt>GnomeCanvasItem</tt> object: lines, rectangles, ellipses, arrows, polylines
and a generic widget container to embed GTK+ widgets within a canvas. The Canvas framework is designed to be very extensible. As
proof of this extensibility, the GNOME spreadsheet is implemented on
top of the base canvas engine, with additional functionality provided
by spreadsheet-specific <tt>CanvasItems</tt>.
<p>
Note that the current Canvas uses Gdk primitives
(a thin wrapper over Xlib primitives) to draw, so it is limited in the
quality and range of special effects that can be provided with it, which
bring us to the next step in Canvas technology.
<p>
Raph Levien is working on an advanced rendering engine for the
Canvas. It was originally developed as a stand-alone widget within his
Type1 outline font editor, <b>gfonted</b>. As of the time of this writing,
work on integrating the engine into the Canvas is getting underway.
<p>
Features of this engine include:
<p>
<ul>
<li> Anti-aliased rendering of all items
<li> Alpha transparency
<li> Items for vector and bezier paths
<li> Items for RGB and RGB plus alpha images
<li> Vector operations, including clip (intersect), union,
difference and stroke layout
<li> PostScript Type1 font loading and rendering
</ul>
The engine's design goal is to support almost all of the
PostScript imaging model with the addition of alpha transparency. As
such, it is expected to be an excellent starting point for
high-powered graphics applications.
<p>
In spite of the ambitious goal of keeping the display up to date
with entirely anti-aliased and alpha-composited items, performance is
surprisingly good--comparable in fact to the Xlib-primitive-based
canvas engine.
<p>
His code is expected to be merged into the main Canvas sometime soon.
<p>
<b>Window Manager Independence</b>
<p>
GNOME does not have any dependency on a special window manager--any
existing window manager will do. GNOME specifies window
manager hints that can be implemented by the window manager to give the
user better desktop integration, but they are optional.
The E window manager implements all of the GNOME window
manager hints and can be used as a reference implementation for people
wishing to extend their window managers to be GNOME-compliant. The
ICEWM manager is tracking those developments, and it is also considered
to be a GNOME-compliant window manager, although at this time, it is lagging
a bit behind. People have showed interest in providing the WindowMaker and
FVWM2 maintainers with patches to make those window managers GNOME-aware.
<p>
<b>Component Programming</b>
<p>
Historically, one of the attractions of UNIX has been the
philosophy of small tools that each do one thing well, and combining
these tools, using pipes and simple shell scripts, to
perform more complex tasks. This philosophy works very well when the
data objects are represented as plaintext and the operations are
effectively filters. However, this UNIX command-line philosophy does
not scale well to today's world of multimedia objects.
<p>
Thus, it would be nice to have a framework in GNOME that would
provide software reuse and component plugging and interaction,
i.e., connecting small specialized tools to carry out complex
tasks. With this infrastructure in place, GNOME applications can once again
return to the UNIX roots of simple, well-specialized tools.
<p>
An RPC system was then required for providing this sort of
functionality, so we decided to use CORBA (the Common Object Request
Broker Architecture) from the Object Management Group (OMG). CORBA can be thought
of as an object-oriented RPC system, which happens to have
standardized bindings for different languages.
<p>
CORBA opened a range of applications for us. Component
programming allowed us to package programs and shared libraries as
program servers that each implement a specific interface.
<p>
For example, the GNOME mail program, Balsa, implements the
<tt>GNOME::MailMessage</tt> interface that enables any CORBA-aware program to
remotely compose and customize the contents of a mail message and send
it. It is thus possible to replace the mail program with any program
that implements the <tt>GNOME::MailMessage</tt> interface. As far as the GNOME
desktop is concerned, the process just implements the
<tt>GNOME::MailMessage</tt> interface. This means, for example, that I will be able to
continue using GNUS to read my mail and have GNUS completely
integrated with the rest of my desktop. This also applies to the
other components in the GNOME system: the address book, the file
manager, the terminal emulation program, the help browser, the office
applications and more.
<p>
Besides providing the basic GNOME interfaces, applications can
provide an interface to their implementation-specific features. This
is done by using CORBA's interface inheritance. A specific interface
would be derived from the more general interface. For example, GNUS
would implement the <tt>GNOME::MailMessage</tt> interface and extend it with
GNUS specific features in the <tt>GNOME::GnusMailMessage</tt>
interface. This interface would hypothetically allow the user to customize
GNUS at the Lisp level, something other mailers may not do. Another example
would be a <tt>GNOME::MozillaMailMessage</tt> interface that would
let the user configure the HTML rendering engine in Mozilla mail.
<p>
Not only does CORBA address these issues, but CORBA can also be
used as a general interprocess communication engine. Instead of
inventing a new ad-hoc interprocess communication system each time
two programs need to communicate, a CORBA interface can be used.
<p>
Embedding documents into other documents has been popularized by
Microsoft with their Object Linking and Embedding architecture.
A document-embedding model similar in spirit is being designed for
GNOME (the Baboon model), and all of the interprocess communication
in this model is defined in terms of CORBA interfaces.
<p>
Initially, we were very excited by the possibilities CORBA presented
us, but we soon realized that using CORBA in the GNOME desktop was
going to be more difficult than we expected.
<p>
We tried using Xerox's ILU for our CORBA needs. The license at
the time did not permit us to make modifications to the code and
redistribute them, an important thing for the free software
community, so we had to look for alternatives. Xerox has since
changed the licensing policy.
<p>
After evaluating various free CORBA implementations, we settled on
MICO, as it was the most feature-full free implementation.
MICO was designed as a teaching tool for CORBA, with a primary focus on
code clarity.
<p>
Unfortunately, we soon found that MICO was not a production-quality tool
suitable for the needs of GNOME. For one, we found that
the rather indiscriminate use of C++ templates (both in MICO and in
MICO-generated stubs) proved to be a resource hog. Compiling bits of
GNOME required as much as 48MB of RAM for even the simplest uses of
CORBA, and this was slowing down our development. Another problem
was that MICO only supported the C++ CORBA bindings. Even though an
initial attempt had been made at providing C bindings, they were incomplete
and not well-maintained.
<p>
To address these problems, Dick Porter at i2it and Elliot Lee at Red
Hat labs wrote a C-based, thin and fast CORBA 2.2 implementation
called ORBit. As soon as ORBit became stable, the use of
CORBA throughout GNOME began, after a delay of almost eight months.
<p>
With an efficient, production quality CORBA implementation under
our control, we ensure that CORBA-enabled interprocess communication
is a valuable service for application programmers, rather than a
source of overhead and bulk.
<p>
<h3>Dissecting a GNOME desktop Application</h3>
<p>
<b>The toolkit</b>
<p>
GNOME desktop applications have been built on top of the object-oriented
GTK+ toolkit originally designed as a GUI toolkit for
the GNU Image Manipulation Program (GIMP).
<p>
GTK+ has been implemented on top of a simple window and drawing
API called Gdk (GTK Drawing Kit). The initial version of Gdk was a
fairly thin wrapper around the Xlib libraries, but a port to Win32 and a port to
the Y windowing system are presently in alpha stages.
<p>
GTK+ implements an object system entirely in C. This object
system is quite rich in functionality, including classical single
inheritance, dynamic creation of new methods and classes, and a
``signal'' mechanism for dynamically attaching handlers to the various
events that occur in the user interface. One of GTK's great strengths
is the availability of a wide range of language bindings, including
C++, Objective-C, Perl, Python, Scheme and Tom. These language
bindings provide access both to GTK+ objects and to new objects programmed
in the language of choice.
<p>
An additional feature of GNOME is Rasterman's Imlib library. This
library is implemented alongside Gdk, and provides a fast yet flexible
interface for loading and saving images, and rendering them on the
screen. Applications using Imlib have quick and direct access to PNG,
GIF, TIFF, JPEG and XPM files, as well as other formats available
through external conversion filters.
<p>
<b>The Support Libraries</b>
<p>
C-based GNOME applications use the glib utility library. Glib
provides the C programmer with a set of useful data structures:
linked lists, doubly linked lists, hash tables (one-to-one maps),
trees, string manipulation, memory-chunk reuse, debugging macros,
assertion and logging facilities. Glib also includes a portable
interface for a dynamic module facility.
<p>
<b>The GNOME libraries</b>
<p>
The GNOME libraries add the missing pieces to the toolkit
to create full applications, dictate some policy, and help
in the process of providing consistent user interfaces, as well as
localizing the GNOME applications so they can be used in various countries.
<p>
The current GNOME libraries are: GTK+-xmhtml, gnome-print,
libgnome, libgnomeui, libgnorba, libgtop, gnome-dom and gnome-xml.
Other libraries are used for specific applications: libPropList (soon
to be replaced by a new configuration engine) and audiofile.
<p>
The main non-graphical library is called libgnome. This provides
functions to keep track of recently used documents, configuration
information, metadata handling (see below), game score functions and
command-line argument handling. This library does not depend on the
use of a windowing system.
<p>
As we use CORBA to achieve parts of our desktop integration, we
have a special library that deals with various CORBA issues,
called the libgnorba library. It provides GUI/CORBA integration (to
let our GUI applications act as servers), authentication within the
GNOME framework, and service activation.
<p>
The gnomeui library, on the other hand, has the code that requires a
window system to run. It contains the following components:
<p>
<ul>
<li> The GNOME session management support
<li> Widgets, both as straightforward extensions of GTK+ and
designed to be dependent on libgnome features
<li> A set of standard dialog boxes otherwise not available on
GTK+, well-integrated with other GNOME libraries
<li> Standard property configuration dialog boxes
<li> Standard top-level window handling
<li> A multi-document interface (gnome-mdi)
<li> Windowing hints
<li> CORBA integration where required
</ul>
GTK+-XmHTML is a port of the Koen D'Hondt's XmHTML widget for Motif,
and it is used for our HTML display needs. Our changes are being
folded back into the main distribution.
<p>
The gtop library allows system applications to be easily ported to
various operating systems; it provides system, process and file
system information.
<p>
<b>gnome-xml</b> provides XML file loading, parsing and saving for GNOME
applications, and it is being used in the GNOME spreadsheet (<b>Gnumeric</b>)
and in the GNOME word processor program. <b>gnome-dom</b>
provides an implementation of the World Wide Web Consortium's Document
Object Model for GNOME applications. By the time you read this
article, gnome-dom will have been deployed widely in the GNOME
office applications. Both gnome-xml and gnome-dom were developed
by Daniel Veillard from the World Wide Web Consortium.
<p>
<b>gnome-print</b> implements GNOME's printing architecture.
It consists of a pluggable rendering engine, as well as a set
of widgets and standard dialog boxes for selecting and configuring
printers. In addition, gnome-print is responsible for managing
outline fonts, and contains scripts that automatically find fonts
already installed on the system.
<p>
The GNOME print imaging model is modeled after PostScript. Basic
operations include vector and bezier path construction, stroking,
filling, clipping, text (using Type1 fonts, with TrueType to follow
shortly) and images.
<p>
At this time, gnome-print generates only PostScript
output. However the design of the imaging model is closely
synchronized with the anti-aliased rendering engine for the Canvas,
and it is expected that these two modules will be interoperating
soon. In particular, it will be possible to ``print'' into a canvas,
useful for providing a high-quality screen preview, and to print the contents
of a canvas. This feature should simplify the design of applications that
use the Canvas, as very little extra code will be needed to support printing.
<p>
The same rendering engine will be used to render printed pages
directly without going through a PostScript step. This path is
especially exciting for providing high-quality, high-performance
printing to color ink-jet printers, even of complex pages
containing transparency, gradients and other elements considered
``tricky'' in the traditional PostScript imaging model.
<p>
<b>Bindings</b>
<p>
One explicit goal of GNOME was to support development in a wide
range of languages, because no single language is ideal for every
application. To this end, bindings for both GTK+ and the GNOME
libraries exist for many popular programming languages, currently C,
C++, Objective-C, Perl, Python, Scheme and Tom.
<p>
The early involvement of Scheme, Tom and Perl hackers in both the GTK+ and
GNOME projects has helped in making the GTK+ and GNOME APIs easy to wrap up for
various different languages. Multi-language support is ``baked in'' to
the design of GTK+ and GNOME, rather than being added on as an
afterthought.
<p>
<h3>Development model</h3>
<p>
GNOME is developed by a loosely coupled team of programmers around
the world. Project coordination is done on the various GNOME mailing
lists.
<p>
The GNOME source code is kept on the GNOME CVS server
(cvs:cvs.gnome.org:/cvs/gnome/). Access to the source code through
Netscape's Bonsai and LXR tools is provided at http://cvs.gnome.org/,
to help programmers get acquainted with the GNOME source code base.
<p>
Most developers who have contributed code, major bug fixes and
documentation to GNOME have CVS write access, fostering a very open
atmosphere. GNOME developers come from a wide range of backgrounds and
have diverse levels of skills and experience. Contributions from less
experienced people have been surprisingly helpful, and the older, wiser
coders have been happy to mentor the younger contributors on the team.
The GNOME developer community values clean, maintainable code.
Even programmers with many years of coding experienced have noted how
the GNOME project has helped them write better code.
<p>
<h3>The GNOME Office Suite Applications</h3>
<p>
As the GNOME foundation libraries become more stable, the
development of larger programming projects has become possible and
has allowed small teams of developers to put together the applications
which will make up the GNOME office suite.
<p>
As with other GNOME components, the GNOME office suite is currently
catching up with commercial offerings. By providing an office
suite which is solid, fast and component-based, the code written for
the GNOME project might become the foundation for a new era of free
software program development.
<p>
The office suite leverages a lot of knowledge many of us have
acquired during the past year while developing various GNOME
components. Our coding standards are higher, the code quality is
better, and the code is more clean and more robust.
<p>
The availability of these applications has provided us with the
test bed we required to complete our document embedding interfaces (the
Baboon model).
<p>
There are two word processing projects going on for GNOME: one of
them is GWP by Seth Alves at the Hungry Programmers and the
other one is Go from Chris Lahey. GWP is currently more advanced and has
printing working with the GNOME printing architecture.
<p>
Gnumeric, the GNOME spreadsheet project, is aimed at providing
a commercial quality spreadsheet with advanced features. It provides a
comfortable and powerful user interface.
As with other components in GNOME, we have worked toward providing a
solid and extensible framework for future development.
<p>
Recently, work has begun on Acthung, the GNOME presentations
program. It is still in the early stages of development.
<p>
<h3>Getting GNOME</h3>
<p>
Tested source code releases of GNOME are available from GNOME's
ftp site: ftp://ftp.gnome.org/.
<p>
It is also possible to get the very latest GNOME developments from
the Anonymous CVS servers. Check the GNOME web page for details on how
to pull the latest version straight from the CVS servers.
<p>
Breaking news about GNOME is posted to the GNOME web site in
http://www.gnome.org/, along with documents to get you started on GNOME
and developing GNOME applications.
<P> <HR> <P>
<h3>Acknowledgments</h3>
<p>
There is no way to thank all of the contributors to the GNOME project
in this space. All of these contributions are gratefully appreciated.
<p>
I would like to especially thank Alan Cox, Nat Friedman, Raph Levien
and Richard Stallman for reviewing the draft of this document.
<P> <HR> <P>
<h3>Resources</h3>
<p>
<b>bonobo</b>: The GNOME team has learned that the Bonobo, the primate
closest to humans, is an endangered species. If you want to know more about how
you can help save the Bonobos, check this web page:
http://www.gsu.edu/~wwwbpf/bpf/
<p>
<b>GIMP</b>: http://www.gimp.org/
<p>
<b>GNU</b>: http://www.gnu.org/
<p>
<b>GTK+</b>: http://www.gtk.org/
<p>
<b>GNOME</b>: http://www.gnome.org/
<p>
<b>Gnumeric</b>: http://www.gnome.org/gnumeric/
<p>
<b>gnome-print</b>: http://www.levien.com/gnome/print-arch.html
<p>
<b>GWP</b>: http://www.hungry.com/products/gwp/
<p>
<b>OMG</b>: http://www.omg.org/
<p>
<b>ORBit</b>: http://www.labs.redhat.com/orbit/
<p>
<b>RHAD</b>: http://www.labs.redhat.com/
<p>
<b>Themes</b>: http://www.labs.redhat.com/themes/
<p>
<b>Tom Tromey</b>: http://www.cygnus.com/~tromey/gnome/metadata.html
<p>
<b>Y</b>: http://www.hungry.com/
<!--===================================================================-->
<P> <hr> <P>
<center><H5>Copyright &copy; 1998, Miguel de Icaza <BR>
Published in Issue 35 of <i>Linux Gazette</i>, December 1998</H5></center>
<!--===================================================================-->
<P> <hr> <P>
<A HREF="./index.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif"
ALT="[ TABLE OF CONTENTS ]"></A>
<A HREF="../index.html"><IMG ALIGN=BOTTOM SRC="../gx/homenew.gif"
ALT="[ FRONT PAGE ]"></A>
<A HREF="./advani.html"><IMG SRC="../gx/back2.gif"
ALT=" Back "></A>
<A HREF="./jao.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
<P> <hr> <P>
<!--startcut ==========================================================-->
</BODY>
</HTML>
<!--endcut ============================================================-->