The XPM Story.


By Daniel Dardailler.
(with input from Colas Nahaboo and Arnaud Le Hors).


The first version of the XPM format and library were designed and developed in January 1989.

The two people involved in this early phase were Colas Nahaboo, who was working on GWM (The Generic Window Manager) at that time, and myself, working on xfedor, an X Window font/icon editor. We were both members of a Groupe Bull Research Center project headed by Vania Joloboff and known as the Koala project (an INRIA/Bull joint located in the INRIA laboratories of Sophia-Antipolis, near Cannes - France).

Colas and I both needed a file format able to store/retrieve colored icons for gwm and xfedor. Unfortunately, Xlib didn't provide anything along these lines besides XBM, which was limited to monochrome icons.

We were very much against binary formats at that time and our primary motivation was to provide a simple Ascii format: something we could edit with emacs and send over email without problems (much like we were doing with PostScript). One afternoon, I went into Colas' office with a BDF-like syntax in mind (xfedor had already a BDF parser in it :-) but Colas quickly persuaded me that to stay in sync with XBM and that using a C includable syntax was a wiser choice (something which really proved to be true over time).

So here is was, the PAX format (for Pixmap in Ascii for X), or XPM1 if you prefer, before it had gotten its real name. As you can see in the following example, the structure was directly derived from the XBM syntax:

 #define foo_format 1	        /* version# of the format, for extensions */
 #define foo_width 6		/* width in pixels */
 #define foo_height 3		/* height in pixels */
 #define foo_ncolors 4		/* number of colors needed */
 #define foo_chars_per_pixel 2	/* number of ascii chars per pixels */
 static  char * foo_colors[] = { /* colormap in symbolic form */
 "  " , "DarkSlateGrey",	 	/*      rgb database color name */
 ". " , "#A8A8A8",		        /* or   RGB value */
 "X " , "White",
 "o " , "#540054005400"  
 } ;
 static char * foo_pixels[] = {  /* the rows of pixels as C strings: */
 "  X X .     ",		 /* foo_height rows of */
 "o o o X X . "			 /* foo_chars_per_pixel * foo_width chars */
 } ;

I went back to my workstation and quickly implemented a very simple library to be used by gwm and xfedor: XReadPaxmapFile() XWritePaxmapFile() XCreatePaxmapFromData(). These routines were really inefficient; they used (and abused) sscanf and XDrawPoint and amounted to less than 500 lines of C code (in comparison, the today XPM 3.4 library is over 6500 lines).

Nothing approaching rocket science in this PAX package, and nothing truly original either (the UIL color icon - among others - was already out at that time) but it was there and it was freely available to anyone (we had put a version on expo.lcs.mit.edu:/contrib). So people started using it, and a month later, in February 89, as we realized the name PAX was already used for something else (an archive format in the PC world), an informal vote was conducted on the xpert newsgroup and we settled on XPM, the X PixMap format (PDF, for Pixmap Distribution Format - ala BDF - was a close second). The API was changed accordingly.

In April 89, Colas and I sent a "X11 Portable Pixmap Files Proposal" to the X Consortium (Bull was a member) and to say the least it was coldly received by Bob Scheifler... Re-reading the proposal today, I do understand the point Bob was making about our proposal not being "real": no rationales, no state of the art study, etc. just a bunch of APIs we wanted to see endorsed. Hey, we were young :-) The other thing was that Bob wasn't sure at that time he could standardize on anything that wasn't 100% related to X, and this was not (it could easily be seen as a general image file format, which standard committees all over the world are still battling over).

The year 1989 went along without any noticeable event and by the end of it, we had users from around the world and the industry: ATT, HP, Sun, ICS, etc. They all were very happy to get for free something that they had needed badly and that the standard Xlib was not providing.

Besides Colas and I, the fall of 89 saw one other individual taking more responsibility into improving the XPM package: Richard Hess, from a company called Consilium in Mountain View. Richard added the first monochrome colortable extension to the XPM1 format.

The beginning of '90 marked the end of my involvment into XPM. I had other plans in mind, among them flying to Cambridge (MA) to foster a young toolkit called Motif... Arnaud Le Hors took both my office and the future of XPM from me and one of his first contribution was to rewrite the library in a much more efficient way.

In February 1990, Colas posted a proposal for an XPM2 version of the format. The main ideas were to get rid of the C syntax and the addition of the visual and symbolic color information in the colortable array.

The symbolic color information is perhaps the most important feature of XPM now, it really characterized XPM as being not specialized in images, which must reproduce some reality, but in "desktop icons", that must convey more abstract information. This, combined with the extreme customizability of X applications means that an element of an icon can be painted in colors conveying a meaning that is dependent of the context, i.e. the color set of the application. For instance, if the user has decided that all the text fields are dark blue on beige, with lightblue and black shadow visuals, so should the icons in this particular dialog box. Surprisingly, we knew of no image format supporting such a feature.

In August 90, Arnaud and Colas released an XPM2 library using a multi-language (C/Lisp and Natural) syntax and the color customization mechanism. It has been agreed upon today that the multi-language approach was a mistake, as it induced some noticeable parsing overhead for a rather minial return (there are almost no non-C users of X :-).

The XPM2 format didn't last very long and in April 91, after the first XPM BOF was conducted at the X Conference in Boston, XPM3 was introduced as the C subset of the XPM2 multi syntax:

/* XPM */
static char * roundb_xpm[] = {
/* width height ncolors cpp [x_hot y_hot] */
"13 13 5 2 7 7",
/* colors */
"  s none	m none	c none",
". s topShadowColor m white c lightblue",
"X s iconColor1 m black c black",
"o s bottomShadowColor m black c #646464646464",
"O s selectColor m white c red",
/* pixels */
"                          ",
"          . . .           ",
"      . . X X X o o       ",
"    . X X X X X X X o     ",
"    . X X X X X X X o     ",
"  . X X X X O X X X X o   ",
"  . X X X O O O X X X o   ",
"  . X X X X O X X X X o   ",
"    . X X X X X X X o     ",
"    . X X X X X X X o     ",
"      o o X X X o o       ",
"          o o o           ",
"                          "
}; 

At about that time too, the xpm-talk mailing was started, to drive the evolution of the format and library, with Arnaud acting as the architect/coordinator. The changes/improvements over the last 2 or 3 years have included some major API changes (Xpm prefix, XpmAttributes, etc), hot-spot and transparent pixels support (for cursor and mask capabilities) and, as always, more of Arnaud's industrialization and bug fixing solidification.

Today, XPM is still in its third format revision and given the recent endorsement of XPM3 by the COSE/CDE group and by Motif 2.0, it is safe to say that it will probably remain at 3 for a while.

What about an X Consortium standard do you ask ? Well, now that XPM is the industry de-facto standard, what it would take to have it endorsed by the X Consortium is mainly one person's cycles to drive the review to completion. Unfortunately, that hasn't been budgeted by anybody so far... So we'll probably still have to live with a contrib Xpm for a while.