[alt.sources] [xpert] XPM2 The new XPM version

lehors@modja.inria.fr (Arnaud Le Hors) (08/26/90)

Archive-name: xpm2/25-Aug-90
Original-posting-by: lehors@modja.inria.fr (Arnaud Le Hors)
Original-subject: XPM2 The new XPM version (source files).
Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)

[Reposted from comp.windows.x.
Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]

Here goes the first  distribution of the new version of XPM.

XPM (X PixMap) is a format for storing/retrieving X pixmaps to/from ascii 
files. 

Here is provided a library containing a set of three functions, similar to the
X bitmap functions as defined in the Xlib: XCreatePixmapFromData,
XReadPixmapFile and XWritePixmapFile for respectively including, reading and
writing this format.

This new version provides different types of format: a natural one which will
be preferably used for manual editing (with emacs, vi, ...), a C includable
format and a Lisp includable format. It provides defaults for different types
of display: monochrome/color/grayscale, and symbol names for colors for
overriding default colors when creating the pixmap. Finally it provides a
structure for storing information while reading a file which is re-used while
writing. This way comments, default colors and symbol names aren't lost.

Follows the shar file containing all the source files needed for building the 
XPM2 library, the manual (xpm.tex file), and a demo.

I hope this will be useful to you. Please let me know your feelings.

--
   Arnaud LE HORS
   BULL Research FRANCE -- Koala Project   |    Email : lehors@mirsa.inria.fr
         Inria - Sophia Antipolis          |    Phone : (33) 93 65 77 71
         2004, Route des Lucioles          |    Telex :      97 00 50 F
         06565 Valbonne CEDEX  France      |    Fax   : (33) 93 65 77 66

--
#!/bin/sh
# This is a shell archive. To unpack its contents, do "sh <this-file>"
cat > COPYRIGHT << \END_OF_SHAR_FOR_COPYRIGHT
/*
 * Copyright 1990 GROUPE BULL
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted, provided
 * that the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of GROUPE BULL not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission.  GROUPE BULL makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * GROUPE BULL disclaims all warranties with regard to this software,
 * including all implied warranties of merchantability and fitness,
 * in no event shall GROUPE BULL be liable for any special,
 * indirect or consequential damages or any damages
 * whatsoever resulting from loss of use, data or profits,
 * whether in an action of contract, negligence or other tortious
 * action, arising out of or in connection with the use 
 * or performance of this software.
 *
 */

Arnaud LE HORS      BULL Research FRANCE -- Koala Project 
                    (XPM2 - X PixMap format version 2)
    Internet:       lehors@mirsa.inria.fr
Surface Mail:       Arnaud LE HORS, INRIA - Sophia Antipolis, 
                    2004, route des Lucioles, 06565 Valbonne Cedex -- FRANCE
 Voice phone:       (33) 93.65.77.71, Fax: (33) 93 65 77 66, Telex: 97 00 50 F
END_OF_SHAR_FOR_COPYRIGHT
cat > Makefile << \END_OF_SHAR_FOR_Makefile
# Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT
#
# XPM Makefile - Arnaud LE HORS
# $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
#

AR = ar r
CC = cc
RANLIB = ranlib
RM = rm -f

CFLAGS=

LIBDIRS= -L/usr/lib/X11 -L.
LIBS= -lXPM2 -lX11
OBJS= mio.o value.o create.o visual.o free.o XWrPixF.o XRdPixF.o XCrPFData.o

all: demo

clean: 
	$(RM) *.o demo libXPM2.a

demo: libXPM2.a demo.o
	$(CC) $(CFLAGS) demo.o $(LIBDIRS) $(LIBS) -o demo

libXPM2.a: $(OBJS)
	$(AR) libXPM2.a $(OBJS)
	$(RANLIB) libXPM2.a
END_OF_SHAR_FOR_Makefile
cat > README << \END_OF_SHAR_FOR_README
$Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $

				XPM Version 2

WHAT IS XPM?
============

XPM (X PixMap) is a format for storing/retrieving X pixmaps to/from ascii
files.

Here is provided a library containing a set of three functions, similar to the
X bitmap functions as defined in the Xlib: XCreatePixmapFromData,
XReadPixmapFile and XWritePixmapFile for respectively including, reading and
writing this format.

This new version provides different types of format: a natural one which will
be preferably used for manual editing (with emacs, vi, ...), a C includable
format and a Lisp includable format. It provides defaults for different types
of display: monochrome/color/grayscale, and symbol names for colors for
overriding default colors when creating the pixmap. Finally it provides a
structure for storing information while reading a file which is re-used while
writing. This way comments, default colors and symbol names aren't lost.

See the XPM Manual for more details.

INSTALLATION:
============

To obtain the XPM library, first execute the shell archive file in an
approriate directory. Then just do:

		      make all 
	   or	      make libxpm.a

NOTE:   if you compile  with gcc, use "gcc -traditional", otherwise you will
        have compilation warnings (but the code will work Ok)

DEMO:
====

In addition to the library a demo is provided. If you have previously done 
'make all' you should have it yet, otherwise just do:

		      make demo

This demo shows you all the features of XPM and the three provided functions.

By executing 'demo' without any option you will see a demo of the 
XCreatePixmapFromData function. The pixmap is created from the static variable
plaid defined in the demo.c file. Demo will end when you click in the created
window.

Executing 'demo -s lines_in_mix blue' will show the feature of color symbols.

Then you should try 'demo -o output' to get an output file using the
XWritePixmapFile function. This is a natural type format file, other types can
be obtained by adding the option '-t C' or '-t Lisp'.

To end you should try 'demo -i plaid' or 'demo -i plaid_c' or 
'demo -i plaid_ll' to use the XReadPixmapFile function.

Of course, other combinations are allowed and should be tried. Thus, 
'demo -i plaid -o output -t C' will show you how a natural type format is
translated to a C type format.

The XCreatePixmapFromData function is on purpose called without any Xpminfo 
pointer to show the utility of this one. Indeed, compare the color section of
the two files foo and bar obtained from 'demo -o foo' and 
'demo -i plaid -o bar'.

KNOWN BUG:
=========

XWritePixmapFile:
Writing out multilines comment to a single line comment is not handled. Thus,
translating a C multilines comment to Lisp will result to an invalid file.

DISCUSSION:
==========

Any discussion should be made on the comp.windows.x newsgroup. The subject
line will preferably begin by the word XPM.

COPYRIGHT:
==========

  Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT
  See the COPYRIGHT file in the XPM distribution

Please mail any bug reports or modifications done, comments, suggestions,
requests for updates or patches to port on another machine to:

lehors@mirsa.inria.fr		(INTERNET)

33 (FRANCE) 93.65.77.71		(VOICE PHONE)

Arnaud Le Hors			(SURFACE MAIL)
INRIA
2004, Route des lucioles
Sophia Antipolis
06565 VALBONNE
FRANCE
END_OF_SHAR_FOR_README
cat > XCrPFData.c << \END_OF_SHAR_FOR_XCrPFData.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* XCrPFData.c:
 *
 *  XPM2
 *  Create from Data utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"

int XCreatePixmapFromData(display, visual, d, colormap, data, depth,
			  pixmap_return, width_return, height_return, 
			  pixels_return, npixels_return,
			  colorsymbols, numsymbols, infos)
     Display *display;
     Visual *visual;
     Drawable d;
     Colormap colormap;
     char **data;
     unsigned int depth;
     Pixmap *pixmap_return;
     unsigned int *width_return, *height_return, *npixels_return;
     Pixel **pixels_return;
     ColorSymbol colorsymbols[];
     unsigned int numsymbols;
     XpmInfo *infos;

{ MData *mdata;

  *width_return = *height_return = 0;
  if (! (mdata = (MData *)malloc(sizeof(MData)))) { 
      XpmErrorStatus = PixmapNoMemory;
      return(NULL);
  }
  mdata->type = MARRAY;
  mdata->stream = (void*) data;
  mdata->cptr = *data;
  mdata->line = 0;
  XpmErrorStatus = PixmapSuccess;
  *pixmap_return = CreatePixmap(display, visual, d, colormap, mdata, depth,
				width_return, height_return, 
				pixels_return, npixels_return,
				colorsymbols, numsymbols, infos);
  free(mdata);
  return(XpmErrorStatus);
}
END_OF_SHAR_FOR_XCrPFData.c
cat > XRdPixF.c << \END_OF_SHAR_FOR_XRdPixF.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* XRdPixF.c:
 *
 *  XPM2
 *  Read utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"

int XReadPixmapFile(display, visual, d, colormap, filename, depth, 
		    pixmap_return, width_return, height_return, 
		    pixels_return, npixels_return,
		    colorsymbols, numsymbols, infos)
     Display *display;
     Visual *visual;
     Drawable d;
     Colormap colormap;
     char *filename;
     unsigned int depth;
     Pixmap *pixmap_return;
     unsigned int *width_return, *height_return, *npixels_return;
     Pixel **pixels_return;
     ColorSymbol colorsymbols[];
     unsigned int numsymbols;
     XpmInfo *infos;

{ MData *mdata;
  char buf[BUFSIZ];
  int l, n = 0;

  *pixmap_return = NULL;
  *width_return = *height_return = 0;
  XpmErrorStatus = PixmapSuccess;

  if (! (mdata = (MData *)malloc(sizeof(MData)))) {
      return(XpmErrorStatus = PixmapNoMemory);
  }
  mdata->type = MFILE;
  if (! (mdata->stream = (void*) fopen(filename, "r"))) {
      free(mdata);
      return(XpmErrorStatus = PixmapOpenFailed);
  }
  mdata->cptr = NULL;
  mdata->line = 0;

  /* parse the header file
   */
  BOS = '\0';
  EOS = '\n';
  BCMT = ECMT = NULL;
  l = mnextw(mdata, buf);	/* skip the first word */
  l = mnextw(mdata, buf);	/* then get the second word */
  if (l == 4 && !strncmp("XPM2", buf, 4)) {
      l = mnextw(mdata, buf);	/* get the type key word */
 
     /* get infos about this type
       */
      while (DataTypes[n].type && strncmp(DataTypes[n].type, buf, l)) n++;
      if (DataTypes[n].type) {
	  if (infos) {
	      infos->type = (char *) malloc(l+1);
	      strncpy(infos->type, buf, l);
	      infos->type[l] = '\0';
	  }
	  if (n == 0) {		/* natural type */
	      BCMT = DataTypes[n].Bcmt;
	      ECMT = DataTypes[n].Ecmt;
	      mnextstring(mdata);	/* skip the end of headerline */
	      BOS = DataTypes[n].Bos;
	  } else {
	      mnextstring(mdata);	/* skip the end of headerline */
	      BCMT = DataTypes[n].Bcmt;
	      ECMT = DataTypes[n].Ecmt;
	      BOS = DataTypes[n].Bos;
	      mnextstring(mdata);	/* skip the assignment line */
	  }
	  EOS = DataTypes[n].Eos;

	  *pixmap_return = CreatePixmap(display, visual, d, colormap, mdata,
					depth, width_return, height_return,
					pixels_return, npixels_return,
					colorsymbols, numsymbols, infos);
      } else {
	  XpmErrorStatus = PixmapFileInvalid;
      }
  } else {
      XpmErrorStatus = PixmapFileInvalid;
  }
  fclose((FILE *) mdata->stream);
  free(mdata);
  return(XpmErrorStatus);
}
END_OF_SHAR_FOR_XRdPixF.c
cat > XWrPixF.c << \END_OF_SHAR_FOR_XWrPixF.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/*
 *  XPM2
 *  Write utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"
#include <strings.h>

#undef RETURN
#define RETURN(status) \
  { if (index) free(index); \
    if (colorStrings) { \
	for (a = 0; a < ncolors; a++) \
	    if (*(colorStrings + a)) \
		free(*(colorStrings + a)); \
	free(colorStrings); \
    } \
    fclose(stream); \
    return(XpmErrorStatus = status); }

int XWritePixmapFile(display, colormap, filename, pixmap, width, 
		     height, type, cppm, infos)
     Display *display;
     Colormap colormap;
     char *filename;
     Pixmap *pixmap;
     unsigned int width, height;
     char *type;
     unsigned int cppm;
     XpmInfo *infos;

{ FILE *stream;
  XImage *ximage = NULL;
  unsigned int pixlen;		/* length of pixels */
  unsigned int pixgap;		/* length of pixels gap */
  byte *dptr;
  Pixel *index = NULL;		/* index of different pixels */
  unsigned int indexsize = 256;	/* should be enough most of the time */
  XColor *xcolors;		/* used colors */
  char **colorStrings = NULL;	/* character strings associated to colors */
  unsigned int ncolors = 0;	/* number of colors */
  unsigned int cpp;             /* chars per pixel */
  char *name;
  unsigned int a, b, c, x, y, n = 0, key;
  Pixel pixel;

  if (! (stream = fopen(filename, "w"))) {
      return(XpmErrorStatus = PixmapOpenFailed);
  }
  XpmErrorStatus = PixmapSuccess;

  if (!(name = rindex(filename, '/')))
    name = filename;
  else
    name++;

  if (!type)
      if (infos && infos->type)
	  type = infos->type;
      else
	  n = 0;		/* natural type */
  if (n == 0 && type) {
      while (DataTypes[n].type && strcmp(DataTypes[n].type, type)) n++;
      if (! DataTypes[n].type)
	  return(XpmErrorStatus = PixmapFileInvalid);
  }


  /*
   * read the image data
   */

  ximage = XGetImage(display, pixmap, 0, 0, width, height, AllPlanes,
ZPixmap);
  pixlen = (ximage->bits_per_pixel / 8) + (ximage->bits_per_pixel % 8 ? 1 :
0);
  pixgap = ximage->bytes_per_line - width;

  /* index the different pixels
   */
  if (! (index = (Pixel *)malloc(sizeof(Pixel) * indexsize)))
      return(XpmErrorStatus = PixmapNoMemory);
  dptr = (byte *)ximage->data;
  for (y = 0; y < height; y++) {
      for (x = 0; x < width; x++) {
	  pixel = memToVal(dptr, pixlen);
	  for (a = 0; a < ncolors; a++)
	      if (*(index + a) == pixel) break;
	  if (a == ncolors) {
	      if (ncolors > indexsize) {
		  indexsize *= 2;
		  if (! (index = (Pixel *)malloc(sizeof(Pixel) * indexsize)))
		      RETURN(PixmapNoMemory);
	      }
	      *(index + ncolors) = pixel;
	      ncolors++;
	  }
	  valToMem((unsigned long)a, dptr, pixlen);
	  dptr += pixlen;
      }
      for (b = 0; b < pixgap; b++) dptr += pixlen; /* skip extra pixels */
  }

  /* get rgb values and a string of char for each color
   */
  if (! (xcolors = (XColor *) malloc(sizeof(XColor) * ncolors)))
      RETURN(PixmapNoMemory);
  if (! (colorStrings = (char **) calloc(ncolors, sizeof(char *))))
      RETURN(PixmapNoMemory);

  for (cpp = 1, c = MAXPRINTABLE; ncolors > c; cpp++) c *= MAXPRINTABLE;
  if (cpp < cppm) cpp = cppm;

  for (a = 0; a < ncolors; a++) {
      if (! (*(colorStrings + a) = (char *)malloc(cpp)))
	  RETURN(PixmapNoMemory);
      **(colorStrings + a) = printable[c = a % MAXPRINTABLE];
      for (b = 1; b < cpp; b++)
	  *(*(colorStrings + a) + b) = 
	      printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
      (xcolors + a)->pixel = *(index + a);
  }
  XQueryColors(display, colormap, xcolors, ncolors);


  /*
   * print the pixmap file
   */

  /* print the header line 
   */
  fprintf(stream, "%s XPM2 %s %s", DataTypes[n].Bcmt, DataTypes[n].type, 
	  DataTypes[n].Ecmt);
  if (n != 0)			/* print the assignment line */
      fprintf(stream, "%s %s %s", DataTypes[n].Dec, name, 
	      DataTypes[n].Boa);

  /* print the hints 
   */
  if (infos && infos->hints_cmt) /* print hints comment line */
      fprintf(stream, "%s%s%s", DataTypes[n].Bcmt, 
	      infos->hints_cmt, DataTypes[n].Ecmt);

  if (DataTypes[n].Bos) fprintf(stream, "%c", DataTypes[n].Bos);
  fprintf(stream, "%d %d %d %d", width, height, ncolors, cpp);
  if (DataTypes[n].Eos) fprintf(stream, "%c", DataTypes[n].Eos);
  fprintf(stream, DataTypes[n].Strs);

  /* print colors 
   */
  if (infos && infos->colors_cmt) /* print colors comment line */
      fprintf(stream, "%s%s%s", DataTypes[n].Bcmt, 
	      infos->colors_cmt, DataTypes[n].Ecmt);

  for (a = 0; a < ncolors; a++) {
      if (DataTypes[n].Bos) fprintf(stream, "%c", DataTypes[n].Bos);
      for (b = 0; b < cpp; b++)
	  fprintf(stream, "%c", *(*(colorStrings + a) + b));
      c = 1;
      if (infos && infos->pixels) {
	  for (b = 0; b < infos->ncolors; b++)
	      if (*(infos->pixels + b) == (xcolors + a)->pixel)
		  break;
	  if (b != infos->ncolors) {
	      c = 0;
	      for (key = 1; key < NKEYS + 1; key++) {
		  if (*(*(infos->colorTable + b) + key))
		      fprintf(stream, "  %s %s", ColorKeys[key - 1], 
			      *(*(infos->colorTable + b) + key));
	      }
	  }
      }
      if (c)
	      fprintf(stream, " c #%04X%04X%04X", (xcolors + a)->red, 
		      (xcolors + a)->green, (xcolors + a)->blue);
      if (DataTypes[n].Eos) fprintf(stream, "%c", DataTypes[n].Eos);
      fprintf(stream, DataTypes[n].Strs);
  }

  /* print pixels
   */
  if (infos && infos->pixels_cmt) /* print pixels comment line */
      fprintf(stream,  "%s%s%s", DataTypes[n].Bcmt, 
	      infos->pixels_cmt, DataTypes[n].Ecmt);

  dptr = (byte *)ximage->data;
  for (y = 0; y < height; y++) {
      if (DataTypes[n].Bos) fprintf(stream, "%c", DataTypes[n].Bos);
      for (x = 0; x < width; x++) {
	  for (b = 0; b < cpp; b++) {
	      fprintf(stream, "%c", 
		      *(*(colorStrings + memToVal(dptr, pixlen)) + b));
	  }
	  dptr += pixlen;
      }
      if (DataTypes[n].Eos) fprintf(stream, "%c", DataTypes[n].Eos);
      if (y < height - 1) 
	  fprintf(stream, DataTypes[n].Strs);
      for (c = 0; c < pixgap; c++) dptr += pixlen; /* skip extra pixels */
  }
  fprintf(stream, DataTypes[n].Eoa);

  fclose(stream);
  free(index);
  for (a = 0; a < ncolors; a++)
      free(*(colorStrings + a));
  free(colorStrings);
  free(xcolors);
  return(XpmErrorStatus);
}
END_OF_SHAR_FOR_XWrPixF.c
cat > colas.sty << \END_OF_SHAR_FOR_colas.sty
% my add-on LaTeX macros
% to be used like in:
% \documentstyle[12pt,gwm]{report}

% postscript inclusion:
\def\texpsfig#1#2#3
{\vbox{\kern #3pt\hbox{\special{psfile=#1}\kern #2pt}}\typeout{(#1)}}

% RCS version stripping
\def\RCSRevNum#1Revision: #2 ${#2}
\def\RCSRevVersion#1Version: #2 ${#2}

\newlength{\colaslength}
\newlength{\colaslengthh}
\newlength{\colasmargin}

\def\exemplefont{\footnotesize}
\def\usagefont{\large}
\def\usageupspace{\vspace{0.1mm}}
\newcommand{\Description}
	{\list{}{\leftmargin 4cm \labelsep 0.1cm \labelwidth 3.9cm}}

\def\descriptionlabel#1{\bf #1\hspace\labelsep\hfil}
\def\description
	{\list{}{\leftmargin 2.4cm \labelsep 0.1cm \labelwidth 2.3cm
	\let\makelabel\descriptionlabel}}

\def\upspace{\vspace{-2mm}}
\def\undertablespace{\vspace{-3mm}}

\def\Item#1#2{\upspace\pagebreak[1]\section*{\hspace{-7pt}
	{\large\tt#1}{\normalsize\sf\quad ---\quad #2}}\vspace{-0.3cm}}

\def\ITEMa#1#2{
 \Item{#1}{#2}\markright{#1}
 \label{#1}}
\def\ITEMb#1#2#3{
 \Item{\vbox{\hbox{#1}\hbox{#2}}}{#3}\markright{#1}
 \label{#1} \label{#2}}
\def\ITEMbi#1#2#3{
 \Item{\vbox{\hbox{#1}\hbox{#2}}}{#3}\markright{#1}
 \label{#2}}
\def\ITEMc#1#2#3#4{
 \Item{\vbox{\hbox{#1}\hbox{#2}\hbox{#3}}}{#4}\markright{#1}
 \label{#1}\label{#2} \label{#3}}
\def\ITEMci#1#2#3#4{
 \Item{\vbox{\hbox{#1}\hbox{#2}\hbox{#3}}}{#4}\markright{#1}
 \label{#2}\label{#3}}
\def\ITEMd#1#2#3#4#5{
 \Item{\vbox{\hbox{#1}\hbox{#2}\hbox{#3}\hbox{#4}}}{#5}\markright{#1}
 \label{#1}\label{#2}\label{#3}\label{#4}}
\def\ITEMe#1#2#3#4#5#6{
 \Item{
  \vbox{\hbox{#1}\hbox{#2}\hbox{#3}\hbox{#4}\hbox{#5}}}{#6}\markright{#1}
 \label{#1}\label{#2}\label{#3}\label{#4}\label{#5}}
\def\ITEMf#1#2#3#4#5#6#7{
 \Item{
    \vbox{\hbox{#1}\hbox{#2}\hbox{#3}\hbox{#4}\hbox{#5}\hbox{#6}}}{#7}
	\markright{#1}
 \label{#1}\label{#2}\label{#3}\label{#4}\label{#5}\label{#6}}

\newcommand{\context}[1]{
  Context used:
    \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{7cm}}
    \multicolumn{1}{c}{\bf Variable}&\multicolumn{1}{c}{\bf used for}\\ 
    \hline \multicolumn{2}{l}{\undertablespace}\\
    #1
    \end{tabular}\end{center}}

\newcommand{\contextdim}[2]{
  \setlength{\colaslength}{7cm}
  \addtolength{\colaslength}{#1}
  Context used:
    \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{\colaslength}}
    \multicolumn{1}{c}{\bf Variable}&\multicolumn{1}{c}{\bf used for}\\ 
    \hline  \multicolumn{2}{l}{\undertablespace}\\
    #2
    \end{tabular}\end{center}}

\newcommand{\desctable}[3]{
    \begin{center}\begin{tabular}{@{\bf}l@{\hspace{1cm}}@{\rm}p{7cm}}
    \multicolumn{1}{c}{\bf #1}&\multicolumn{1}{c}{\bf #2}\\ 
    \hline \multicolumn{2}{l}{\undertablespace}\\
    #3
    \end{tabular}\end{center}}

\newcommand{\desctabledim}[4]{
  \setlength{\colaslength}{7cm}
  \addtolength{\colaslength}{#1}
    \begin{center}\begin{tabular}{@{\bf}l@{\hspace{1cm}}@{\rm}p{\colaslength}}
    \multicolumn{1}{c}{\bf #2}&\multicolumn{1}{c}{\bf #3}\\ 
    \hline  \multicolumn{2}{l}{\undertablespace}\\
    #4
    \end{tabular}\end{center}}

\newcommand{\exemples}[2]{
  #1{\exemplefont 
    \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{5cm}}
    #2
    \end{tabular}\end{center}}}

\newcommand{\exemplesdim}[3]{
  \setlength{\colaslength}{5cm}
  \addtolength{\colaslength}{#1}
  #2{\exemplefont 
    \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{\colaslength}}
    #3
    \end{tabular}\end{center}}}

\newcommand{\usagetype}[1]{{\sl #1}\vspace{0.2cm}}
\newcommand{\usagetyped}[2]{{\sl #1}\quad{\it (#2)}\vspace{0.2cm}}
\newcommand{\see}[1]{{\tt #1}}
\newcommand{\seep}[1]{{\tt #1}, p~\pageref{#1}}
\newcommand{\seensp}[1]{{\tt #1} (see p~\pageref{#1})}
\newcommand{\seesnp}[1]{(see {\tt #1}, p~\pageref{#1})}
\newcommand{\seeref}[1]{{\tt #1} (see \ref{#1}, p~\pageref{#1})}
\newcommand{\seesp}[1]{(see \ref{#1}, p~\pageref{#1})}

\def\smalldesc#1#2#3{#1&#3&#2\\}
\newcommand{\bigdesc}[2]{
  \setlength{\colaslength}{300pt}
  \settowidth{\colaslengthh}{{\tt #1}}
  \addtolength{\colaslength}{-\colaslengthh}
    \begin{center}\begin{tabular}
	{@{\tt}l@{\hspace{0.5cm}}@{\sf}p{\colaslength}@{\hspace{0.4cm}}@{\bf}r}
   \multicolumn{1}{c}{\bf Object}&\multicolumn{1}{c}{\bf Description}&{\bf
p}\\
    \hline \multicolumn{3}{l}{\undertablespace}\\
    #2
    \end{tabular}\end{center}}

\newcommand{\desc}[4]{
  \setlength{\colaslength}{250pt}
  \settowidth{\colaslengthh}{{\tt #1}}
  \addtolength{\colaslength}{-\colaslengthh}
    \begin{center}\begin{tabular}
{@{\tt}l@{\hspace{0.5cm}}@{\sf}p{\colaslength}}
    \multicolumn{1}{c}{\bf #2}&\multicolumn{1}{c}{\bf #3}\\
    \hline \multicolumn{2}{l}{\undertablespace}\\
    #4
    \end{tabular}\end{center}}

\newcommand{\contextdimtt}[2]{
  \setlength{\colaslength}{250pt}
  \settowidth{\colaslengthh}{{\tt #1}}
  \addtolength{\colaslength}{-\colaslengthh}
  Context used:
    \begin{center}\begin{tabular}{@{\tt}l@{\hspace{1cm}}@{\rm}p{\colaslength}}
    \multicolumn{1}{c}{\bf Variable}&\multicolumn{1}{c}{\bf used for}\\ 
    \hline \multicolumn{2}{l}{\undertablespace}\\
    #2
    \end{tabular}\end{center}}

\def\itemtt#1{\item[{\tt #1}]}
\def\itemit#1{\item[{\it #1}]}


% SIZE of page
%=============

\def\fullpage{\if@twoside \oddsidemargin 35pt \evensidemargin -8pt 
\marginparsep 10pt \marginparpush 10pt \marginparwidth 10pt
\else \oddsidemargin 0pt \evensidemargin 0pt 
\marginparwidth 30pt\fi
\textwidth 450pt \setlength{\colasmargin}{0pt}
\def\colaspm{\hspace{0pt}}\def\colasmm{\hspace{0pt}}
\def\colassmm{\hspace{0pt}}\def\colastitledisp{\hspace{0pt}}
}
\def\mediumpage{\if@twoside \oddsidemargin 75pt \evensidemargin 32pt 
\marginparsep 10pt \marginparpush 10pt \marginparwidth 40pt
\else \oddsidemargin 43pt \evensidemargin 63pt 
\marginparwidth 30pt\fi
\textwidth 410pt \setlength{\colasmargin}{0pt}
\def\colaspm{\hspace{40pt}}\def\colasmm{\hspace{-40pt}}
\def\colassmm{\hspace{-20pt}}\def\colastitledisp{\hspace{-45pt}}
}
\def\smallpage{\if@twoside \oddsidemargin 135pt \evensidemargin 92pt 
\marginparsep 10pt \marginparpush 10pt \marginparwidth 80pt
\else \oddsidemargin 123pt \evensidemargin 123pt
\marginparwidth 30pt \fi
\textwidth 350pt 
\setlength{\colasmargin}{100pt}
\def\colaspm{\hspace{100pt}}\def\colasmm{\hspace{-100pt}}
\def\colassmm{\hspace{-60pt}}\def\colastitledisp{\hspace{-75pt}}
}

\smallpage
\topmargin -30pt \headheight 12pt \headsep 25pt \footheight 12pt \footskip
30pt 
\textheight 680pt \columnsep 10pt \columnseprule 0pt 
\footnotesep 12pt \skip\footins 6pt plus 2pt minus 2pt 
\floatsep 12pt plus 2pt minus 2pt \textfloatsep 20pt plus 2pt minus 4pt
\intextsep 12pt plus 2pt minus 2pt \@maxsep 20pt \dblfloatsep 12pt plus 2pt
minus 2pt \dbltextfloatsep 20pt plus 2pt minus 4pt \@dblmaxsep 20pt 
\@fptop 0pt plus 1fil \@fpsep 8pt plus 2fil \@fpbot 0pt plus 1fil 
\@dblfptop 0pt plus 1fil \@dblfpsep 8pt plus 2fil \@dblfpbot 0pt plus 1fil

\parskip 5pt plus 1pt \parindent 0pt \topsep 2pt plus 1pt minus 1pt
\partopsep 0pt plus 1pt minus 1pt \itemsep 2pt plus 1pt minus 1pt 

\reversemarginpar
\@mparswitchfalse

%% abbrevs

\def\GWM{\sc Gwm}
\def\WOOL{\sc Wool}

%% fonts
\def\Huge{\@setsize\Huge{30pt}\xxvpt\@xxvpt}

%% chapter

\def\@makechapterhead#1{ \vspace*{1pt} { \parindent 0pt \raggedright 
 \Huge\bf \colasmm
 \ifnum \c@secnumdepth >\m@ne \thechapter \quad \fi
 #1\par 
 \nobreak \vskip 20pt
 \colasmm{\vbox{\hbox{\vrule height 5pt width450pt depth -3pt}
 			\vspace*{-1.1cm}
 		       \hbox{\vrule height 0.0pt width450pt depth 0.4pt}}}
 \nobreak \vskip 50pt \nobreak } }

\def\@makeschapterhead#1{ \vspace*{1pt} { \parindent 0pt \raggedright 
 \Huge \bf \colasmm #1\par 
 \nobreak \vskip 80pt } }

\def\chapter{\clearpage \thispagestyle{pagenum} \global\@topnum\z@
\@afterindentfalse \secdef\@chapter\@schapter} 
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
 \refstepcounter{chapter}
 \typeout{\@chapapp\space\thechapter.}
 \addcontentsline{toc}{chapter}{\protect
 \numberline{\thechapter}#1}\else
 \addcontentsline{toc}{chapter}{#1}\fi
 \chaptermark{#1}
 \addtocontents{lof}{\protect\addvspace{10pt}}
\addtocontents{lot}{\protect\addvspace{10pt}} \if@twocolumn
\@topnewpage[\@makechapterhead{#2}] 
 \else \@makechapterhead{#2}
 \@afterheading \fi} 
\def\@schapter#1{\if@twocolumn \@topnewpage[\@makeschapterhead{#1}]
 \else \@makeschapterhead{#1} 
 \@afterheading\fi}

%% sections

\def\section{\@startsection {section}{1}{\z@}{-3.5ex plus -1ex minus 
 -.2ex}{2.3ex plus .2ex}{\Large\bf\colasmm}}
\def\subsection{\@startsection{subsection}{2}{\z@}{-3.25ex plus -1ex minus 
 -.2ex}{1.5ex plus .2ex}{\large\bf\colassmm}}
\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-3.25ex plus
-1ex minus -.2ex}{1.5ex plus .2ex}{\normalsize\bf}}
\def\paragraph{\@startsection
 {paragraph}{4}{\z@}{3.25ex plus 1ex minus .2ex}{-1em}{\normalsize\bf}}
\def\subparagraph{\@startsection
 {subparagraph}{4}{\parindent}{3.25ex plus 1ex minus 
 .2ex}{-1em}{\normalsize\bf}}

%% headings

\if@twoside \def\ps@headings{\def\@oddfoot{}
\def\@evenfoot{}\def\@evenhead{
\colasmm\makebox[0pt][l]{\vrule height-4pt width450pt depth4.3pt}
\bf\thepage\hfill \sl \leftmark}
\def\@oddhead{
\colasmm\makebox[0pt][l]{\vrule height-4pt width450pt depth4.3pt}
\sl \rightmark \hfill\bf\thepage}
\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth
>\m@ne
 \@chapapp\ \thechapter. \ \fi ##1}}{}}\def\sectionmark##1{\markright
{\uppercase{\ifnum \c@secnumdepth >\z@
 \thesection. \ \fi ##1}}}}
\else \def\ps@headings{\def\@oddfoot{}\def\@evenfoot{}\def\@oddhead{\hbox
{}\sl \rightmark \hfill \rm\thepage}\def\chaptermark##1{\markright
{\uppercase{\ifnum \c@secnumdepth >\m@ne
 \@chapapp\ \thechapter. \ \fi ##1}}}}
\fi

\if@twoside \def\ps@pagenum{\def\@oddfoot{}
\def\@evenfoot{}\def\@evenhead{
\colasmm\bf\thepage\hfill}
\def\@oddhead{
\colasmm\hfill\bf\thepage}
\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth
>\m@ne
 \@chapapp\ \thechapter. \ \fi ##1}}{}}\def\sectionmark##1{\markright
{\uppercase{\ifnum \c@secnumdepth >\z@
 \thesection. \ \fi ##1}}}}
\else \def\ps@pagenum{\def\@oddfoot{}\def\@evenfoot{}\def\@oddhead{\hbox
{}\hfil \bf\thepage}\def\chaptermark##1{\markright
{\uppercase{\ifnum \c@secnumdepth >\m@ne
 \@chapapp\ \thechapter. \ \fi ##1}}}}
\fi

END_OF_SHAR_FOR_colas.sty
cat > create.c << \END_OF_SHAR_FOR_create.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* create.c:
 *
 *  XPM2
 *  Create utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"

#define RETURN(status) \
  { freeColorTable(colorTable, ncolors); \
    XpmErrorStatus = status; \
    return(NULL); }

Pixmap CreatePixmap(display, visual, d, colormap, data, depth, 
		    width_return, height_return, 
		    pixels_return, npixels_return,
		    colorsymbols, numsymbols, infos)
     Display *display;
     Visual *visual;
     Drawable d;
     Colormap colormap;
     MData *data;
     unsigned int depth;
     unsigned int *width_return, *height_return, *npixels_return;
     Pixel **pixels_return;
     ColorSymbol colorsymbols[];
     unsigned int numsymbols;
     XpmInfo *infos;

{ Pixmap       pixmap;
  unsigned int cpp;             /* chars per pixel */
  unsigned int ncolors;         /* number of colors */
  char       ***colorTable;     /* color table */
  unsigned int key;		/* color key */
  unsigned int pixlen;		/* length of pixels */
  Pixel        *pixels;		/* pixels colors */
  unsigned int width, height;
  char         *chars, buf[BUFSIZ], *colorname;
  byte         *dptr, *bptr;
  XColor       xcolor;
  XGCValues    gcv;
  GC           gc;
  XImage       *ximage;
  unsigned int a, b, x, y, l = 0;

  /* Initialize return values
   */
  *width_return = *height_return = *npixels_return = 0;
  *pixels_return = NULL;

  /*
   * parse the data
   */

  /* read hints: width, height, ncolors, chars_per_pixel
   */
  if (! ((width = mnextui(data)) && (height = mnextui(data))
	 && (ncolors = mnextui(data)) && (cpp =  mnextui(data)))) {
      XpmErrorStatus = PixmapFileInvalid;
      return(NULL);
  }

  /* store the hints comment line
   */
  if (infos) mgetcmt(data, &infos->hints_cmt);

  for (a = 1, b = 2; b < ncolors; b <<= 1, a++);
  pixlen = (a / 8) + (a % 8 ? 1 : 0);

  /* read colors
   */
  if (! (colorTable = (char ***)calloc(ncolors, sizeof(char **)))) {
      XpmErrorStatus = PixmapNoMemory;
      return(NULL);
  }
  for(a = 0; a < ncolors; a++) {
      mnextstring(data);		/* skip the line */
      if (! (*(colorTable + a) = (char **)calloc((NKEYS + 1), sizeof(char
*))))
	  RETURN(PixmapNoMemory);
      /* read pixel value
       */
      if (! (**(colorTable + a) = (char *)malloc(cpp)))
	  RETURN(PixmapNoMemory);
      for (b = 0; b < cpp; b++)
	  *(**(colorTable + a) + b)= mgetc(data);

      /* read color keys and values
       */
      while (l = mnextw(data, buf)) {
	  for (key = 1; key < NKEYS + 1; key++)
	      if (! strncmp(ColorKeys[key - 1], buf, l))
		  break;
	  if (l = mnextw(data, buf)) {
	      if (! (*(*(colorTable + a) + key) = (char *)malloc(l + 1)))
		  RETURN(PixmapNoMemory);
	      strncpy(*(*(colorTable + a) + key), buf, l);
	      *(*(*(colorTable + a) + key) + l) = '\0';
	  } else {
	      RETURN(PixmapFileInvalid); /* key without value */
	  }
      }      
  }

  /* store the colors comment line
   */
  if (infos) mgetcmt(data, &infos->colors_cmt);

  /* read pixels and index them on color number
   */
  if (! (dptr = bptr = (unsigned char *)
	 malloc(width * height * pixlen)))
      RETURN(PixmapNoMemory);
  if (! (chars = (char *)malloc(cpp)))
      RETURN(PixmapNoMemory);
  for (y = 0; y < height; y++) {
      mnextstring(data);
      for (x = 0; x < width; x++) {
	  for (a = 0; a < cpp; a++) {
	      chars[a] = mgetc(data);
	  }
	  for (a = 0; a < ncolors; a++)
	      if (!strncmp(**(colorTable + a), chars, cpp))
		  break;
	  if (a == ncolors) {	/* no color matches */
	      RETURN(PixmapFileInvalid);
	  }
	  valToMem((unsigned long)a, dptr, pixlen);
	  dptr += pixlen;
      }
  }

  /* store the pixels comment line
   */
  if (infos) mgetcmt(data, &infos->pixels_cmt);

  /* 
   * build the image data
   */

  key = visualType(visual);

  if (! (pixels = (Pixel *)malloc(sizeof(Pixel) * ncolors)))
      RETURN(PixmapNoMemory);

  /* get pixel colors and index them
   */
  for (a = 0; a < ncolors; a++) {
      colorname = NULL;

      /* look for a defined symbol
       */
      if (numsymbols && *(*(colorTable + a) + 1)) {
	  for (l = 0; l < numsymbols; l++)
	      if (!strcmp(colorsymbols[l].name, *(*(colorTable + a) + 1)))
		  break;
	  if (l != numsymbols && colorsymbols[l].value)
	      colorname = colorsymbols[l].value;
      }
      if (! colorname) {
	  if (*(*(colorTable + a) + key)) {
	      b = key;
	  } else {
	      for (b = key - 1; b > 1; b--)
		  if (*(*(colorTable + a) + b))
		      break;
	      if (b == 1) {
		  for (b = key + 1; b < NKEYS + 1; b++)
		      if (*(*(colorTable + a) + b))
			  break;
		  if (b == NKEYS + 1)
		      RETURN(PixmapFileInvalid);
	      }
	  }
	  colorname = *(*(colorTable + a) + b);
      }
      if (! XParseColor(display, colormap, colorname, &xcolor))
	  RETURN(PixmapParseColorFailed);
      if (XAllocColor(display, colormap, &xcolor)) {
	  if (infos) {
	      for (b = 0; b < a; b++)
		  if (*(pixels + b) == xcolor.pixel)
		      break;
	      if (b != a) {
		  if (! XAllocColorCells(display, colormap, False, NULL, 0,
					 pixels + a, 1))
		      RETURN(PixmapAllocColorFailed);
		  XFreeColors(display, colormap, &(xcolor.pixel), 1, 0);
		  xcolor.pixel = *(pixels + a);
		  XStoreColor(display, colormap, &xcolor);
	      }
	  }
      } else
	  RETURN(PixmapAllocColorFailed);

      *(pixels + a) = xcolor.pixel;
  }

  /* set data pixels to the indexed color pixel
   */
  dptr = bptr;
  for (y = 0; y < height; y++) {
      for (x = 0; x < width; x++) {
	  valToMem(*(pixels + memToVal(dptr, pixlen)), dptr, pixlen);
	  dptr += pixlen;
      }
  }

  /*
   * send the image to the server
   */

  pixmap = XCreatePixmap(display, d, width, 
			 height, depth);
  gcv.function= GXcopy;
  gc = XCreateGC(display, pixmap, GCFunction, &gcv);
  ximage = XCreateImage(display, visual, depth, ZPixmap, 0, (char *)bptr, 
			width, height, 8, 0);
  ximage->byte_order= MSBFirst; /* trust him, Jim Frost knows what he's */
				/* talking about */
  XPutImage(display, pixmap, gc, ximage, 0, 0, 0, 0, 
	    width, height);

  ximage->data = NULL;
  XDestroyImage(ximage);	/* waste not want not */
  XFreeGC(display, gc);
  free(dptr);
  free(chars);

  *width_return = width;
  *height_return = height;
  *pixels_return = pixels;
  *npixels_return = ncolors;

  /* store color table infos
   */
  if (infos) {
      infos->ncolors = ncolors;
      infos->colorTable = colorTable;
      infos->pixels = pixels;
  } else {
      freeColorTable(colorTable, ncolors);
  }

  return(pixmap);
}
END_OF_SHAR_FOR_create.c
cat > demo.c << \END_OF_SHAR_FOR_demo.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* demo.c:
 *
 *  XPM2
 *  Demo File
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpm.h"

/* XPM2 C */
/* plaid pixmap */
static char * plaid[] = {
/* width height ncolors chars_per_pixel */ 
"22 22 4 2",
/* colors */
"   c red 	m white  s light_color",
"Y  c yellow	m black  s lines_in_mix",
"+  c yellow	m white  s lines_in_dark",
"x 		m black  s dark_color",
/* pixels */
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ",
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ", 
"          x           x   x   x Y x   x   x ", 
"x x x x x x x x x x x x x x x x x x x x x x ", 
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ", 
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ", 
"          x           x   x   x Y x   x   x "
} ;

static Display *dpy;
static XEvent e ;
static Window root, win ;
static int depth,screen ;
static XSetWindowAttributes xswa;
static char **command ;
static Pixmap pix ;
static Colormap cmp;
static unsigned long *pixels;
static unsigned int npixels;
static XpmInfo infos;
static Visual *v;

main(argc, argv)
int	argc;
char	*argv[];
{

    unsigned int w, h;
    int winx, winy, winw, winh;
    char *display = NULL ;
    char *geom = NULL;
    char *type = NULL;
    char *input = NULL;
    char *output = NULL;
    int numsymbols = 0;
    ColorSymbol symbols[4];
    int ErrorStatus, notend = 1;

    command = argv ;
    while (*++argv) {
	if (index(*argv,':')) display = *argv ; else
	if (!strcmp(*argv,"-d")) 
		if (*++argv)  display = *argv ; else Usage(); else
	if (!strcmp(*argv,"-display")) 
		if (*++argv)  display = *argv ; else Usage(); else
	if (index(*argv,'=')) geom = *argv ; else
	if (!strcmp(*argv,"-g")) 
		if (*++argv)  geom = *argv ; else Usage(); else
	if (!strcmp(*argv,"-geometry")) 
		if (*++argv)  geom = *argv ; else Usage(); else
	if (!strcmp(*argv,"-geom")) 
		if (*++argv)  geom = *argv ; else Usage(); else
	if (!strcmp(*argv,"-t")) 
		if (*++argv)  type = *argv ; else Usage(); else
	if (!strcmp(*argv,"-i")) 
		if (*++argv)  input = *argv ; else Usage(); else
	if (!strcmp(*argv,"-o")) 
		if (*++argv)  output = *argv ; else Usage(); else
	if (!strcmp(*argv,"-s")) {
	    if (numsymbols < 4) {
		if (*++argv) symbols[numsymbols].name = *argv ; else Usage();
		if (*++argv) symbols[numsymbols++].value = *argv ; else Usage();
	    }
	} else
		 Usage() ;
    }


    if ((dpy = XOpenDisplay(display)) == NULL) {
	fprintf(stderr,"Cannot open display : %s\n",
			XDisplayName(display));
	exit(0);
    }

    winx = 100;    	winy = 100;
    winw = 100;    	winh = 100;
    if (geom)  {
	   XParseGeometry(geom, &winx, &winy, &winw, &winh) ;
    }
	 
    root = DefaultRootWindow(dpy);
    screen = DefaultScreen(dpy) ;
    depth = DefaultDepth(dpy,screen) ;
    cmp = DefaultColormap(dpy, screen);
    v = DefaultVisual(dpy, screen);

    xswa.background_pixel = WhitePixel(dpy,DefaultScreen(dpy)) ;
    xswa.event_mask = ButtonPressMask;
    xswa.save_under = True ;
    xswa.override_redirect = True ;
    win = XCreateWindow(dpy,root,
			winx, winy, winw, winh, 1, 
			depth, InputOutput,CopyFromParent,
			CWEventMask|CWBackPixel|
			CWOverrideRedirect|CWSaveUnder, &xswa);

    if (input) {
	if ((ErrorStatus = XReadPixmapFile(dpy, v, win, cmp, input, depth,
					   &pix, &w, &h, &pixels, &npixels,
					   symbols, numsymbols, &infos))
	    != PixmapSuccess) {
	    printf("Pixmap Error %d\n", ErrorStatus);
	    exit(1);
	}
    } else {
	if ((ErrorStatus = XCreatePixmapFromData(dpy, v, win, cmp, plaid, depth,
						&pix, &w, &h, &pixels, &npixels,
						 symbols, numsymbols, NULL))
	    != PixmapSuccess) {
	    printf("Pixmap Error %d\n", ErrorStatus);
	    exit(1);
	}
    }
    XSetWindowBackgroundPixmap(dpy, win, pix);
    XMapWindow(dpy, win);

    if (output)
	if ((ErrorStatus = XWritePixmapFile(dpy, cmp, output, pix, w, h, type, 
					    2, &infos))
	    != PixmapSuccess) {
	    printf("Pixmap Error %d\n", ErrorStatus);
	    exit(1);
	}

    do {
      XNextEvent(dpy, &e) ;
      if (e.type == ButtonPress)
	   notend = 0;
    } while (notend) ;

    XFreePixmap(dpy, pix);
    XFreeColors(dpy, cmp, pixels, npixels, 0);
    XFreeXpmInfo(&infos);
}


Usage()
{
	fprintf(stderr,"%s %s %s%s", command[0],
		"[-g wxh+x+y] [-d host:display.screen]",
		"[-s symbol_name symbol_value]\n", 
		"\t[-t type] [-i inputfile] [-o outputfile]\n");
	exit(0);
}
END_OF_SHAR_FOR_demo.c
cat > free.c << \END_OF_SHAR_FOR_free.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* free.c:
 *
 *  XPM2
 *  Free utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"

freeColorTable(colorTable, ncolors)
char ***colorTable;
int ncolors;
{ int a, b;
    if (colorTable) {
	for (a = 0; a < ncolors; a++)
	    if (*(colorTable +a)) {
		for (b = 0; b < (NKEYS + 1); b++)
		    if (*(*(colorTable +a) + b))
			free(*(*(colorTable +a) + b));
		free(*(colorTable +a));
	    }
	free(colorTable);
    }
}

XFreeXpmInfo(infos)
XpmInfo *infos;
{
    if (infos) {
	if (infos->type) free(infos->type);
	freeColorTable(infos->colorTable, infos->ncolors);
	if (infos->hints_cmt) free(infos->hints_cmt);
	if (infos->colors_cmt) free(infos->colors_cmt);
	if (infos->pixels_cmt) free(infos->pixels_cmt);
    }
}
END_OF_SHAR_FOR_free.c
cat > mio.c << \END_OF_SHAR_FOR_mio.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* mio.c:
 *
 *  XPM2
 *  I/O utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"

static int CommentLength = 0;
static char Comment[BUFSIZ];
LFUNC(atoui, unsigned int, (char *p));

static unsigned int atoui(p)
char *p;
{
        register int n;

        n = 0;
        while(*p >= '0' && *p <= '9')
                n = n*10 + *p++ - '0';
        return(n);
}

mnextstring(mdata)		/* skip to the end of the current string */
MData *mdata;			/* and the beginning of the next one */
{ char  c;
    switch(mdata->type) {
    case MARRAY:
	mdata->cptr = ((char **)mdata->stream)[++mdata->line];
	break;
    case MFILE:
	while ((c = mgetc(mdata)) != EOS && c != EOF);
	if (BOS)
	    while ((c = mgetc(mdata)) != BOS && c != EOF);
	break;
    }
}

unsigned int mnextui(mdata)	/* skip whitespace and return the following */
MData *mdata;			/* unsigned int 			    */
{ char buf[BUFSIZ];

  mnextw(mdata, buf);
  return(atoui(buf));
}

char mgetc(mdata)		/* return the current character */
MData *mdata;
{ char c;
  register unsigned int n = 1, a;
  unsigned int notend;

    switch(mdata->type) {
    case MARRAY:
	return(*mdata->cptr++);
    case MFILE:
	c = getc((FILE *)mdata->stream);
	if (BCMT && c == BCMT[0]) {
	    Comment[0] = c;
	    /* skip the string begining comment
	     */
	    while ((Comment[n] = getc((FILE *)mdata->stream)) == BCMT[n]
		   && BCMT[n] != '\0' && Comment[n] != EOF) n++;
	    if (BCMT[n] != '\0') { /* this wasn't the begining of a comment */
		for (a = 1; a < n; a++)
		    mungetc(Comment[a], mdata);
		return(c);
	    }
	    /* store comment 
	     */
	    Comment[0] = Comment[n];
	    n = notend = 1;
	    while (notend) {
		while ((Comment[n] = getc((FILE *)mdata->stream)) != ECMT[0] 
		       && Comment[n] != EOF) n++;
		CommentLength = n++;
		a = 1;
		while ((Comment[n] = getc((FILE *)mdata->stream)) == ECMT[a]
		       && ECMT[a] != '\0' && Comment[n] != EOF) { a++; n++; }
		if (ECMT[a] == '\0') { /* this is the end of the comment */
		    notend = 0;
		    mungetc(Comment[n], mdata);
		} else {
		    n++;
		}
	    }
	    c = mgetc(mdata);
	}
	return(c);
    }
}


char mungetc(c, mdata)		/* push the given character back */
int c;
MData *mdata;
{ 
    switch(mdata->type) {
    case MARRAY:
	return(*--mdata->cptr = c);
    case MFILE:
	return(ungetc(c, (FILE *)mdata->stream));
    }
}


mskipwhite(mdata)		/* skip whitespace */
MData *mdata;
{ char c;

    switch(mdata->type) {
    case MARRAY:
	while (*mdata->cptr == SPC || *mdata->cptr == TAB) 
	    mdata->cptr++;
	break;
    case MFILE:
	while ((c = mgetc(mdata)) == SPC || c == TAB);
	mungetc(c, mdata);
	break;
    }
}


unsigned int mnextw(mdata, buf)	/* skip whitespace and return the following */
MData *mdata;			/* word					    */
char *buf;
{ register unsigned int n = 0;

    mskipwhite(mdata);
    switch(mdata->type) {
    case MARRAY:
	while ((buf[n] = *mdata->cptr++) != SPC 
	       && buf[n] != TAB && buf[n] != EOS && buf[n] != EOF) n++;
	mdata->cptr--;
	break;
    case MFILE:
	while ((buf[n] = mgetc(mdata)) != SPC 
	       && buf[n] != TAB && buf[n] != EOS && buf[n] != EOF) n++;
	ungetc(buf[n],(FILE *)mdata->stream); 
	break;
    }
  return(n);
}

mgetcmt(mdata, cmt)		/* get the current comment line */
MData *mdata;
char **cmt;
{
    switch(mdata->type) {
    case MARRAY:
	break;
    case MFILE:
	*cmt = (char *) malloc(CommentLength + 1);
	strncpy(*cmt, Comment, CommentLength);
	(*cmt)[CommentLength] = '\0';
	CommentLength = 0;
	break;
    }
}
END_OF_SHAR_FOR_mio.c
cat > plaid << \END_OF_SHAR_FOR_plaid
! XPM2
! width height ncolors chars_per_pixel
22 22 4 2
! colors
   c red 	m white  s light_color
Y  c yellow	m black  s lines_in_mix
+  c yellow	m white  s lines_in_dark
x 		m black  s dark_color
! pixels
x   x   x x x   x   x x x x x x + x x x x x 
  x   x   x   x   x   x x x x x x x x x x x 
x   x   x x x   x   x x x x x x + x x x x x 
  x   x   x   x   x   x x x x x x x x x x x 
x   x   x x x   x   x x x x x x + x x x x x 
Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + 
x   x   x x x   x   x x x x x x + x x x x x 
  x   x   x   x   x   x x x x x x x x x x x 
x   x   x x x   x   x x x x x x + x x x x x 
  x   x   x   x   x   x x x x x x x x x x x 
x   x   x x x   x   x x x x x x + x x x x x 
          x           x   x   x Y x   x   x 
          x             x   x   Y   x   x   
          x           x   x   x Y x   x   x 
          x             x   x   Y   x   x   
          x           x   x   x Y x   x   x 
x x x x x x x x x x x x x x x x x x x x x x 
          x           x   x   x Y x   x   x 
          x             x   x   Y   x   x   
          x           x   x   x Y x   x   x 
          x             x   x   Y   x   x   
          x           x   x   x Y x   x   x 
END_OF_SHAR_FOR_plaid
cat > plaid_c << \END_OF_SHAR_FOR_plaid_c
/* XPM2 C */
static char * plaid[] = {
/* plaid pixmap 
 * width height ncolors chars_per_pixel */
"22 22 4 2 ",
/* colors 
 */
"   c red 	m white  s light_color ",
"Y  c yellow	m black  s lines_in_mix ",
"+  c yellow	m white  s lines_in_dark ",
"x 		m black  s dark_color ",
/* pixels */
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"  x   x   x   x   x   x x x x x x x x x x x ", 
"x   x   x x x   x   x x x x x x + x x x x x ", 
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ",
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ", 
"          x           x   x   x Y x   x   x ", 
"x x x x x x x x x x x x x x x x x x x x x x ", 
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ", 
"          x           x   x   x Y x   x   x ", 
"          x             x   x   Y   x   x   ", 
"          x           x   x   x Y x   x   x "
} ;
END_OF_SHAR_FOR_plaid_c
cat > plaid_ll << \END_OF_SHAR_FOR_plaid_ll
; XPM2 Lisp 
(setq plaid '(
; width height ncolors chars_per_pixel  
"22 22 4 2"
; colors 
"   c red 	m white  s light_color"
"Y  c yellow	m black  s lines_in_mix"
"+  c yellow	m white  s lines_in_dark"
"x 		m black  s dark_color"
; pixels 
"x   x   x x x   x   x x x x x x + x x x x x " 
"  x   x   x   x   x   x x x x x x x x x x x " 
"x   x   x x x   x   x x x x x x + x x x x x " 
"  x   x   x   x   x   x x x x x x x x x x x " 
"x   x   x x x   x   x x x x x x + x x x x x " 
"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + " 
"x   x   x x x   x   x x x x x x + x x x x x " 
"  x   x   x   x   x   x x x x x x x x x x x " 
"x   x   x x x   x   x x x x x x + x x x x x " 
"  x   x   x   x   x   x x x x x x x x x x x " 
"x   x   x x x   x   x x x x x x + x x x x x " 
"          x           x   x   x Y x   x   x " 
"          x             x   x   Y   x   x   "
"          x           x   x   x Y x   x   x " 
"          x             x   x   Y   x   x   " 
"          x           x   x   x Y x   x   x " 
"x x x x x x x x x x x x x x x x x x x x x x " 
"          x           x   x   x Y x   x   x " 
"          x             x   x   Y   x   x   " 
"          x           x   x   x Y x   x   x " 
"          x             x   x   Y   x   x   " 
"          x           x   x   x Y x   x   x "
))
END_OF_SHAR_FOR_plaid_ll
cat > rep10.sty << \END_OF_SHAR_FOR_rep10.sty
% rep10.sty 23 Sep 85
\lineskip 1pt \normallineskip 1pt
\def\baselinestretch{1}

\def\@normalsize{\@setsize\normalsize{12pt}\xpt\@xpt
\abovedisplayskip 10pt plus2pt minus5pt\belowdisplayskip \abovedisplayskip
\abovedisplayshortskip \z@ plus3pt\belowdisplayshortskip 6pt plus3pt minus3pt}
\def\small{\@setsize\small{11pt}\ixpt\@ixpt
\abovedisplayskip 8.5pt plus 3pt minus 4pt\belowdisplayskip \abovedisplayskip
\abovedisplayshortskip \z@ plus2pt\belowdisplayshortskip 4pt plus2pt minus 2pt
\def\@listi{\topsep 4pt plus 2pt minus 2pt\parsep 2pt plus 1pt minus 1pt
\itemsep \parsep}}
\def\footnotesize{\@setsize\footnotesize{9.5pt}\viiipt\@viiipt
\abovedisplayskip 6pt plus 2pt minus 4pt\belowdisplayskip \abovedisplayskip
\abovedisplayshortskip \z@ plus 1pt\belowdisplayshortskip 3pt plus 1pt minus
2pt
\def\@listi{\topsep 3pt plus 1pt minus 1pt\parsep 2pt plus 1pt minus 1pt
\itemsep \parsep}}
\def\scriptsize{\@setsize\scriptsize{8pt}\viipt\@viipt}
\def\tiny{\@setsize\tiny{6pt}\vpt\@vpt}
\def\large{\@setsize\large{14pt}\xiipt\@xiipt}
\def\Large{\@setsize\Large{18pt}\xivpt\@xivpt}
\def\LARGE{\@setsize\LARGE{22pt}\xviipt\@xviipt}
\def\huge{\@setsize\huge{25pt}\xxpt\@xxpt}
\def\Huge{\@setsize\Huge{30pt}\xxvpt\@xxvpt}
\normalsize 

\if@twoside \oddsidemargin 44pt \evensidemargin 82pt \marginparwidth 107pt
\else \oddsidemargin 63pt \evensidemargin 63pt
 \marginparwidth 90pt 
\fi
\marginparsep 11pt 
 \topmargin 27pt \headheight 12pt \headsep 25pt \footheight 12pt \footskip
30pt 

\textheight 528pt \textwidth 345pt \columnsep 10pt \columnseprule 0pt 

\footnotesep 6.65pt 
\skip\footins 9pt plus 4pt minus 2pt 
\floatsep 12pt plus 2pt minus 2pt \textfloatsep 20pt plus 2pt minus 4pt
\intextsep 12pt plus 2pt minus 2pt \@maxsep 20pt \dblfloatsep 12pt plus 2pt
minus 2pt \dbltextfloatsep 20pt plus 2pt minus 4pt \@dblmaxsep 20pt 
\@fptop 0pt plus 1fil \@fpsep 8pt plus 2fil \@fpbot 0pt plus 1fil 
\@dblfptop 0pt plus 1fil \@dblfpsep 8pt plus 2fil \@dblfpbot 0pt plus 1fil
\marginparpush 5pt 

\parskip 0pt plus 1pt \parindent 15pt \topsep 8pt plus 2pt minus 4pt
\partopsep 2pt plus 1pt minus 1pt \itemsep 4pt plus 2pt minus 1pt 
\@lowpenalty 51 \@medpenalty 151 \@highpenalty 301 
\@beginparpenalty -\@lowpenalty \@endparpenalty -\@lowpenalty \@itempenalty
-\@lowpenalty 

\def\part{\cleardoublepage \thispagestyle{plain} \if@twocolumn \onecolumn
\@tempswatrue \else \@tempswafalse \fi \hbox{}\vfil \bgroup \centering
\secdef\@part\@spart} 

\def\@part[#1]#2{\ifnum \c@secnumdepth >-2\relax \refstepcounter{part}
\addcontentsline{toc}{part}{\thepart \hspace{1em}#1}\else
\addcontentsline{toc}{part}{#1}\fi \markboth{}{}
 \ifnum \c@secnumdepth >-2\relax \huge\bf Part \thepart \par \vskip 20pt \fi
\Huge \bf #1\@endpart} 
\def\@endpart{\par\egroup \vfil\newpage \if@twoside \hbox{}
\thispagestyle{empty} 
 \newpage 
 \fi \if@tempswa \twocolumn \fi} 
\def\@spart#1{\Huge \bf #1\@endpart}


\def\@makechapterhead#1{ \vspace*{50pt} { \parindent 0pt \raggedright 
 \ifnum \c@secnumdepth >\m@ne \huge\bf \@chapapp{} \thechapter \par 
 \vskip 20pt \fi \Huge \bf #1\par 
 \nobreak \vskip 40pt } }

\def\@makeschapterhead#1{ \vspace*{50pt} { \parindent 0pt \raggedright 
 \Huge \bf #1\par 
 \nobreak \vskip 40pt } }

\def\chapter{\clearpage \thispagestyle{plain} \global\@topnum\z@
\@afterindentfalse \secdef\@chapter\@schapter} 
\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne
 \refstepcounter{chapter}
 \typeout{\@chapapp\space\thechapter.}
 \addcontentsline{toc}{chapter}{\protect
 \numberline{\thechapter}#1}\else
 \addcontentsline{toc}{chapter}{#1}\fi
 \chaptermark{#1}
 \addtocontents{lof}{\protect\addvspace{10pt}}
\addtocontents{lot}{\protect\addvspace{10pt}} \if@twocolumn
\@topnewpage[\@makechapterhead{#2}] 
 \else \@makechapterhead{#2}
 \@afterheading \fi} 
\def\@schapter#1{\if@twocolumn \@topnewpage[\@makeschapterhead{#1}]
 \else \@makeschapterhead{#1} 
 \@afterheading\fi}

\def\section{\@startsection {section}{1}{\z@}{-3.5ex plus -1ex minus 
 -.2ex}{2.3ex plus .2ex}{\Large\bf}}
\def\subsection{\@startsection{subsection}{2}{\z@}{-3.25ex plus -1ex minus 
 -.2ex}{1.5ex plus .2ex}{\large\bf}}
\def\subsubsection{\@startsection{subsubsection}{3}{\z@}{-3.25ex plus
-1ex minus -.2ex}{1.5ex plus .2ex}{\normalsize\bf}}
\def\paragraph{\@startsection
 {paragraph}{4}{\z@}{3.25ex plus 1ex minus .2ex}{-1em}{\normalsize\bf}}
\def\subparagraph{\@startsection
 {subparagraph}{4}{\parindent}{3.25ex plus 1ex minus 
 .2ex}{-1em}{\normalsize\bf}}

\def\chaptermark#1{}

\setcounter{secnumdepth}{2}

\def\appendix{\par
 \setcounter{chapter}{0}
 \setcounter{section}{0}
 \def\@chapapp{Appendix}
 \def\thechapter{\Alph{chapter}}}


\leftmargini 25pt
\leftmarginii 22pt \leftmarginiii 18.7pt \leftmarginiv 17pt \leftmarginv 10pt
\leftmarginvi 10pt
\leftmargin\leftmargini
\labelwidth\leftmargini\advance\labelwidth-\labelsep
\labelsep 5pt
\parsep 4pt plus 2pt minus 1pt
\def\@listi{\leftmargin\leftmargini}
\def\@listii{\leftmargin\leftmarginii
 \labelwidth\leftmarginii\advance\labelwidth-\labelsep
 \topsep 4pt plus 2pt minus 1pt
 \parsep 2pt plus 1pt minus 1pt
 \itemsep \parsep}
\def\@listiii{\leftmargin\leftmarginiii
 \labelwidth\leftmarginiii\advance\labelwidth-\labelsep
 \topsep 2pt plus 1pt minus 1pt 
 \parsep \z@ \partopsep 1pt plus 0pt minus 1pt
 \itemsep \topsep}
\def\@listiv{\leftmargin\leftmarginiv
 \labelwidth\leftmarginiv\advance\labelwidth-\labelsep}
\def\@listv{\leftmargin\leftmarginv
 \labelwidth\leftmarginv\advance\labelwidth-\labelsep}
\def\@listvi{\leftmargin\leftmarginvi
 \labelwidth\leftmarginvi\advance\labelwidth-\labelsep}
END_OF_SHAR_FOR_rep10.sty
cat > value.c << \END_OF_SHAR_FOR_value.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* value.c:
 *
 * routines for converting byte values to long values.  these are pretty
 * portable although they are not necessarily the fastest things in the
 * world.
 *
 * jim frost 10.02.89
 * Copyright 1989, 1990 Jim Frost
 *
 * Permission to use, copy, modify, distribute, and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  The author makes no representations
 * about the suitability of this software for any purpose.  It is
 * provided "as is" without express or implied warranty.
 *
 * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
 * USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

typedef unsigned char  byte;      /* byte type */

unsigned long memToVal(p, len)
     byte         *p;
     unsigned int  len;
{ unsigned int  a;
  unsigned long i;

  i= 0;
  for (a= 0; a < len; a++)
    i= (i << 8) + *(p++);
  return(i);
}

void valToMem(val, p, len)
     unsigned long  val;
     byte          *p;
     unsigned int   len;
{ int a;

  for (a= len - 1; a >= 0; a--) {
    *(p + a)= val & 0xff;
    val >>= 8;
  }
}
END_OF_SHAR_FOR_value.c
cat > visual.c << \END_OF_SHAR_FOR_visual.c
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* visual.c:
 *
 *  XPM2
 *  Visual utility for XPM2 file format
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#include "xpmP.h"

visualType(visual)
Visual *visual;
{
  if (visual->class == GrayScale)
      switch(visual->map_entries) {
      case 2:
	  return(MONO);
	  break;
      case 4:
	  return(GRAY4);
	  break;
      default:
	  return(GRAY);
      }
  else
      return(COLOR);
}

END_OF_SHAR_FOR_visual.c
cat > xpm.h << \END_OF_SHAR_FOR_xpm.h
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* xpm.h:
 *
 *  XPM2
 *  Include file
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#ifndef XPM_h
#define XPM_h

#define XPM_FORMAT 2

#include <X11/Xlib.h>
#include <stdio.h>

/* we keep the same codes as for Bitmap management */
#ifndef _XUTIL_H_
#ifdef VMS
#include "decw$include:Xutil.h"
#else
#include <X11/Xutil.h>
#endif
#endif

#define PixmapSuccess          0
#define PixmapOpenFailed       1
#define PixmapFileInvalid      2
#define PixmapNoMemory         3
#define PixmapParseColorFailed 4
#define PixmapAllocColorFailed 5


/* Global variables
 */

int XpmErrorStatus;
char *BCMT, *ECMT, BOS, EOS;

#define EOL '\n'
#define TAB '\t'
#define SPC ' '

typedef unsigned char  byte;      /* byte type */
typedef unsigned long  Pixel;     /* what X thinks a pixel is */

struct {
    char *type;			/* key word */
    char *Bcmt;			/* string begining comments */
    char *Ecmt;			/* string ending comments */
    char  Bos;			/* character begining strings */
    char  Eos;			/* character ending strings */
    char *Strs;			/* strings separator */
    char *Dec;			/* data declaration string */
    char *Boa;			/* string begining assignment */
    char *Eoa;			/* string ending assignment */
} DataTypes[] = {
    "", "!", "\n", '\0', '\n', "", "", "", "", /* Natural type */
    "C", "/*", "*/\n", '"', '"', ",\n", "static char **", " = {\n", "};\n",
    "Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n",
    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};

char *ColorKeys[] = {
    "s",			/* key #1: symbol */
    "m",			/* key #2: mono visual */
    "g4",			/* key #3: 4 grays visual */
    "g",			/* key #4: gray visual */
    "c",			/* key #5: color visual */
};
#define NKEYS 5			/* total number of Colorkeys */


typedef struct {
    char *name;
    char *value;
} ColorSymbol;

typedef struct {
    char *type;
    int ncolors;
    char ***colorTable;
    Pixel *pixels;
    char *hints_cmt;
    char *colors_cmt;
    char *pixels_cmt;
} XpmInfo;

#define MAXPRINTABLE 93             /* number of printable ascii chars 
				       minus \ and " for string compat. */

char *printable = 
" .XoO+@#$%&*=-;:?>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|" ;
           /* printable begin with a space, so in most case, due to
	      my algorythm, when the number of different colors is
	      less than MAXPRINTABLE, it will give a char follow by 
	      "nothing" (a space) in the readable xpm file */


/* minimal portability layer between ansi and KR C 
 */

/* forward declaration of functions with prototypes */

#if __STDC__				/* ANSI */
#define FUNC(f, t, p) extern t f p
#define LFUNC(f, t, p) static t f p
#else					/* K&R */
#define FUNC(f, t, p) extern t f()
#define LFUNC(f, t, p) static t f()
#endif					/* end of K&R */

/* functions declarations
 */

FUNC(XCreatePixmapFromData, int, (Display *display,
				  Visual *visual,
				  Drawable d,
				  Colormap colormap,
				  char **data,
				  unsigned int depth,
				  Pixmap *pixmap_return,
				  unsigned int *width_return, 
				  unsigned int *height_return, 
				  Pixel **pixels_return,
				  unsigned int *npixels_return,
				  ColorSymbol colorsymbols[],
				  unsigned int numsymbols,
				  XpmInfo *infos));

FUNC(XReadPixmapFile, int, (Display *display,
			    Visual *visual,
			    Drawable d,
			    Colormap colormap,
			    char *filename,
			    unsigned int depth,
			    Pixmap *pixmap_return,
			    unsigned int *width_return, 
			    unsigned int *height_return, 
			    Pixel **pixels_return,
			    unsigned int *npixels_return,
			    ColorSymbol colorsymbols[],
			    unsigned int numsymbols,
			    XpmInfo *infos));

FUNC(XWritePixmapFile, int, (Display *display,
			     Colormap colormap,
			     char *filename,
			     Pixmap *pixmap,
			     unsigned int width,
			     unsigned int height,
			     char *type,
			     unsigned int cppm,
			     XpmInfo *infos));

FUNC(XFreeXpmInfo, int, (XpmInfo *infos));

#endif
END_OF_SHAR_FOR_xpm.h
cat > xpm.tex << \END_OF_SHAR_FOR_xpm.tex
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                              XPM MANUAL                                    %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
%
% adjust these for centering on the page:
% upper-left corner of frame in title page must be at 60mm,60mm from 
% upper-left corner of the page

% normal (A4) on our Apple Laserwriter with dvi2ps
%\hoffset 0cm
%\voffset 0cm
% normal (A4 & Letter) on our Apple Laserwriter with dvips v5.0
\hoffset -5.5mm
\voffset 0cm
% our imagen
%\hoffset -0.9cm
%\voffset -2.2cm
		   
% NOTE: the following line MUST be commented out!
%\includeonly{standard}

\makeindex

\documentstyle[twoside,colas]{article}

% IF YOUR DVI PRINTER CHOKES ON INCLUDED POSTSCRIPT FILES
% by the \special command, uncomment the following line:
% \def\texpsfig#1#2#3{\fbox{Figure ``#1''}}


\pagestyle{headings}
\begin{document} 

\thispagestyle{empty}
\ 
\hbox{\colastitledisp
\vbox{
\vspace{3cm}
\begin{center}
\fboxrule 0.4pt \fboxsep 1pt
\fbox{\fboxrule 3pt \fboxsep 30pt \fbox{\Huge\bf XPM Manual}}
\end{center}
\vspace{2cm}
\begin{center}
\huge
The {\bf X} {\bf P}ix{\bf M}ap Format
\end{center}
\vspace{2cm}
\begin{center} 
\Large Version \RCSRevVersion$Version: 2.1 $\\
\end{center}
\vspace{2cm}
\begin{center}
\LARGE\sf Arnaud Le Hors\\
\large\tt lehors@mirsa.inria.fr
\end{center}
\vspace{1cm}
\vspace{1cm}
\begin{center}
\copyright BULL 1990
\end{center}
}}

\newpage

\section*{Copyright restrictions}
{\bf\begin{flushleft} 
Copyright 1990 GROUPE BULL\\
\end{flushleft}}

{\sf
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided
that the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of GROUPE BULL not be used in advertising
or publicity pertaining to distribution of the software without specific,
written prior permission.  GROUPE BULL makes no representations about the
suitability of this software for any purpose.  It is provided ``as is''
without express or implied warranty.

GROUPE BULL disclaims all warranties with regard to this software,
including all implied warranties of merchantability and fitness,
in no event shall GROUPE BULL be liable for any special,
indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits,
whether in an action of contract, negligence or other tortious
action, arising out of or in connection with the use 
or performance of this software.
}

\section*{Acknowledgements}

I want to thank my team partner and friend Colas Nahaboo who proposed me this
project, and who actively participated to its design.

\begin{flushright}
{\Large Arnaud Le Hors.\quad}
{\small
KOALA Project -- BULL Research c/o INRIA\\
2004 route des Lucioles -- 06565 Valbonne Cedex -- FRANCE\\
}
\end{flushright}

\section*{Support}

\sloppy 
You can mail any question or suggestion relative to {\bf XPM} by electronic
mail to {\tt lehors@mirsa.inria.fr}, and you can find the latest release by
anonymous ftp on avahi.inria.fr (192.5.60.47) or expo.lcs.mit.edu
(18.30.0.212).

\newpage
\section{Introduction}
First, Why another image format?  We (Koala team at Bull Research, France)
felt that most images bundled with X applications will be small "icons", and
that since many applications are color-customizable, existing image formats
such as gif, tiff, iff, etc... were intended for big images with well-defined
colors and so weren't adapted to the task.  So {\bf XPM} was designed with
these criterions in mind:
\begin{itemize}
\item be editable by hand (under emacs, vi...). Color pixmap editors aren't
available everywhere.
\item be includable in code either C, Lisp, ... It is unreasonable to load
1000 pixmap files on each start of an application.
\item be a portable, mailable ascii format.
\item provide defaults for monochrome/color/grayscale renderings.
\item provide overriding of colors. This way if the user wants your
application
to be bluish instead of greenish, you can use the SAME icon files.
\item allow comments to be included in the file.
\end{itemize}

\newpage
\section{The {\bf XPM2} Format}

The {\bf XPM2} format presents different types of syntax, in order to provide
the ability to include {\bf XPM2} files in different languages. But the
different types are much alike if we consider the following type dependent
tokens: beginning and end of line, beginning and end of string, string
separator, beginning and end of comment, declaration string, beginning and end
of assignment. Depending on the type they may or may not exist.

The {\bf XPM2} format is conceptually an array of string. The Natural type
which is designed for manual editing is a syntax derived from the {\bf X}
resource file format, where strings are just lines ending with a newline
character and where comments start at an exclamation mark and end at the end
of the line.

The {\bf XPM2} format is composed of six different sections as follows:
{\tt
\begin{flushleft}
\hspace{1cm}<Header line>\\
\hspace{1cm}<Declaration and Beginning of Assignment line>\\
\hspace{1cm}<Hints>\\
\hspace{1cm}<Colors>\\
\hspace{1cm}<Pixels>\\
\hspace{1cm}<End of Assignment>
\end{flushleft}
}
The {\tt Header line} is composed as follows: 

{\tt <AnyWord>} XPM2 {\tt <Type>} {\tt <AnyWord>}

The words are separated by a white space which can be composed of space and
tabulation characters.  The {\tt AnyWord} can be anyone as it will just be
skipped, this is to allow any kind of language dependent comment string. The
{\tt Type} word defines the type of {\bf XPM2} format and thus the syntax of
the file being read. For now, this may be nothing for Natural type, C, or
Lisp.  The line must end by a newline character. From there, the different
type dependent syntax tokens are determined.

In case of Natural type, there is no {\tt Declaration and Beginning of
Assignment line}; otherwise it must end by a newline character and is composed
as follows: 

{\tt <Declaration string> <variable name> <Beginning of assignment>}

The {\tt Hints} section is composed of one line containing the four integers
in base 10, corresponding to the pixmap width and height, the number of colors
and the number of characters per pixel as follows:

{\tt <width> <height> <ncolors> <chars\_per\_pixel>}

The {\tt Colors} section is composed of as many lines as there are colors, and
each line is composed as follows: 

{\tt <chars> [[<key> <color>] ... ]}

Where {\tt chars} is the {\tt chars\_per\_pixel} length string (not surrounded
anything) representing the pixels, {\tt color} is the specified color, and
{\tt key} is a keyword describing in which context this color should be used.
For now these keys may have the following values:

\begin{tabbing}
\hspace{1cm}\= g4 \= for 4-level grayscale\kill
\> m  \>for mono visual\\
\> s  \> for symbolic name\\
\> g4 \> for 4-level grayscale\\
\> g  \> for grayscale with more than 4 levels\\
\> c  \> for color visual
\end{tabbing}

Colors can be specified by giving colorname, the RGB code following the \#
character, or the HSV code following the \% character (not implemented yet).
The symbolic name provides the ability of specifying the colors at load
time, and not to hard-code them in the file.

The {\tt Pixels} section is composed by {\tt height} strings of {\tt width} *
{\tt chars\_per\_pixel} characters, where every {\tt chars\_per\_pixel} length
string must be one of the previously defined in the {\tt Colors} section.

Finally the {\tt End of Assignment} section ends the format.


\newpage
\section{The {\bf XPM2} Library}

The {\bf XPM2} library provides three functions that you can use to read and
write a pixmap from and to a {\bf XPM2} format file, and to create a pixmap.
This section describes these functions.

\vspace{.5cm}
To provide a way to rewrite an {\bf XPM2} file without loosing information
such as comments, color defaults and symbols which may exist in the read file,
the {\bf XPM2} library defines the {\bf XpmInfo} structure to stores them.
This structure contains:

\begin{tabbing}

\hspace{1cm}\= Unsigned long *pixels; \= /* List of color pixels. */ \kill
typedef struct \{ \\
\> char *type; \> /* Type of {\bf XPM2} format: Natural, C, Lisp, ... */ \\
\> int ncolors; \> /* Number of colors. */ \\
\> char ***colorTable; \> /* Color table pointer. */ \\
\> Unsigned long *pixels; \> /* List of color pixels. */ \\
\> char *hints\_cmt; \> /* Comment of the hints section. */ \\
\> char *colors\_cmt; \> /* Comment of the colors section. */ \\
\> char *pixels\_cmt; \> /* Comment of the pixels section. */ \\
\} XpmInfo;

\end{tabbing}

The colorTable is a two dimensional array of strings, organized as follows:
\begin{flushleft}
\hspace{.5cm}colorTable[color\#][0] points to the character string associated
to the color.\\
\hspace{.5cm}colorTable[color\#][1] points to the symbolic name of the
color.\\
\hspace{.5cm}colorTable[color\#][2] points to the default color for monochrome
visuals.\\
\hspace{.5cm}colorTable[color\#][3] points to the default color for 4-level
grayscale visuals.\\
\hspace{.5cm}colorTable[color\#][4] points to the default color for other
grayscale visuals.\\
\hspace{.5cm}colorTable[color\#][5] points to the default color for color
visuals. 
\end{flushleft}

Comments are limited to a single comment string by section. If more exist in
the read file, then only the last comment of each section will be stored.

To get informations back while writting out to a file, you just have to pass a
pointer to an {\bf XpmInfo} structure to the {\bf XReadPixmapFile} {\bf XPM2}
function while reading the file, and then give it back to the {\bf
XWritePixmapFile} {\bf XPM2} function while writting.

\vspace{.5cm}
To allow overriding of colors at load time the {\bf XPM2} library defines the
{\bf ColorSymbol} structure which contains:

\begin{tabbing}
\hspace{1cm}\= char *value; \hspace{1.5cm}\= /* Color value */\kill
typedef struct \{\\
\> char *name; \> /* Symbolic color name */\\
\> char *value;\> /* Color value */\\
\} ColorSymbol;
\end{tabbing}

To override colors at load time, you just have to pass to the {\bf
XReadPixmapFile} or {\bf XCreatePixmapFromData} {\bf XPM2} functions a pointer
to a list of {\bf ColorSymbol} elements containing the desired colors.

\vspace{.5cm}
To read a pixmap from a file, use {\bf XReadPixmapFile}.

\begin{flushleft} 

int XReadPixmapFile({\it display, visual, d, colormap, filename, depth, \\
\hspace{3cm}pixmap\_return, width\_return, height\_return, \\
\hspace{3cm}pixels\_return, npixels\_return, \\
\hspace{3cm}colorsymbols, numsymbols, infos})\\

\hspace{1cm}Display {\it *display;}\\
\hspace{1cm}Visual {\it *visual;}\\
\hspace{1cm}Drawable {\it d;}\\
\hspace{1cm}Colormap {\it colormap;}\\
\hspace{1cm}char {\it *filename;}\\
\hspace{1cm}unsigned int {\it depth;}\\
\hspace{1cm}Pixmap {\it *pixmap\_return;}\\
\hspace{1cm}unsigned int {\it *width\_return, *height\_return;}\\
\hspace{1cm}unsigned long {\it **pixels\_return;}\\
\hspace{1cm}unsigned int {\it *npixels\_return;}\\
\hspace{1cm}ColorSymbol {\it colorsymbols[];}\\
\hspace{1cm}unsigned int {\it numsymbols;}\\
\hspace{1cm}XpmInfo {\it *infos;}

\end{flushleft}

\begin{description}

\itemit{display} Specifies the connection to the X server.
\itemit{visual} Specifies a pointer to the visual.
\itemit{d} Specifies the drawable that indicates the screen.
\itemit{colormap} Specifies the colormap to use.
\itemit{filename} Specifies the file name to use.
\itemit{depth} Specifies the depth.
\itemit{pixmap\_return} Returns the pixmap which is created.
\itemit{width\_return}
\itemit{height\_return} Return the width and height values of the read pixmap
file.
\itemit{pixels\_return} Returns the list of color pixels which have been
allocated.
\itemit{npixels\_return} Returns the length of the returned color pixels list.
\itemit{colorsymbols} Specifies an array of color symbols for overriding.
\itemit{numsymbols} Specifies the number of symbols.
\itemit{infos} Specifies the location of an {\bf XpmInfo} structure to store
informations. 

\end{description} 

The {\bf XReadPixmapFile} function reads in a file containing a pixmap in the
{\bf XPM2} format. If the file cannot be opened, {\bf XReadPixmapFile} returns
{\bf PixmapOpenFailed}. If the file can be opened but does not contain valid
{\bf XPM2} pixmap data, it returns {\bf PixmapFileInvalid}. If insufficient
working storage is allocated, it returns {\bf PixmapNoMemory}. If parsing a
color fails, it returns {\bf PixmapParseColorFailed}. If allocating a color
cell fails, it returns {\bf PixmapAllocColorFailed}. Finally if no error
occurs, it returns {\bf PixmapSuccess}.

{\bf XReadPixmapFile} returns the pixmap's height and width, as read from the
file, to width\_return and height\_return. It reads the colors and pixels data
from the file. It allocates colors, as read from the file or possibly
overridden as specified in the given colorsymbols array.  The colors are
allocated dependently on the type of visual and on the default colors. If no
default value exits for the specified visual, it first looks for other
defaults nearer to the monochrome visual type and secondly nearer to the color
visual type. Then it creates a pixmap of the appropriate size, which is
returned to pixmap\_return.  If a pointer to an {\bf XpmInfo} structure, other
than {\bf NULL}, is passed {\bf XReadPixmapFile} stores in it possible
comments, color defaults and symbols, and color pixels.  The caller must free
the pixmap using {\bf XFreePixmap}, the colors using {\bf XFreeColors} with
the returned pixels list, and finally the {\bf XpmInfo} if any using {\bf
XFreeXpmInfo} when finished.

\vspace{.5cm}
To write out a pixmap to a file, use {\bf XWritePixmapFile}.

\begin{flushleft} 

int XWritePixmapFile({\it display, colormap, filename, pixmap, width,
height,\\
\hspace{3cm}type, cppm, infos})\\

\hspace{1cm}Display {\it *display;}\\
\hspace{1cm}Colormap {\it colormap;}\\
\hspace{1cm}char {\it *filename;}\\
\hspace{1cm}Pixmap {\it *pixmap;}\\
\hspace{1cm}unsigned int {\it width, height;}\\
\hspace{1cm}char {\it *type;}\\
\hspace{1cm}unsigned int {\it cppm;}\\
\hspace{1cm}XpmInfo {\it *infos;}

\end{flushleft}

\begin{description}

\itemit{display} Specifies the connection to the X server.
\itemit{colormap} Specifies the colormap.
\itemit{filename} Specifies the file name to use.
\itemit{pixmap} Specifies the pixmap which is created.
\itemit{width}
\itemit{height} Specifies the width and height of the pixmap.
file.
\itemit{type} Specifies the type of {\bf XPM2} format.
\itemit{cppm} Specifies a minimum number of characters per pixels.
\itemit{infos} Specifies the location of an {\bf XpmInfo} structure containing
informations. 

\end{description} 

The {\bf XWritePixmapFile} function writes a pixmap out to a file in the {\bf
XPM2} format. If the file cannot be opened, it returns {\bf PixmapOpenFailed}.
If the specified type is not valid, it returns {\bf PixmapFileInvalid}. If
insufficient working storage is allocated, it returns {\bf PixmapNoMemory}. If
no error occurs then it returns {\bf PixmapSuccess}.

{\bf XWritePixmapFile} writes out in the type format specified in argument,
stored in the {\bf XpmInfo} structure if any is given, or in Natural type by
default.  If a {\bf XpmInfo} structure is passed, it will writes out possible
stored informations such as comments, and color defaults and symbols.

\vspace{.5cm}
To create a pixmap from file written out by {\bf XWritePixmapFile} and
directly include in a program, use {\bf XCreatePixmapFromData}.

\begin{flushleft} 

int XCreatePixmapFromData({\it display, visual, d, colormap, data, depth, \\
\hspace{3cm}pixmap\_return, width\_return, height\_return, \\
\hspace{3cm}pixels\_return, npixels\_return, \\
\hspace{3cm}colorsymbols, numsymbols, infos})\\

\hspace{1cm}Display {\it *display;}\\
\hspace{1cm}Visual {\it *visual;}\\
\hspace{1cm}Drawable {\it d;}\\
\hspace{1cm}Colormap {\it colormap;}\\
\hspace{1cm}char {\it **data;}\\
\hspace{1cm}unsigned int {\it depth;}\\
\hspace{1cm}Pixmap {\it *pixmap\_return;}\\
\hspace{1cm}unsigned int {\it *width\_return, *height\_return;}\\
\hspace{1cm}unsigned long {\it **pixels\_return;}\\
\hspace{1cm}unsigned int {\it *npixels\_return;}\\
\hspace{1cm}ColorSymbol {\it colorsymbols[];}\\
\hspace{1cm}unsigned int {\it numsymbols;}\\
\hspace{1cm}XpmInfo {\it *infos;}

\end{flushleft}

\begin{description}

\itemit{display} Specifies the connection to the X server.
\itemit{visual} Specifies a pointer to the visual.
\itemit{d} Specifies the drawable that indicates the screen.
\itemit{colormap} Specifies the colormap to use.
\itemit{data} Specifies the location of the pixmap data.
\itemit{depth} Specifies the depth.
\itemit{pixmap\_return} Returns the pixmap which is created.
\itemit{width\_return}
\itemit{height\_return} Return the width and height values of the read pixmap
data.
\itemit{pixels\_return} Returns the list of color pixels which have been
allocated.
\itemit{npixels\_return} Returns the length of the returned color pixels list.
\itemit{colorsymbols} Specifies an array of color symbols which for
overriding.
\itemit{numsymbols} Specifies the number of symbols.
\itemit{infos} Specifies the location of an {\bf XpmInfo} structure to store
informations. 

\end{description} 

The {\bf XCreatePixmapFromData} function allows you to include in your program
a pixmap file of the corresponding type (C, Lisp, ...) which was written out
by {\bf XWritePixmapFile} ({\bf XPM2} format only) without reading in the
pixmap file.

{\bf XCreatePixmapFromData} exactly works as {\bf XReadPixmapFile} does and
returns the same way. It just reads data instead of a file. Here again, it is
the caller's responsibility to free the pixmap, the colors, and possibly the
{\bf XpmInfo} structure.

\vspace{.5cm}
To free an {\bf XpmInfo} structure use {\bf XFreeXpmInfo}.

\begin{flushleft} 

int XFreeXpmInfo({\it infos})\\

\hspace{1cm}XpmInfo {\it *infos;}

\end{flushleft}

\begin{description}

\itemit{infos} Specifies the structure to free.

\end{description}

The {\bf XFreeXpmInfo} frees all the different members of the structure: the
character strings and the ColorTable. 

\end{document} 
END_OF_SHAR_FOR_xpm.tex
cat > xpmP.h << \END_OF_SHAR_FOR_xpmP.h
/* Copyright 1990 GROUPE BULL -- See licence conditions in file COPYRIGHT */
/* xpmP.h:
 *
 *  XPM2
 *  Private Include file
 *  Developped by Arnaud Le Hors
 *  $Id: xpm.shar,v 2.1 90/08/24 19:07:31 lehors Exp $
 */

#ifndef XPMP_h
#define XPMP_h

#include <X11/Xlib.h>
#include<stdio.h>

/* we keep the same codes as for Bitmap management */
#ifndef _XUTIL_H_
#ifdef VMS
#include "decw$include:Xutil.h"
#else
#include <X11/Xutil.h>
#endif
#endif

typedef struct {
    unsigned int type;
    void         *stream;
    char         *cptr;
    unsigned int line;
} MData;

#define PixmapSuccess          0
#define PixmapOpenFailed       1
#define PixmapFileInvalid      2
#define PixmapNoMemory         3
#define PixmapParseColorFailed 4
#define PixmapAllocColorFailed 5


#define MARRAY 0
#define MFILE  1

extern int XpmErrorStatus;

typedef unsigned char  byte;      /* byte type */
typedef unsigned long  Pixel;     /* what X thinks a pixel is */

extern char *BCMT, *ECMT, BOS, EOS;

#define EOL '\n'
#define TAB '\t'
#define SPC ' '

extern struct {
    char *type;			/* key word */
    char *Bcmt;			/* string begining comments */
    char *Ecmt;			/* string ending comments */
    char  Bos;			/* character begining strings */
    char  Eos;			/* character ending strings */
    char *Strs;			/* strings separator */
    char *Dec;			/* data declaration string */
    char *Boa;			/* string begining assignment */
    char *Eoa;			/* string ending assignment */
} DataTypes[];

typedef struct {
    char *name;
    char *value;
} ColorSymbol;

typedef struct {
    char *type;
    int ncolors;
    char ***colorTable;
    Pixel *pixels;
    char *hints_cmt;
    char *colors_cmt;
    char *pixels_cmt;
} XpmInfo;

extern char *ColorKeys[];
#define NKEYS 5			/* number of ColorKeys */

#define MONO	2		/* key numbers for visual type, they must */
#define GRAY4	3		/* fit along with the number key of each */
#define GRAY 	4		/* corresponding element in ColorKeys[] */
#define COLOR	5		/* defined in xpm.h */


#define MAXPRINTABLE 93             /* number of printable ascii chars 
				       minus \ and " for string compat. */
extern char *printable;

/* minimal portability layer between ansi and KR C 
 */

/* forward declaration of functions with prototypes */

#if __STDC__				/* ANSI */
#define FUNC(f, t, p) extern t f p
#define LFUNC(f, t, p) static t f p
#else					/* K&R */
#define FUNC(f, t, p) extern t f()
#define LFUNC(f, t, p) static t f()
#endif					/* end of K&R */

/* functions declarations
 */

FUNC(XCreatePixmapFromData, int, (Display *display,
				  Visual *visual,
				  Drawable d,
				  Colormap colormap,
				  char **data,
				  unsigned int depth,
				  Pixmap *pixmap_return,
				  unsigned int *width_return, 
				  unsigned int *height_return, 
				  Pixel **pixels_return,
				  unsigned int *npixels_return,
				  ColorSymbol colorsymbols[],
				  unsigned int numsymbols,
				  XpmInfo *infos));

FUNC(XReadPixmapFile, int, (Display *display,
			    Visual *visual,
			    Drawable d,
			    Colormap colormap,
			    char *filename,
			    unsigned int depth,
			    Pixmap *pixmap_return,
			    unsigned int *width_return, 
			    unsigned int *height_return, 
			    Pixel **pixels_return,
			    unsigned int *npixels_return,
			    ColorSymbol colorsymbols[],
			    unsigned int numsymbols,
			    XpmInfo *infos));

FUNC(XWritePixmapFile, int, (Display *display,
			     Colormap colormap,
			     char *filename,
			     Pixmap *pixmap,
			     unsigned int width,
			     unsigned int height,
			     char *type,
			     unsigned int cppm,
			     XpmInfo *infos));

FUNC(XFreeXpmInfo, int, (XpmInfo *infos));

/* XPM private routines */
FUNC(CreatePixmap, Pixmap, (Display *display,
			    Visual *visual,
			    Drawable d,
			    Colormap colormap,
			    MData *data,
			    unsigned int depth,
			    unsigned int *width_return, 
			    unsigned int *height_return, 
			    Pixel **pixels_return,
			    unsigned int *npixels_return,
			    ColorSymbol colorsymbols[],
			    unsigned int numsymbols,
			    XpmInfo *infos));

FUNC(visualType, int, (Visual *visual));
FUNC(freeColorTable, int, (char ***colorTable, int ncolors));

/* I/O utility */
FUNC(mnextstring, int, (MData *mdata));
FUNC(mnextui, unsigned int, (MData *mdata));
FUNC(mgetc, char, (MData *mdata));
FUNC(mungetc, char, (int c, MData *mdata));
FUNC(mnextc, char, (MData *mdata));
FUNC(mnextw, unsigned int, (MData *mdata, char *buf));
FUNC(mgetcmt, int, (MData *mdata, char **cmt));

/* Values routines */
FUNC(valToMem, void, (unsigned long val, byte *p, unsigned int len));
FUNC(memToVal, unsigned long, (byte *p, unsigned int len));


#endif
END_OF_SHAR_FOR_xpmP.h