Git init
authorKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:49:32 +0000 (00:49 +0900)
committerKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:49:32 +0000 (00:49 +0900)
82 files changed:
AUTHORS [new file with mode: 0644]
CHANGES [new file with mode: 0644]
COPYING [new file with mode: 0755]
COPYRIGHT [new file with mode: 0644]
ChangeLog [new file with mode: 0755]
FAQ.html [new file with mode: 0644]
FILES [new file with mode: 0644]
Makefile.am [new file with mode: 0755]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
acinclude.m4 [new file with mode: 0644]
autogen.sh [new file with mode: 0644]
configure.ac [new file with mode: 0755]
cxpm/Makefile.am [new file with mode: 0755]
cxpm/cxpm.c [new file with mode: 0755]
cxpm/cxpm.man [new file with mode: 0644]
debian/README.source [new file with mode: 0644]
debian/changelog [new file with mode: 0755]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0644]
debian/libxpm-dev.docs [new file with mode: 0644]
debian/libxpm-dev.install [new file with mode: 0755]
debian/libxpm4.install [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/watch [new file with mode: 0644]
debian/xpmutils.install [new file with mode: 0644]
debian/xsfbs/repack.sh [new file with mode: 0644]
debian/xsfbs/xsfbs.mk [new file with mode: 0644]
debian/xsfbs/xsfbs.sh [new file with mode: 0644]
doc/FAQ.html [new file with mode: 0755]
doc/Makefile.am [new file with mode: 0755]
doc/README.AMIGA [new file with mode: 0755]
doc/README.MSW [new file with mode: 0755]
doc/README.html [new file with mode: 0755]
doc/xpm.PS.gz [new file with mode: 0755]
include/Makefile.am [new file with mode: 0755]
include/X11/xpm.h [new file with mode: 0755]
m4/ax_define_dir.m4 [new file with mode: 0755]
packaging/libXpm.spec [new file with mode: 0644]
src/Attrib.c [new file with mode: 0644]
src/CrBufFrI.c [new file with mode: 0755]
src/CrBufFrP.c [new file with mode: 0644]
src/CrDatFrI.c [new file with mode: 0755]
src/CrDatFrP.c [new file with mode: 0644]
src/CrIFrBuf.c [new file with mode: 0644]
src/CrIFrDat.c [new file with mode: 0644]
src/CrIFrP.c [new file with mode: 0644]
src/CrPFrBuf.c [new file with mode: 0644]
src/CrPFrDat.c [new file with mode: 0644]
src/CrPFrI.c [new file with mode: 0644]
src/Image.c [new file with mode: 0644]
src/Info.c [new file with mode: 0644]
src/Makefile.am [new file with mode: 0755]
src/RdFToBuf.c [new file with mode: 0644]
src/RdFToDat.c [new file with mode: 0644]
src/RdFToI.c [new file with mode: 0755]
src/RdFToP.c [new file with mode: 0644]
src/WrFFrBuf.c [new file with mode: 0644]
src/WrFFrDat.c [new file with mode: 0644]
src/WrFFrI.c [new file with mode: 0755]
src/WrFFrP.c [new file with mode: 0644]
src/XpmI.h [new file with mode: 0755]
src/amigax.c [new file with mode: 0644]
src/amigax.h [new file with mode: 0644]
src/create.c [new file with mode: 0755]
src/data.c [new file with mode: 0755]
src/hashtab.c [new file with mode: 0644]
src/misc.c [new file with mode: 0644]
src/parse.c [new file with mode: 0755]
src/rgb.c [new file with mode: 0644]
src/rgbtab.h [new file with mode: 0644]
src/scan.c [new file with mode: 0755]
src/simx.c [new file with mode: 0644]
src/simx.h [new file with mode: 0644]
sxpm/Makefile.am [new file with mode: 0755]
sxpm/plaid.xpm [new file with mode: 0644]
sxpm/plaid_ext.xpm [new file with mode: 0644]
sxpm/plaid_mask.xpm [new file with mode: 0644]
sxpm/sxpm.c [new file with mode: 0755]
sxpm/sxpm.man [new file with mode: 0755]
xpm.pc.in [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..1f3e437
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Xpm was originally written by Groupe Bull, but maintainence has since passed
+through the hands of XFree86, and to freedesktop.org; Daniel Stone is the
+current maintainer.
diff --git a/CHANGES b/CHANGES
new file mode 100644 (file)
index 0000000..b90e6cd
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,957 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/**************************************************************************\
+*                                                                         *
+*                      HISTORY of user-visible changes                    *
+*                                                                         *
+\**************************************************************************/
+
+3.4k    (98/03/18)
+
+    ENHANCEMENTS:
+       - A new program called cxpm is provided to check on XPM files and help
+         figuring out where the file might be invalid.
+        - The FAQ and README are now in HTML.
+
+    BUGS CORRECTED:
+        - A bug in writing pixmaps out on an 32 bit depth visual and MSBFirst
+         machine.
+               - patch from Uwe Langenkamp <Uwe.Langenkamp@t-online.de>
+        - A severe bug in parsing the pixels section when an unknown character
+         is encountered.
+
+3.4j   (96/12/31)
+
+    ENHANCEMENTS:
+       - The XPM library can now be built under Amiga DOS. This entirely comes
+         from: Lorens Younes <d93-hyo@nada.kth.se>
+         See the README.AMIGA file for details.
+       - Changes for MSW: big performance improvement in ParseAndPutPixels(),
+               fixed creation of the mask in SetColor()
+               - patch from Jan Wielemaker <jan@swi.psy.uva.nl>
+       - makefiles are provided for VMS
+               - given by Martin P.J. Zinser m.zinser@gsi.de  
+       - Imakefiles reworked to get smoother builds and fixes from:
+               - Paul DuBois dubois@primate.wisc.edu
+               - Larry Schwimmer schwim@cyclone.stanford.edu
+       - thanks to some code rearrangement the library is smaller (the size
+         reduction goes from 4 to 7% depending on the system)
+
+    BUGS CORRECTED:
+       - A severe bug (introduced in 3.4i as part of the sprintf
+         optimization) in code writing XPM extensions to a buffer
+         XpmCreateBufferFromImage/Pixmap.
+       - The XpmAttributes definition in xpm.h was declaring nalloc_colors to
+         be Bool, it's an int.
+
+3.4i   (96/09/13)
+
+    NEW FEATURES:
+       - The XPM library now allows the application to pass its own color
+         allocation/free functions. For this matter the following was done:
+         The XpmAttributes structure has three new fields alloc_color,
+         free_color, and color_closure. The following new valuemasks were
+         added XpmAllocColorFunc, XpmFreeColorsFunc, XpmColorClosure. And
+         two new types were defined XpmAllocColorFunc and XpmFreeColorsFunc.
+         See documentation for details.
+
+    ENHANCEMENTS:
+       - Windows NT support. It should compile and run fine based on the X
+         Consortium X11R6 distribution.
+       - The README file contains information to compile on Solaris with gcc.
+       - Part of the code has been optimized by using the value returned by
+         sprintf instead of calling strlen. Add the flag -DVOID_SPRINTF
+         if on your system sprintf returns void.
+                 - patch from Thomas Ott thommy@rz.fh-augsburg.de
+
+    BUGS CORRECTED:
+       - XpmFree is now a real function (simply calling free by default).
+
+    CHANGES TO THE DOC:
+       - The documentation describes the new XpmAttributes fields and their
+         use.
+
+3.4h   (96/02/01)
+
+    NEW FEATURES:
+       - The XpmAttributes has a new member called 'alloc_close_colors' which
+         lets the caller specify whether close colors should be allocated
+         using XAllocColor or not. This is especially useful when one uses a
+         private colormap full of read/write cells.
+         The xpm.h header file define a new bitmap flag called
+         XpmAllocCloseColors to use along with this new slot.
+                 - Dale Pease peased@bigbird.cso.gtegsc.com
+       - The XpmAttributes has a new member called 'bitmap_format' which lets
+         the caller specify the format of 1 bit depth images (XYBitmap or
+         ZPixmap). The xpm.h header file define a new bitmap flag called
+         XpmBitmapFormat to use along with this new field.
+
+    ENHANCEMENTS:
+       - XpmReadFileTo[Image/Pixmap], XpmCreate[Image/Pixmap]FromData,
+         XpmCreateImageFromDataFromBuffer functions do no longer use a
+         temporary XpmImage object, which reduces a lot the amount of memory
+         used. On the other hand it can take a little more time, but given the
+         following figures (based on sxpm) it is a real good trade-off.
+
+         Reading a 22x22 pixmap with 5 colors no time change is detected
+         using time:
+                 real        0.3
+                 user        0.1
+                 sys         0.1
+
+         Reading a 1279x1023 pixmap with 14 colors (quite extreme case for
+         XPM!) the time goes from:
+                 real        1.9
+                 user        0.8
+                 sys         0.8
+
+         to:
+                 real        2.2
+                 user        1.8
+                 sys         0.3
+
+         Reading the 22x22 pixmap with 5 colors the memory usage (under
+         purify) goes from:
+                 255256 code
+                  55496 data/bss
+                 163848 heap (peak use)
+                   4248 stack
+         to:
+                 271240 code
+                  55472 data/bss
+                 159752 heap (peak use)
+                   4224 stack
+
+         And reading the 1279x1023 pixmap with 14 colors it goes from:
+                 255256 code
+                  55496 data/bss
+                6705160 heap (peak use)
+                   4280 stack
+         to:
+                 271240 code
+                  55472 data/bss
+                1732616 heap (peak use)
+                   4264 stack
+
+         This clearly shows that while for small pixmaps there is no real
+         difference on both sides, for large pixmaps this makes a huge
+         difference about the amount of memory used and it is not much
+         slower.
+
+         Note that you can still get the old behavior using both
+         XpmReadFileToXpmImage and XpmCreate[Image/Pixmap]FromXpmImage instead
+         of XpmReadFileTo[Image/Pixmap]. Once more XPM gives you the choice!
+
+    BUGS CORRECTED:
+        - when defined locally the global symbols strcasecmp and strdup are
+         now called xpmstrcasecmp and xpmstrdup to avoid any possible
+         conflict.
+       - VMS has a bogus file system which requires a work around in
+         XpmReadFileToBuffer.
+                 - patch from Bob.Deen@jpl.nasa.gov
+       - the type of the exactColors attribute has been changed from unsigned
+         int to Bool.
+
+    CHANGES TO THE DOC:
+       - the documentation describes the new XpmAttributes fields
+         alloc_close_colors and bitmap_format.
+
+3.4g   (95/10/08)
+
+    ENHANCEMENTS:
+       - The XpmAttributes structure has now two new slots: alloc_pixels and
+         nalloc_pixels in order to provide an easy way to free allocated
+         colors. The new bitmask XpmReturnAllocPixels should be used to
+         request this data through the valuemask. Unless you really know why,
+         you should use this instead of XpmReturnPixels, pixels, and npixels.
+       - the XPM1 format parsing has been improved.
+                 - patch from Chuck Thompson <cthomp@cs.uiuc.edu>
+       - compilers defining _STDC_ to something different from 1 are now
+         considered as ANSI compilers.
+       - the README file provides now more info on how to build XPM depending
+         on the system.
+
+    BUGS CORRECTED:
+       - a bug introduced in 3.4f in the XPM1 format parsing function.
+                 - fix from Chuck Thompson <cthomp@cs.uiuc.edu>
+       - the hashtable was not free when the color parsing failed.
+                 - patch from ackley@cs.unm.edu (David Ackley)
+       - the close color mechanism wasn't used if one of the closeness
+          parameter was null. Now only one needs to be different from 0.
+                    Lorens Younes d93-hyo@nada.kth.se
+       - parsing of long comments failed with a segmentation fault.
+
+    CHANGES TO THE DOC:
+       - the documentation describes the new XpmAttributes fields
+         alloc_pixels and nalloc_pixels and how they are used.
+
+3.4f   (95/05/29)
+
+    ENHANCEMENTS:
+       - Defines IMAKE_DEFINES in the top Imakefile so one can easily avoid
+         building the shared library.
+       - Add some information about the installation process in the README.
+       - filenames are surrounded with quotes when calling gzip or compress in
+          order to allow spaces within filenames.
+                 - William Parn <parn@fgm.com>
+       - the compilation and the shared library building should be smoother
+         on Alpha OSF/1.
+                 - patch from Dale Moore <Dale.Moore@CS.cmu.edu>
+
+    BUGS CORRECTED:
+       - a segmentation fault occurring in some weird case.
+
+3.4e   (95/03/01)
+
+    ENHANCEMENTS:
+       - The top Imakefile passes CDEBUGFLAGS and DEFINES to subdirs. Thus
+         only this Imakefile should need to be edited by users.
+       - FAQ includes the answer to the question "How can I get a non
+         rectangular icon using XPM ?"
+       - VMS support updated
+                 - patch from Martin P.J. Zinser m.zinser@gsi.de
+
+    BUGS CORRECTED:
+       - XpmCreateImageFromXpmImage() called from XpmReadFileToPixmap() could
+         lead to a segmentation fault since free was called on a memory block
+         size variable instead of the block itself. Note: this bug has been
+         introduced in 3.4d.
+
+3.4d   (95/01/31)
+
+    ENHANCEMENTS:
+       - sxpm now supports a -version option command.
+
+    BUGS CORRECTED:
+       - the list of pixels returned in XpmAttributes was wrong when two
+         colors were defined as None in the read XPM
+                 - Lionel.Mallet@sophia.inria.fr
+       - the parser was skipping whitespace reading extensions strings. This
+         has been fixed so extensions lines are now returned exactly as they
+         are.
+       - some compilation control added for the dec alpha with X11R5 (LONG64)
+                 - patch from Fredrik Lundh <Fredrik_Lundh@ivab.se>
+       - when writing an XPM file, '-' characters are replaced with '_'
+         characters in the array name, in order to get a valid C syntax name.
+       - XYPixmap format images were not correctly handled.
+       - XPM1 file with names using multiple '_' characters are now handled
+         correctly.
+                 - todd@erda.rl.af.mil (Todd Gleason)
+
+3.4c   (94/06/06)
+
+    Yes, this is kind of quick. But this is because no code has been modified,
+    this is just a new packaging to make the whole stuff more suitable to the
+    X development team's requests for inclusion in the R6 contrib.
+
+    ENHANCEMENTS:
+       - Several filenames were too long to fit without any conflict on DOS
+         and CD-ROM filesystems. They have been renamed.
+       - Imakefiles use XCOMM for comments instead of the # character.
+       - the Postscript documentation file doc/xpm.ps is now distributed as
+         doc/xpm.PS.gz and allows browsing with tools such as ghostview.
+       - Besides, parts of lib/misc.c have been moved to several new files,
+         and some functions of data.c have been moved to other files in
+         order to get a better link profile.
+       - I've also added a FAQ hoping this will prevent people from
+         continuously filling my mailbox with the same questions.
+       - sxpm.c includes <X11/xpm.h> instead of "xpm.h" and BUILDINCTOP is
+         used in Makefiles as expected.
+       - Everything can be done simply using "xmkmf -a" and "make".
+
+3.4b   (94/05/24)
+
+    ENHANCEMENTS:
+       - XPM can now be built under MS Windows. Yes, this is possible and this
+         entirely comes from:
+               - Hermann Dunkel <hedu@cul-ipn.uni-kiel.de>
+         See the README.MSW file for details.
+
+       - building the shared library now depends on the SharedLibXpm variable
+         and no longer on the SharedLibX variable which is private to the X
+         Window System project.
+               - patch from Stephen Gildea <gildea@x.org>
+         Other variables can now be set for the various locations needed.
+
+       - lib/parse.c does no longer use a 256x256 array in the stack but
+         malloc it instead.
+
+       - The Copyright notice which has been re-written from the X11R6's one
+         should be clearer and is now present in every file.
+
+    BUGS CORRECTED:
+       - lib/xpmP.h does no longer define a Boolean type which conflicts with
+         the Intrinsic definition. Instead the type Bool defined in Xlib is
+         used.
+               - neumann@watson.ibm.com (Gustaf Neumann)
+
+3.4a   (94/03/29)
+
+    BUGS CORRECTED:
+       - passing NULL as shapemask_return to XpmReadFileToPixmap and similar
+         functions was leading to a bus error.
+               - Dean Luick <dean@falcon.natinst.com>
+
+3.4    (94/03/14)
+
+    IMPORTANT NOTE:
+       This version is not compatible with 3.3. Fortunately most people should
+       only need to recompile.
+       I apology for this but CDE/Motif have put heavy pressure to go that
+       way. The point is that I designed and released Xpm 3.3 in order to let
+       OSF include a clean version of Xpm in Motif 2.0. This new version was
+       not fully compatible with 3.2 but I thought it didn't matter since this
+       was going to be the first version used within Motif. Unfortunately CDE
+       was already using xpm-3.2 internally and requires both source and
+       binary backward compatibility. By the way I must say they didn't drop
+       us a single line to let us know they were using it and thus were
+       expecting stability. All this could have been avoided...
+
+       However, since I had to go for a not compatible version I took this as
+       an opportunity to modify the lower level API, which was new in 3.3 and
+       which was somewhat clumsy, in order to provide yet a better API.
+
+       The library has been modified to have both source and binary backward
+       compatibility with xpm-3.2. This implies it is not either source or
+       binary compatible with 3.3. The fields related to the 3.2 XpmInfos
+       mechanism have been put back into the XpmAttributes structure. The new
+       3.3 XpmInfos struct has been renamed as XpmInfo to avoid conflict with
+       the old 3.2 flag which is back too. All the semantic related to the
+       XpmAttributes infos fields is back as well.
+
+       So this new version provides a high level API which is fully
+       compatible with 3.2 and still provides the 3.3 lower level API
+       (XpmImage) with the XpmInfos struct renamed as XpmInfo. This leads to
+       some redundancy but this was the best I could do to satisfy both
+       CDE/Motif people who needed the backward compatibility and myself (who
+       always tries to provide you with the best ;-).
+
+       Tests have been successfully performed with pixmap-2.1, pixmap-2.4, and
+       sxpm.
+
+    ENHANCEMENTS:
+       - The colorTable member of the XpmAttributes structure is now an
+         (XpmColor*) in order to be compatible with an XpmImage colorTable.
+         However in order to be backward compatible this field is cast to
+         (XpmColor **), which is equivalent to (char ***), when it is used
+         with the old flags XpmInfos and XpmReturnInfos. To handle the new
+         type the new flags XpmColorTable and XpmReturnColorTable have been
+         defined.
+       - The XpmInfo struct has been extended to avoid having to deal with an
+         XpmAttributes at the lower level. The idea is that all the data
+         stored in an Xpm file can be retrieve through both an XpmImage and
+         an XpmInfo struct. See the documentation for details.
+       - XpmUndefPixel is defined and exported by xpm.h in order to let
+         clients providing their own colorTable when writing out an Xpm file.
+         See the documentation for details.
+       - in sxpm/sxpm.c, set attribute XtNinput to True on toplevel widget.
+         Windows that don't "take" input, never get focus, as mandated by
+         the ICCM.
+               patch from Henrique Martins <martins@hplhasm.hpl.hp.com>
+       - lib/Imakefile modified to build the shared library under IRIX 5.
+                patch from simon@lia.di.epfl.ch (Simon Leinen)
+
+    NEW FEATURES:
+       - a new function and a new define should help client figuring out with
+         which Xpm library version they are working. These are
+         XpmIncludeVersion and XpmLibraryVersion().
+
+3.3    (93/12/20)
+
+    NEW FEATURES:
+       - XPM1 files are now supported.
+       - a new function is provided to get an error string related to the
+         returned error code.
+               - suggested by Detlef Schmier <detlef@mfr.dec.com>
+
+    ENHANCEMENTS:
+       - gzip and gunzip are called with the -q option (quiet)
+               - patch from Chris P. Ross <cross@eng.umd.edu>
+       - the parser is again more flexible about the way the strings are
+         distributed on lines. Actually a single line XPM file can be read.
+       - the documentation should be clearer about shapemask generation and
+         XpmAttributes valuemask.
+
+    BUGS CORRECTED:
+       - reading some binary file was leading to a bus error.
+               - patch from Detlef Schmier <detlef@mfr.dec.com>
+       - the ? character is no longer used when writing an XPM file in order
+         to avoid possible ANSI trigraphs.
+
+3.3alpha (93/08/13)
+
+    NEW FEATURES:
+       - a new level interface is provided to allow applications to do either
+         icon editing or data caching.
+         The XpmAttributes has been changed but most applications will just
+         need to be recompiled.
+       - new structures are provided to deal with the new lower level:
+                XpmImage, XpmColor, XpmInfos.
+
+       - a separate distribution called xpm-contrib is available. This
+         includes the converters which used to be part of this distribution
+         plus:
+               two new applications:
+               * nexpm to draw a pixmap in *any* existing window from
+                        Ralph Betza <gnohmon@ssiny.com>
+               * xpmview to display a list of Xpm files from
+                        Jean Michel Leon <leon@sophia.inria.fr>
+
+               a hacky string to pixmap converter, provided by
+                       Robert H. Forsman Jr.  <thoth@manatee.cis.ufl.edu>
+
+               The Xpm editor called pixmap will also be part of this contrib.
+               This does not mean it is the best pixmap editor one can find
+               but it is the only one that I know of which tries to handle
+               all the features of this format.
+
+    ENHANCEMENTS:
+       - the code to build XImage data has been optimized by
+                jules@x.co.uk (Julian Gosnell)
+         the old code is still available when compiling with the
+         -DWITHOUT_SPEEDUPS flag.
+
+       - closecolor code was not re-entrant
+                - dbl@visual.com (David B. Lewis)
+       - fix gzip filename (*.gz and no longer *.z).
+                - Jason Patterson <jasonp@fitmail.fit.qut.edu.au>
+       - sxpm has 2 new options:
+                -nom to do not display the mask if there is one
+                -cp <color> <pixel> to override a color value with a given
+                pixel, i.e. sxpm plaid.xpm -cp red 4
+
+         also the '-s' adn '-p' options have been renamed to '-sc' and '-sp'.
+
+       - xpm.h defines XpmFormat, XpmVersion, and XpmRevision numbers.
+
+    BUGS CORRECTED:
+       - closecolor minor fix
+                - Jason Patterson <jasonp@fitmail.fit.qut.edu.au>
+
+3.2g   (93/04/26)
+
+    ENHANCEMENTS:
+       - much faster close colors
+       - piping from/to compressed files now handles GNU's gzip (.z)  format
+       - added XpmColorKey attribute - ability to specify which visual's
+         colors to use (ie: now it's possible to read in a pixmap in a
+         color visual, but use the colors specified for monochrome).
+       - added -mono, -grey4, -grey and -color options to sxpm to demonstrate
+         the XpmColorKey attribute.
+               - Jason Patterson <jasonp@fitmail.qut.edu.au>
+
+    BUGS CORRECTED:
+       - fixed bug where redefining "None" as a pixel stopped mask generation
+       - minor SVR4 defines for <string.h>
+       - fixed annoying closecolor bug related to read/write color cells
+       - fixed minor bug in color value -> pixel overloading
+       - manual updated to include new red/green/blue closeness attributes
+               - Jason Patterson <jasonp@fitmail.qut.edu.au>
+
+       - the top Imakefile was missing the depend target
+       - sxpm/Imakefile fixed so that -L../lib is set before the standard
+         library location.
+               - Vivek Khera <khera@cs.duke.edu>
+
+       - lib/xpmP.h now defines bcopy as memcpy for VMS (required by recent
+         versions of VMS)
+               - J. Daniel Smith <dsmith@ann-arbor.applicon.slb.com>
+
+       - the lib/Imakefile didn't work with X11R4.
+
+
+3.2f           (93/03/17)
+
+    NEW FEATURES:
+       - the library provides four new functions to deal with Xpm files
+         loaded in memory as single character strings buffers:
+
+                       XpmCreateImageFromBuffer
+                       XpmCreatePixmapFromBuffer
+                       XpmCreateBufferFromImage
+                       XpmCreateBufferFromPixmap
+
+       - in addition, as a convenience, two functions are provided to copy a
+         file in a buffer and to write a file from a buffer:
+
+                       XpmReadFileToBuffer
+                       XpmWriteFileFromBuffer
+
+    ENHANCEMENTS:
+       - Files are now dispatched in the following sub-directories:
+         lib, sxpm, and doc.
+       - Imakefiles will let you build a shared library as well as the static
+         one (with either X11R4 or X11R5).
+       - The documentation has been ported from LaTeX to FrameMaker and is
+         now included in the distribution in its PostScript form (doc/xpm.ps).
+         Source files are available on request.
+         Also the documentation has been reorganized and includes a table of
+         contents and an index of the functions (the number of functions
+         increasing this became a requisite).
+
+    BUGS CORRECTED:
+       - Many warnings have been fixed - patch from Daniel Dardailler 
+         daniel@osf.org
+
+3.2e           (93/02/05)
+
+    ENHANCEMENTS:
+       - use XpmMalloc, XpmRealloc, XpmCalloc, and XpmFree which are defines
+       in xpmP.h. This should help people wanting to use their own functions.
+
+    BUGS CORRECTED:
+       - Intrinsic.h is no longer included.
+       - bzero is defined as memset on SYSV and SVR4.
+       - some memory initialization bug concerning XpmAttributes.
+
+3.2d           (93/01/27)
+
+    ENHANCEMENTS:
+       - compile on Solaris 2.0
+               - patch from Clint Jeffery <cjeffery@cs.arizona.edu>
+
+    BUGS CORRECTED:
+       - shape masks are now set correctly for LSBFirst (Decs).
+       - pixmaps are now set correctly for 2 bit displays (Nexts).
+               - patch from Josef Leherbauer <joe@takeFive.co.at>
+       - isspace was called on getc which fails when EOF is returned.
+               - Marelli Paolo <marelli@colos3.usr.dsi.unimi.it>
+
+3.2c           (92/12/29)
+
+    ENHANCEMENTS:
+       - parsing optimized for single and double characters color
+               - patch originally from Martin Brunecky 
+                                      marbru@build1.auto-trol.com
+
+    BUGS CORRECTED:
+       - XpmFreeExtensions was calling free on some argument without checking
+       it was not NULL.
+       - strdup was not correctly defined for systems which do not provide
+       it.     - Hans-Peter Lichtin <lich@zellweger.ch>
+       - some bug in XpmCrDataFI.c
+               - Sven Delmas garfield@avalanche.cs.tu-berlin.de
+
+    NOTE:
+       - there is still a bug with the creation of the clipmask on display of
+       depth 2 but I can't find a fix because unfortunately I don't have such
+       a rendering system and nobody gets the time to investigate for me.
+
+3.2b           (92/10/19)
+
+    ENHANCEMENTS:
+       - Create XpmReadFileToData and XpmWriteFileFromData
+               - Dan Greening <dgreen@sti.com>
+       - added "close colors" support and ability to redefine color values
+         as pixels at load time, as well as color names
+               - Jason Patterson <jasonp@fitmail.qut.edu.au>
+       - errors while parsing or allocating colors now revert to other
+         visual defaults, creating pixmap/image as expected, and returning
+         XpmSuccess. The old behavior of XpmColorError being returned and no
+         pixmap/image being created can be retained by setting the
+         exactColors attribute.
+               - Jason Patterson <jasonp@fitmail.qut.edu.au>
+
+    BUGS CORRECTED:
+       - SVR4 defines for including <string.h> instead of <strings.h>
+               - Jason Patterson <jasonp@fitmail.qut.edu.au>
+       - attributes->extensions and attributes->nextensions fields were not 
+         set correctly when no extensions present in file.
+               - Simon_Scott Cornish <cornish@ecr.mu.oz.au>
+
+3.2a           (92/08/17)
+
+    ENHANCEMENTS:
+       - use the mock lisp hashing function instead of the gnu emacs one,
+       it is faster in some cases and never slower (I've not found any case).
+
+    BUGS CORRECTED:
+       - function prototypes for ansi compilers.
+       - some memory initialization bugs (purify is just great for this).
+       - empty strings in extensions are now correctly handled.
+
+3.2            (92/07/06)
+
+    NEW FEATURES:
+       - both format and functions handle extensions data. This allow people
+       to store additional data related to a pixmap. See documentation for
+       detail.
+       - sxpm supports the new option '-c' to use a private colormap. This is
+       useful when displaying pixmaps using a lot of colors.
+       - sxpm supports the new option '-v' (verbose) to get possible
+       extensions print out on standard error.
+
+    ENHANCEMENTS:
+       - most of the code has been reworked to be improved and thus almost
+       every function is faster. It takes less than 6 seconds of real time on
+       a sun4 to display, with sxpm, a 487x635 pixmap using 213 colors, while
+       it takes 32 seconds with the old library! It takes 18 seconds to
+       display a 1279x1023 screen dump using 14 colors while xwud takes 10
+       seconds.
+       Of course performance improvements are not always that great, they
+       depend on the size and number of colors but I'm sure everybody will
+       appreciate ;-)
+       I know how to improve it more but this will require changes in the
+       architecture so this is not for now. Some optimizations have been
+       contributed by gregor@kafka.saic.com (gregg hanna) and
+       jnc@csl.biosci.arizona.edu (John N. Calley).
+       - the Imakefile is modified to let you install sxpm - Rainer Klute
+           <klute@irb.informatik.uni-dortmund.de>
+       - xpmP.h declares popen for Sequent platforms - Clinton Jeffery
+          <cjeffery@cs.arizona.edu>
+       - XpmWriteFileFromImage/Pixmap rather than truncating the pixmap name
+       to the first dot changes dots to underscores to get a valid C syntax
+       name.
+
+
+    BUGS CORRECTED:
+       - there was a bug in the image creation function for some 24 bits
+       displays. It is fixed.
+       - allocated color pixels are now freed when an error occurs -
+          nusser@dec1.wu-wien.ac.at (Stefan Nusser)
+
+    CHANGES TO THE DOC:
+       - the documentation describes the new XpmExtension structure and how
+       to use it with read and write functions.
+
+3.1            (92/02/03)
+
+    ENHANCEMENTS:
+       - sxpm now have more standard options (mainly suggested by 
+       Rainer Sinkwitz <sinkwitz@ifi.unizh.ch>):
+
+       Usage:  sxpm [options...]
+       Where options are:
+
+       [-d host:display]            Display to connect to.
+       [-g geom]                    Geometry of window.
+       [-hints]                     Set ResizeInc for window.
+       [-icon filename]             Set pixmap for iconWindow.
+       [-s symbol_name color_name]  Overwrite color defaults.
+       [-p symbol_name pixel_value] Overwrite color defaults.
+       [-plaid]                     Read the included plaid pixmap.
+       [filename]                   Read from file 'filename', and from
+                                    standard input if 'filename' is '-'.
+       [-o filename]                Write to file 'filename', and to standard
+                                    output if 'filename' is '-'.
+       [-nod]                       Don't display in window.
+       [-rgb filename]              Search color names in the rgb text file
+                                    'filename'.
+
+       if no input is specified sxpm reads from standard input.
+
+
+       - Xpm functions and Ppm converters now deal with multiword colornames.
+         patches from Rainer Sinkwitz <sinkwitz@ifi.unizh.ch>.
+
+
+3.0            (91/10/03)
+
+       Functions name and defines have been modified again (sorry for that)
+       as follows:
+
+            XpmReadPixmapFile    XpmReadFileToPixmap
+            XpmWritePixmapFile   XpmWriteFileFromPixmap
+
+            XpmPixmapColorError  XpmColorError
+            XpmPixmapSuccess     XpmSuccess
+            XpmPixmapOpenFailed  XpmOpenFailed
+            XpmPixmapFileInvalid XpmFileInvalid
+            XpmPixmapNoMemory    XpmNoMemory
+            XpmPixmapColorFailed XpmColorFailed
+
+       To update code using Xpm you can use the included shell script called
+       rename with the sed commands files name-3.0b-3.0c and name-3.0c-3.0.
+       Old names still valid though.
+
+    NEW FEATURES:
+       - four new functions to work with images instead of pixmaps:
+
+            XpmReadFileToImage
+            XpmWriteFileFromImage
+            XpmCreateImageFromData
+            XpmCreateDataFromImage
+
+    ENHANCEMENTS:
+       Algorithms to create and scan images and pixmaps are based on the
+       MIT's R5 code, thus they are much cleaner than old ones and should
+       avoid any problem with any visual (yes, I trust MIT folks :-)
+
+    BUGS CORRECTED:
+       Imakefile use INCDIR instead of ROOTDIR.
+
+    CHANGES TO THE DOC:
+       - the documentation presents the four new functions.
+
+3.0c           (91/09/18)
+
+       In answer to request of people functions, types and defines names have
+       been changed as follows:
+
+            XCreatePixmapFromData       XpmCreatePixmapFromData
+            XCreateDataFromPixmap       XpmCreateDataFromPixmap
+            XReadPixmapFile             XpmReadPixmapFile
+            XWritePixmapFile            XpmWritePixmapFile
+            XFreeXpmAttributes          XpmFreeAttributes
+
+            PixmapColorError            XpmPixmapColorError
+            PixmapSuccess               XpmPixmapSuccess
+            PixmapOpenFailed            XpmPixmapOpenFailed
+            PixmapFileInvalid           XpmPixmapFileInvalid
+            PixmapNoMemory              XpmPixmapNoMemory
+            PixmapColorFailed           XpmPixmapColorFailed
+
+            ColorSymbol                 XpmColorSymbol
+
+       Generally speaking every public name begins with 'Xpm' and every
+       private one with 'xpm'. This should avoid any possible conflict.
+
+       Some files have also be renamed accordingly.
+
+    NEW FEATURES:
+       - support for VMS and two new options for sxpm: icon and hints (see
+       manual for details) Richard Hess <rhess%pleione%cimshop@uunet.UU.NET>
+       - DEFINES in Imakefile and Makefile.noXtree allows you to set the
+       following:
+
+                ZPIPE for un/compressing piped feature (default is on)
+                NEED_STRCASECMP for system which doesn't provide one (default
+                                is off)
+
+       - xpmtoppm.c has is own strstr function which is used if NEED_STRSTR
+       is defined when compiling - Hugues.Leroy@irisa.fr (Hugues Leroy).
+       
+    BUGS CORRECTED:
+       - many bugs have been fixed, especially for ansi compilers -
+              Doyle C. Davidson (doyle@doyled.b23b.ingr.com) and
+              Clifford D. Morrison (cdm%bigdaddy%edsr@uunet.UU.NET)
+       - parser is again a little more improved
+
+3.0b           (91/09/12)
+
+       This is a complete new version with a new API and where files and
+       structures have been renamed. So this should be taken as a new
+       starting release.
+       This release should be quickly followed by the 3.0 because I'm planning
+       to send it for X11R5 contrib which ends October 5th.
+
+    NEW FEATURES:
+       - support for transparent color.
+       - support for hotspot.
+       - a new function: XCreateDataFromPixmap to create an XPM data from a
+       pixmap in order to be able to create a new pixmap from this data using
+       the XCreatePixmapFromData function later on.
+       - a new structure: XpmAttributes which replace the XpmInfo structure
+       and which leads to a much simpler API with less arguments.
+       - arguments such as visual, colormap and depth are optional, default
+       values are taken if omitted.
+       - parsing and allocating color failures don't simply break anymore. If
+       another default color can be found it is used and a PixmapColorError
+       is returned. In case no color can be found then it breaks and returns
+       PixmapColorFailed.
+       - for this reason the ErrorStatus codes are redefined as follows:
+
+                  null     if full success
+                  positive if partial success
+                  negative if failure
+
+       with:
+               #define PixmapColorError    1
+               #define PixmapSuccess       0
+               #define PixmapOpenFailed   -1
+               #define PixmapFileInvalid  -2
+               #define PixmapNoMemory     -3
+               #define PixmapColorFailed  -4
+
+       - sxpm prints out a warning when a requested color could not be parsed
+       or alloc'ed, and an error when none has been found.
+       - sxpm handles pixmap with transparent color. For this purpose the
+       plaid_mask.xpm is added to the distribution.
+
+    BUGS CORRECTED:
+       - I've again improved the memory management.
+       - the parser is also improved.
+       - when writing a pixmap to a file the variable name could be
+       "plaid.xpm" which is not valid in C. Now the extension name is cut off
+       to give "plaid" as variable name.
+       - reading multiple words colornames such as "peach puff" where leading
+       to non readable Xpm files. They are now skipped to have only single
+       word colorname. Lionel Mallet (mallet@ipvpel.unipv.it).
+       - parser was triggered by the "/" character inside string.
+       Doyle C. Davidson (doyle@doyled.b23b.ingr.com). This is corrected.
+       - sxpm maps the window only if the option "-nod" is not selected. 
+
+    CHANGES TO THE DOC:
+       - the documentation presents the new API and features.
+
+3.0a           (91/04/10)
+
+       This is an alpha version because it supports the new version of XPM,
+       but the library interface is still the same. Indeed it will change in
+       future release to get rid of obsolete stuff such as the type argument
+       of the XWritePixmapFile function.
+
+    ******************************* WARNING *********************************
+       The format is not anymore XPM2, it is XPM version 3 which is XPM2
+       limited to the C syntax with the key word "XPM" in place of "XPM2 C".
+       The interface library has not changed yet but the type argument of
+       XWritePixmapFile and the type member of XpmInfo are not used anymore.
+       Meanwhile the library which is now called libXpm.a is backward
+       compatible as XPM2 files can be read. But the XWritePixmapFile
+       function only writes out XPM version 3 files.
+    *************************************************************************
+
+    NEW FEATURES:
+       - the library doesn't use global variables anymore, thus it should be
+       able to share it.
+       - sxpm has been rewritten on top of Xt, it can be used to convert
+       files from XPM2 to XPM version 3.
+       - xpm1to2c.perl has been upgraded to the new XPM version and renamed
+       as xpm1to3.perl
+       - ppmtoxpm2.c and ppmtoxpm2.1 have been upgraded too and renamed
+       ppmtoxpm.c and ppmtoxpm.1. In addition the xpmtoppm.c and xpmtoppm.1
+       of the pbmplus package have been upgraded too. xpmtoppm can thus
+       convert XPM version 1 and 3 to a portable pixmap. These files should
+       replace the original ones which are part of the pbmplus package. See
+       the ppm.README file for more details.
+       - the library contains RCS variables which allows you to get revision
+       numbers with ident (which is part of the RCS package). The Id number
+       is an internal rcs number for my eyes only. The official one is found
+       in Version.
+
+    BUGS CORRECTED:
+       - the memory management has been much improved in order to avoid
+       memory leaks.
+       - the XImage building algorithm has been changed to support correctly
+       different visual depths. There is special code to handle depths 1, 4,
+       6, 8, 24, and 32 to build the image and send it in one whack, and
+       other depths are supported by building the image with XPutPixel which
+       is slow but sure.
+       - similar algorithms are used to read pixmaps and write them out.
+
+    CHANGES TO THE DOC:
+       - the documentation presents the new XPM format.
+
+
+2.8            (90/12/19)
+
+    ******************************* WARNING *********************************
+        Since the last release two structures have been modified and have now
+       bigger sizes, so ANY CODE USING THE libXPM2 NEEDS TO BE RECOMPILED.
+    *************************************************************************
+
+    NEW FEATURES:
+       - the ColorSymbol struct contains the new member 'pixel' which allow
+       to override default colors by giving a pixel value (in such a case
+       symbol value must be set to NULL),
+       - the XpmInfo struct contains the new member 'rgb_fname' in which one
+       can specify an rgb text file name while writing a pixmap with the 
+       XWritePixmapFile function (otherwise this member should be set to
+       NULL). This way colorname will be searched and written out if found
+       instead of the RGB value,
+       - Imakefile originally provided by stolcke@ICSI.Berkeley.EDU,
+       - the old Makefile is now distributed as Makefile.noXtree and presents
+       install targets,
+       - the demo application is renamed sxpm (Show XPM), creates a window of
+       the size of the pixmap if no geometry is specified, prints out
+       messages instead of status when an error occurs, handles the new
+       option -p for overriding colors by giving a pixel value (not really
+       useful but is just here to show this new feature), handles the new
+       option -rgb for specifying an rgb text file, and ends on
+       keypress as buttonpress,
+       - defines for SYSV have been provided by Paul Breslaw
+       <paul@mecazh.uucp>,
+       - the distribution includes a new directory called converters which
+       contains xpm1to2 and xpm1to2c perl converters and a ppmtoxpm2
+       converter provided by Paul Breslaw who upgraded the original ppmtoxpm
+       written by Mark W. Snitily <mark@zok.uucp>.
+
+    CHANGES TO THE DOC:
+       - this file is created and will give old users a quick reference to
+       changes made from one release to the next one,
+       - documentation is changed to present the new ColorSymbol structure
+       and the way to override colors by giving a pixel value, and to present
+       the new XpmInfo structure and how to use it,
+       - a man page for sxpm is added to the distrib,
+       - the README file talks about sxpm and no more demo, and have
+       reference to the different converters.
+
+2.7            (90/11/12)
+
+    NEW FEATURES:
+       - XReadPixmapFile reads from stdin if filename is NULL,
+       - XWritePixmapFile writes to stdin if filename is NULL,
+       - the demo application handles the new option -nod for no displaying
+       the pixmap in a window (useful when used as converter).
+
+    CHANGES TO THE DOC:
+       - documentation about the new feature.
+
+2.6            (90/10/29)
+
+    NEW FEATURES:
+       - from nazgul@alphalpha.com (Kee Hinckley): changes to make the
+       library usable as C++ code, and on Apollo without any warning.
+
+    BUGS CORRECTED:
+       - from nazgul@alphalpha.com (Kee Hinckley): the xpm include files was
+       declaring XWritePixmapFile as taking in arg a Pixmap pointer instead
+       of a Pixmap.
+
+2.5            (90/10/17)
+
+    BUGS CORRECTED:
+       - XWritePixmapFile was not closing the file while ending normally.
+
+2.4            (90/09/06)
+
+    NEW FEATURES:
+       - XReadPixmapFile reads from a piped uncompress if the given filename
+       ends by .Z or if filename.Z exists,
+       - XWritePixmapFile writes to a piped compress if the given filename
+       ends by .Z.
+
+    BUGS CORRECTED:
+       - demo now deals with window manager.
+
+    CHANGES TO THE DOC:
+       - documentation about compressed files management.
+
+2.3            (90/08/30)
+
+    BUGS CORRECTED:
+       - handle monochrome display correctly,
+       - comments can be empty.
+
+2.2            (90/08/27)
+
+    BUGS CORRECTED:
+       - when reading some invalid free was dumping core on some machine.
+
+2.1            (90/08/24)
+
+    First distribution of XPM2.
+
diff --git a/COPYING b/COPYING
new file mode 100755 (executable)
index 0000000..af47549
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,70 @@
+Copyright (C) 1989-95 GROUPE BULL
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of GROUPE BULL shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from GROUPE BULL.
+
+Copyright (C) 1998 Arnaud LE HORS
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+Arnaud LE HORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Arnaud LE HORS shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from Arnaud LE HORS.
+
+Copyright (C) 19896 Lorens Younes
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of Lorens Younes shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from Lorens Younes.
+
+
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644 (file)
index 0000000..446fa4c
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+Arnaud LE HORS      BULL Research FRANCE -- Koala Project 
+                    (XPM - X PixMap format version 2 & 3)
+    Internet:       lehors@sophia.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
diff --git a/ChangeLog b/ChangeLog
new file mode 100755 (executable)
index 0000000..b94f5bd
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,787 @@
+commit 22a434d061af224536baee6c6110b603c5c96b2c
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date:   Fri Oct 29 17:29:25 2010 -0700
+
+    libXpm 3.5.9
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit c11f1bd18303139f070e1873382632ee80cd9878
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Oct 20 08:30:56 2010 -0400
+
+    config: remove obsolete FILES file from the Imakefile days
+    
+    It lists the files contained in the original
+    BULL Research Koala Project.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 0ea6c432a068fc4edf90c614e68a4f4be94edd14
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Sun Oct 17 12:51:15 2010 -0400
+
+    doc: move doc files to the newly created doc dir.
+    
+    As per guidelines for all xorg modules.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 7a3e69cfb079c7345f3d9b1217f373a706ba544c
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Oct 15 17:14:39 2010 -0400
+
+    config: provide a Makefile for the include directory
+    
+    Reduce some complexity in the src makefile as it should not
+    handle sibling directories.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit e50f645f4cc5bb1db0e025fc6e39c6e84a894c13
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Oct 15 14:56:32 2010 -0400
+
+    libXpm make: remove redundant -I.
+    
+    It is always included by Automake
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 8dee37ff3bb908d597d53f2b335fc2111643cce7
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Sun Oct 24 19:39:54 2010 -0400
+
+    sxpm make: no need to use a per target LDADD
+    
+    There is only one program in this makefile.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 34abbaaacddf1018d1805bc4890226ab200a50fb
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Oct 15 11:45:58 2010 -0400
+
+    sxpm make: remove redundant $(XMP_LIBS) linker flags
+    
+    SXPM_LIBS contains the complete list of dependencies.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit b818f5cf7f7d8240db2a94ebcc28603730760e48
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Oct 15 10:21:08 2010 -0400
+
+    src make: remove -I$(top_builddir)/include
+    
+    This directory does not exist, only object code is created
+    in "builddir".
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 78bca7e85b930593fefe85cc51b5e24f98de31d0
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 21:56:21 2010 -0400
+
+    config: fix warnings, m4 quoting and layout
+    
+    Fix some m4 quoting
+    Fix some autoconf warnings
+    Regroup statements per section
+    Add comments
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 8e47c819490331c01959332e067f06a382d9a14a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:35:47 2010 -0400
+
+    config: AC_OUTPUT with parms is deprecated, use AC_CONFIG_FILES
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit c6915d034fa3f72a9724816d2e3f5e8432ef9321
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:33:40 2010 -0400
+
+    config: AC_HELP_STRING is deprecated, use AS_HELP_STRING
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit e2fdf80a7f9feedacf67e46a8e577b2e6d415a5f
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:29:42 2010 -0400
+
+    config: remove unrequired AC_SUBST(XPM_CFLAGS)
+    
+    This macro is called by PKG_CHECK_MODULES
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 937d8c8cf82bd57e82152af3768bdbfc5de4316a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:28:43 2010 -0400
+
+    config: remove AC_PROG_CC as it overrides AC_PROG_C_C99
+    
+    XORG_STRICT_OPTION from XORG_DEFAULT_OPTIONS calls
+    AC_PROG_C_C99. This sets gcc with -std=gnu99.
+    If AC_PROG_CC macro is called afterwards, it resets CC to gcc.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 0ed9cb4546d0c65f08a9511736400c0f7fba982f
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:28:08 2010 -0400
+
+    config: remove unrequired AC_HEADER_STDC
+    
+    Autoconf says:
+    "This macro is obsolescent, as current systems have conforming
+    header files. New programs need not use this macro".
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit e99bce47294eab031fc733d695e3c9589b52aff8
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:25:00 2010 -0400
+
+    config: replace deprecated AM_CONFIG_HEADER with AC_CONFIG_HEADERS
+    
+    Regroup AC statements at the top.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 0b5e15c685d295262bf2307d65bee3a0b28e74f5
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:15:08 2010 -0400
+
+    sxpm: use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS
+    The value of MAN_SUBST is the same for all X.Org packages.
+    
+    Use the appropriate platform version of sed
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 262bb7e9426150f6c7b553d184c51d3884d04adf
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:11:43 2010 -0400
+
+    cxpm: use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS
+    The value of MAN_SUBST is the same for all X.Org packages.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit acd4856aac05a884376736196154842959803aa6
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:03:13 2010 -0400
+
+    config: use AC_PROG_INSTALL now supplied by XORG_DEFAULT_OPTIONS
+    
+    It depends on util-macros 1.8
+    The LT_AC_PROG_SED macro was never released by libtool.
+    Neither man makefile actually used $SED anyway.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit d1bd1fbc6d7f7b4817aca4fecd8ccfe80a1c2f03
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 14 20:02:30 2010 -0400
+
+    config: upgrade to util-macros 1.8 for additional man page support
+    
+    Use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS
+    The value of MAN_SUBST is the same for all X.Org packages.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 3b20344bf3c5ae7a8291041d4887dc8f23644d40
+Author: Colin Harrison <colin.harrison@virgin.net>
+Date:   Thu Oct 7 13:49:17 2010 +0200
+
+    Missing end comment in libXpm/src/parse.c
+    
+    CVS tag removal chopped too much out in this case...
+    
+    Signed-off-by: Julien Cristau <jcristau@debian.org>
+
+commit f8f0a68247b920052df0796a39ebcdc2e4161d05
+Author: Jesse Adkins <jesserayadkins@gmail.com>
+Date:   Tue Sep 28 13:30:03 2010 -0700
+
+    Purge cvs tags.
+    
+    Signed-off-by: Jesse Adkins <jesserayadkins@gmail.com>
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit d026662cce0808cf402e0d50932d90984a2ea1bb
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Apr 1 21:11:35 2010 -0400
+
+    config: update AC_PREREQ statement to 2.60
+    
+    Unrelated to the previous patches, the new value simply reflects
+    the reality that the minimum level for autoconf to configure
+    all x.org modules is 2.60 dated June 2006.
+    
+    ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit d4a7b15b3ed9e7cf94dbf64f929ae954bada9f60
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Apr 1 21:07:54 2010 -0400
+
+    config: update and relocate AX_DEFINE_DIR macro
+    
+    Remove deprecated acinclude.m4 macro container file
+    Use separate macro files as per autoconf recommendation
+    Use the latest version of the macro from GNU
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit e0920779d1227338e61aaab16458b9daad508c36
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Mar 29 14:53:49 2010 -0400
+
+    config: remove the pkgconfig pc.in file from EXTRA_DIST
+    
+    Automake always includes it in the tarball.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 34ebac912c6f1223a274ab2e4f0c12928d357ddd
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Jan 14 09:36:38 2010 -0500
+
+    COPYING: add missing copyright notices
+    
+    Refer to: amigax.c, cxpm.c
+    Copyright (C) 1998 Arnaud LE HORS
+    Copyright (C) 19896 Lorens Younes
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit dca7a9ccbdd4c85d84668c3a4bc14b0049f0c893
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Nov 27 20:56:04 2009 -0500
+
+    Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES
+    
+    Now that the INSTALL file is generated.
+    Allows running make maintainer-clean.
+
+commit af0d92b686c65f7ffb5556b74fd937b01719c535
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Oct 28 14:09:10 2009 -0400
+
+    INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206
+    
+    Add missing INSTALL file. Use standard GNU file on building tarball
+    README may have been updated
+    Remove AUTHORS file as it is empty and no content available yet.
+    Remove NEWS file as it is empty and no content available yet.
+
+commit 8bda9cdb6344c6cdf87237cb84c16c54a3ae84d8
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Oct 27 15:07:25 2009 -0400
+
+    Deploy the new XORG_DEFAULT_OPTIONS #24242
+    
+    This macro aggregate a number of existing macros that sets commmon
+    X.Org components configuration options. It shields the configuration file from
+    future changes.
+
+commit 089237b624722b141a9ba6888584ebcc5247b227
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Oct 26 22:08:43 2009 -0400
+
+    Makefile.am: ChangeLog not required: EXTRA_DIST or *CLEANFILES #24432
+    
+    ChangeLog filename is known to Automake and requires no further
+    coding in the makefile.
+
+commit 37e75b28f4d30a66e16cfe192a0612a335aa8d46
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 22 12:34:19 2009 -0400
+
+    .gitignore: use common defaults with custom section # 24239
+    
+    Using common defaults will reduce errors and maintenance.
+    Only the very small or inexistent custom section need periodic maintenance
+    when the structure of the component changes. Do not edit defaults.
+
+commit 68ae0e442ad57534c25566284ad049299a982d00
+Author: Jeremy Huddleston <jeremyhu@freedesktop.org>
+Date:   Wed Oct 21 12:47:25 2009 -0700
+
+    This is not a GNU project, so declare it foreign.
+    
+    On Wed, 2009-10-21 at 13:36 +1000, Peter Hutterer wrote:
+    > On Tue, Oct 20, 2009 at 08:23:55PM -0700, Jeremy Huddleston wrote:
+    > > I noticed an INSTALL file in xlsclients and libXvMC today, and it
+    > > was quite annoying to work around since 'autoreconf -fvi' replaces
+    > > it and git wants to commit it.  Should these files even be in git?
+    > > Can I nuke them for the betterment of humanity and since they get
+    > > created by autoreconf anyways?
+    >
+    > See https://bugs.freedesktop.org/show_bug.cgi?id=24206
+    
+    As an interim measure, replace AM_INIT_AUTOMAKE([dist-bzip2]) with
+    AM_INIT_AUTOMAKE([foreign dist-bzip2]). This will prevent the generation
+    of the INSTALL file. It is also part of the 24206 solution.
+    
+    Signed-off-by: Jeremy Huddleston <jeremyhu@freedesktop.org>
+
+commit 130b2fb0ea716143c63ba30856eecb351bc2af2a
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Oct 9 10:32:08 2009 -0700
+
+    libXpm 3.5.8
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit a195bd6d375c311b9bf6d7cce477f1d131425757
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Oct 8 21:29:45 2009 -0700
+
+    Migrate to xorg macros 1.3 & XORG_DEFAULT_OPTIONS
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit f4c43f70dff3cb9702fd62bc388353d02589e618
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Oct 8 20:27:49 2009 -0700
+
+    Replace AC_DEFINE_DIR with AX_DEFINE_DIR from Autoconf Archive
+
+commit d846316822ba8eb545d41140007ef98a7de9274e
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue May 19 01:34:19 2009 -0700
+
+    Update AC_DEFINE_DIR to latest version from Autoconf Archive
+
+commit 53f8b42f89214b85804ae9e64c49d1a9c2a7553d
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Feb 2 20:34:35 2009 -0800
+
+    Add README with pointers to mailing list, bugzilla & git repos
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit 6697e31fbb616656b7f34515a79454af394b500a
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Fri Jan 30 15:45:20 2009 -0200
+
+    Janitor: ansification, make distcheck, .gitignore
+    
+      The ansification code is minor edit of the patch (by me) at
+    https://bugs.freedesktop.org/show_bug.cgi?id=14727
+    as it would not apply cleanly anymore.
+
+commit 41e4e2de4d73d098d332ece0410e9f8fda4fe10d
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Oct 20 19:36:52 2008 -0700
+
+    X.Org Bug 17944: avoid gcc warning for libXpm
+    
+    <http://bugs.freedesktop.org/show_bug.cgi?id=17944>
+    
+    Avoid the gcc warning
+    cxpm/cxpm.c:102: warning: no previous prototype for 'ErrorMessage'
+
+commit 64323668c07b4768c57649f5ec7e2888265d1aeb
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Mar 9 08:57:47 2008 +0100
+
+    nuke RCS Ids
+
+commit 6ef45c37160079a9aa551adcd841abdb55eabae3
+Author: Benjamin Close <Benjamin.Close@clearchain.com>
+Date:   Thu Jan 31 14:42:41 2008 +1030
+
+    Use libtools SED check rather than autoconf's SED check.
+    AC_PROG_SED required autoconf 2.60, libtool's should work
+    regardless. This keeps us supporting 2.57 of autoconf
+    
+    Found by: Tinderbox (1.4.1 compile)
+
+commit 3f7624048aa6064c69e2320a70fb7fc89e0bb7ef
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Jan 24 14:26:34 2008 -0800
+
+    Bug 14171: sxpm/Makefile.am:21: SED was already defined
+    
+    <http://bugs.freedesktop.org/show_bug.cgi?id=14171>
+
+commit 503843fd3066031adbd4a362c686acc721787b7d
+Author: James Cloos <cloos@jhcloos.com>
+Date:   Thu Dec 6 16:38:36 2007 -0500
+
+    Replace static ChangeLog with dist-hook to generate from git log
+
+commit 3e37dd39b6169af9928d5b959c40ba79a07450ee
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Aug 22 13:23:30 2007 -0700
+
+    Version bump: 3.5.7
+
+commit d82244497b54889f91c78585374d1ad6a0cef2cf
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Aug 22 13:08:42 2007 -0700
+
+    Replace strcpy with strncpy to match previous code block
+
+commit 47c974872b51b8c1d6965eff4599f8ce739bcedc
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Aug 6 14:22:48 2007 -0700
+
+    Use srcdir in paths passed to xgettext when making .po files
+
+commit 6e003fd5f174a8e312d799d7f8812c2a5b87e433
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Aug 6 12:59:04 2007 -0700
+
+    Replace index/rindex with C89 standard strchr/strrchr
+
+commit 43dfc6be8128139888426d8c709aa78efc207953
+Author: Jason Rumney <jasonr@gnu.org>
+Date:   Mon Aug 6 12:52:52 2007 -0700
+
+    X.Org Bug #11863: Build libXpm on MS Windows (with MinGW)
+    
+        * src/XpmI.h [FOR_MSW]: Include simx.h instead of real X headers.
+    
+        * src/simx.h (_XFUNCPROTOBEGIN, _XFUNCPROTOEND, NO_ZPIPE): Define.
+        (XAllocColor): Fix arg list in prototype.
+        (bzero, close, fdopen, index, rindex, open, strdup, O_RDONLY):
+        Map to W32 equivalents.
+    
+        * src/RdFToI.c [FOR_MSW]: Include fcntl.h.
+
+commit 290f0b9115428dab0cbf2880d154468c557b3e7e
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Jul 25 17:45:15 2007 -0700
+
+    Include comment/copyright/license for AC_DEFINE_DIR in acinclude.m4
+
+commit d4bc7dc0dea218cea380aba972f10f60dc1e86ac
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Jun 27 13:54:07 2007 -0700
+
+    Use AM_CFLAGS & AM_CPPFLAGS to replace per-program and obsolete macros
+    
+    Clears some warnings from automake-1.10
+
+commit 85a87de3c03ca8be526dedc0a2973f9426518c39
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Nov 21 17:12:18 2006 -0800
+
+    Sun bug 4486226: Xpm is not internationalized
+    
+    <http://bugs.opensolaris.org/bugdatabase/view_bug.do?bug_id=4486226>
+    Use gettext() to allow translated messages in sxpm & cxpm
+    (cherry picked from bcda4f17ab3fa9f0572f876dbeb09b45fbc23f3d commit)
+
+commit 3c881daddcc251d6e806715d267e4e55934abd1a
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Nov 21 15:13:44 2006 -0800
+
+    Add *~ to .gitignore to skip over emacs/patch droppings
+
+commit 60817dd28774540622ea404f650db8389c66da54
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Fri Oct 13 16:23:49 2006 -0400
+
+    Bump to 3.5.6
+
+commit 12dc4dc15234ae818a21c20ebf7b2d053b7a94be
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Jul 13 14:59:03 2006 -0700
+
+    renamed: .cvsignore -> .gitignore
+
+commit 4daea919c3aa104b6caf8c0f42f49ae755545986
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Jun 3 06:11:30 2006 +0000
+
+    Always initialize atomTable to NULL, so xpmHashTableFree() doesn't try to
+        free a random value from the stack if xpmHashTableInit returns an
+        error.
+
+commit 19855d6e09aa36db7686ad6f538179bf87e9c6ea
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Fri Jun 2 19:48:01 2006 +0000
+
+    Coverity #1432: Returned without freeing storage "hints_cmt" (in error case
+        when xpmHashTableInit failed)
+
+commit 000abcd371d0c4b1d0a5380023d74bf5bfc47685
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Fri Jun 2 19:33:29 2006 +0000
+
+    Coverity #1415: Returned without freeing storage "hints_cmt" (in error case
+        when xpmHashTableInit failed)
+
+commit 5c70c99833d4040aaf595d0005b861e0a930ee66
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Thu Apr 27 00:19:37 2006 +0000
+
+    Bump to 3.5.5
+
+commit 2dcc187c92c1a579e6e9f0bad999a3b4e47228c3
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sat Mar 18 15:18:56 2006 +0000
+
+    doublecheck that a pointer is not NULL before dereferencing it. (Coverity
+        CID 121).
+
+commit 93421a53ccf159ff39bc9f8ff72c57246f9cb90c
+Author: Kevin E Martin <kem@kem.org>
+Date:   Thu Dec 15 00:24:31 2005 +0000
+
+    Update package version number for final X11R7 release candidate.
+
+commit 2b229ddcb52a3bf9bef32e764f93cc57c1351420
+Author: Kevin E Martin <kem@kem.org>
+Date:   Tue Dec 6 22:48:44 2005 +0000
+
+    Change *man_SOURCES ==> *man_PRE to fix autotools warnings.
+
+commit 50214deb692a9af760088f8e7a51955c7d3f1707
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Dec 3 05:49:44 2005 +0000
+
+    Update package version number for X11R7 RC3 release.
+
+commit 19881d3c88ff0713ef550382fd0dfb03123dabed
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Mon Nov 28 22:03:06 2005 +0000
+
+    Change *mandir targets to use new *_MAN_DIR variables set by xorg-macros.m4
+        update to fix bug #5167 (Linux prefers *.1x man pages in man1 subdir)
+
+commit a6fbdb403efd3bf7e1179660959fd0e66a301ce0
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Nov 19 07:15:42 2005 +0000
+
+    Update pkgconfig files to separate library build-time dependencies from
+        application build-time dependencies, and update package deps to work
+        with separate build roots.
+
+commit 82513d04a8381da8d2281d7581f6b0d65901aede
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sun Nov 13 02:08:07 2005 +0000
+
+    Use sed to substitute variables in man pages
+
+commit d1b430289b2ddb6c1f3383c5288aa125b058508a
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Nov 9 21:19:13 2005 +0000
+
+    Update package version number for X11R7 RC2 release.
+
+commit e2c9276ccc1ef619dcfbdeb414ef0dec5113c1ee
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Oct 29 02:26:49 2005 +0000
+
+    Add --enable-stat-zfile (on by default) to replace Imake's ZFILEDEF =
+        -DSTAT_ZFILE to enable automatically searching for file.xpm.Z &
+        file.xpm.gz when file.xpm is requested.
+
+commit 2f57ab95012d9221cca1af6c0a1ccea5d308c66f
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Oct 19 02:48:11 2005 +0000
+
+    Update package version number for RC1 release.
+
+commit 72bf88ed120fb888c57ed3223faa316403031b36
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Oct 5 20:24:14 2005 +0000
+
+    Add missing files to EXTRA_DIST
+    Fix man page installation
+
+commit 08c43c5f1f851c1acad360a28767670dc62d8a66
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Mon Oct 3 19:53:58 2005 +0000
+
+    Last argument of variable parameter list needs to be casted to a pointer
+        type.
+
+commit 5ecad7c12c3104d653972385f548e3f86532cbe3
+Author: Kevin E Martin <kem@kem.org>
+Date:   Fri Jul 29 21:22:52 2005 +0000
+
+    Various changes preparing packages for RC0:
+    - Verify and update package version numbers as needed
+    - Implement versioning scheme
+    - Change bug address to point to bugzilla bug entry form
+    - Disable loadable i18n in libX11 by default (use --enable-loadable-i18n to
+        reenable it)
+    - Fix makedepend to use pkgconfig and pass distcheck
+    - Update build script to build macros first
+    - Update modular Xorg version
+
+commit 703207d3b3718223d4b2711fb77fc96a4f3909ef
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Jul 17 10:32:57 2005 +0000
+
+    fix build outside of $(srcdir)
+
+commit 5a0177d4474787951c0cae56e285bb075ab405f3
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Jul 16 21:11:25 2005 +0000
+
+    Accept autoconf HAVE_STRLCPY as alias for HAS_STRLCAT
+
+commit fd38ee667976855150d3c1231a1acc2cf1a89330
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Jul 16 21:10:44 2005 +0000
+
+    Check for strlcat() for use in parse.c
+
+commit 9b3eed6e4f7ee542149ecec0d017a3a460f7c084
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Jul 16 07:23:39 2005 +0000
+
+    Set soversion to 4.11.0 with -version-number.
+
+commit a705a1cd9dc4c4ba1940c9b59d2107ba59360e39
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 06:45:44 2005 +0000
+
+    Add .cvsignore files
+
+commit b1d84a9fc9b15232c09b6ce5d96c097fdd4f0a15
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Thu Jun 9 13:42:36 2005 +0000
+
+    Use $(top_srcdir)/src instead of $(top_builddir)/src in INCLUDES
+
+commit 769751fba3e32f49272d19799929e1ad5a3d2cd0
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Thu May 19 17:09:13 2005 +0000
+
+    Add $(top_builddir)/include to INCLUDES
+
+commit 2cc1896c61eef5739bb6a8ffa89e58ba5c175a05
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Thu May 19 15:02:48 2005 +0000
+
+    - Add build system for lib/Xpm
+    - Add Xpm to symlink.sh
+    - Conditionally include config.h in xc/extras/Xpm
+
+commit cf0d69c7ace679f27f105c582760b9be14923aba
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Thu May 19 14:37:53 2005 +0000
+
+    Thu May 19 10:36:54 2005 Søren Sandmann <sandmann@redhat.com>
+    Add "../lib" to INCLUDES.
+    Replace #include "../lib/foo" with #include "foo".
+
+commit 639b3598cd0e7214010248efb62b75ef85a8e5c5
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Mon Feb 21 20:52:32 2005 +0000
+
+    Avoid inifite loops. From Chris Gilbert in bug #1920.
+
+commit f1908d7ee5e2d2d44db2116b3c88213da9dfb854
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sat Dec 11 16:14:05 2004 +0000
+
+    Fix incomplete merge.
+
+commit b041980732f6a6002001cfe079fdfb982937d4a8
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sat Dec 11 16:08:59 2004 +0000
+
+    more s_open() cleanup.
+
+commit 90d0638a42553786f54df333f0da4d008e9a0573
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sat Dec 11 16:04:34 2004 +0000
+
+    Replace s_popen() by a more specific function that allows only one command
+        in the pipe. Remove extraneous tests on file names that broke some
+        applications. From Alex Reisen in Bugzilla #1920.
+
+commit 2c23dbf2cafaad72b1f45da915eb87a8f792fdb0
+Author: Roland Mainz <roland.mainz@nrubsig.org>
+Date:   Wed Dec 8 01:16:48 2004 +0000
+
+    //bugs.freedesktop.org/show_bug.cgi?id=830): Fix libXpm header (xpm.h) to
+        use the X11 function begin/end marker macros (_XFUNCPROTOBEGIN,
+        _XFUNCPROTOEND) instead of homegrown (native) C++ code. Patch by Kevin
+        DeKorte <kdekorte@yahoo.com>.
+
+commit 50986a34f231fbc7a4b62466bd89bd4ae4027d2e
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Thu Nov 25 21:19:11 2004 +0000
+
+    Fixes for CAN-2004-0914 (Thomas Biege).
+
+commit a983dafac59dcb425666a5a5556da4734e50c6c5
+Author: Egbert Eich <eich@suse.de>
+Date:   Tue Sep 21 17:57:35 2004 +0000
+
+    Merged over libXpm security fix provided by Chris Evans, Matthieu Herrb and
+        Alan Coopersmith from release 6.8.1.
+    Fail during initialization with error if font/fontset is not set for
+        widget. This prevents a sig11 later when the non-existent font/fontset
+        structs are referenced.
+    Check if xf86Info.kbdProc pointer is really set before calling it on abort
+        as this pointer won't be set if the new modular keyboard driver is used
+        (Matthias Hopf).
+    Added new libs to the bindist control files.
+    Removed inclusion of unnecessary kernel header on Linux. This may fail in
+        an -ansi environment.
+
+commit 2773a7214e282f6f673483f5233b880505947c3f
+Author: Egbert Eich <eich@suse.de>
+Date:   Fri Apr 23 18:42:32 2004 +0000
+
+    Merging XORG-CURRENT into trunk
+
+commit 65c64a2eaa8698434f1869dcdcb5d9ccb21c6932
+Author: Egbert Eich <eich@suse.de>
+Date:   Sun Mar 14 08:28:26 2004 +0000
+
+    Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004
+
+commit 0b313707a677523fed9ac485445e8b09d2a85c13
+Author: Egbert Eich <eich@suse.de>
+Date:   Wed Mar 3 12:09:53 2004 +0000
+
+    Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004
+
+commit 658f8e9a9094ba5d18743694cad7275be53c7a25
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 13:34:33 2004 +0000
+
+    readding XFree86's cvs IDs
+
+commit 9971f91864e8f722b42c58f2ff19025715f33b98
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 09:21:31 2004 +0000
+
+    Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
+
+commit fbfe965054d8144946651b19085684af7f6715b9
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Tue Nov 25 19:27:16 2003 +0000
+
+    XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks
+
+commit c037348b5df0ac94ad4daba59f8bc9acf12ef623
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:24 2003 +0000
+
+    XFree86 4.3.0.1
+
+commit aafaabc4a0bfab6544e085ee504ad69de4a5ddb1
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:24 2003 +0000
+
+    Initial revision
diff --git a/FAQ.html b/FAQ.html
new file mode 100644 (file)
index 0000000..18d4ee6
--- /dev/null
+++ b/FAQ.html
@@ -0,0 +1,344 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html lang="en">
+<HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<TITLE>FAQ XPM</TITLE>
+</HEAD>
+
+<body>
+<h1 align="center">The XPM<br>
+Frequently Asked Questions</h1>
+<p>
+This article contains the answers to some Frequently Asked Questions about the
+XPM format and/or library. If you don't find the answer to your problem here,
+then you can mail either to lehors@sophia.inria.fr or to the mailing list
+xpm-talk@sophia.inria.fr.
+
+
+<h2>Contents</h2>
+
+<ol>
+<li><a href="#Q1">How do I convert my images to or from XPM ?</a>
+<li><a href="#Q2">Why are my XPM files said to be invalid ?</a>
+<li><a href="#Q3">Why does my program core dumps using XPM ?</a>
+<li><a href="#Q4">Why does my program core dumps using XPM with a widget ?</a>
+<li><a href="#Q5">How can I get a non rectangular icon using XPM ?</a>
+<li><a href="#Q6">What exactly triggers the creation of a mask when using XPM ?</a>
+<li><a href="#Q7">How should I use the mask ?</a>
+<li><a href="#Q8">Is there a string to pixmap converter somewhere ?</a>
+<li><a href="#Q9">How can I edit XPM icons ?</a>
+<li><a href="#Q10">Is there a collection of icons somewhere ?</a>
+<li><a href="#Q11">The documentation fails to print out. Why ?</a>
+<li><a href="#copy">Copyright</a>
+</ol>
+
+
+<h2><a name="Q1">1. How do I convert my images to or from XPM ?</a></h2>
+<p>
+  Netpbm is surely the best image conversion package that I know of. It defines
+  formats for color, gray and monochrome images and provides a set of filters.
+  Thus a GIF image can be converted to XPM with something like:
+<p>
+  $ giftoppm youricon.gif | ppmtoxpm > youricon.xpm
+<p>
+  The latest release can be found at least from wuarchive.wustl.edu
+  (128.252.135.4), directory /graphics/graphics/packages/NetPBM
+
+
+<h2><a name="Q2">2. Why are my XPM files said to be invalid ?</a></h2>
+<p>
+  There are three official versions of the XPM format. The XPM library since
+  version 3.3 can read all them but writes out only XPM 3. Also the small
+  program called sxpm which is part of the XPM library package can be used to
+  automatically translate XPM 1 and 2 files to XPM 3 with a command such as:
+<p>
+  $ sxpm -nod yourxpm1or2file -o yourxpm3file
+<p>
+  Also, the XPM format defines "None" to be the color name meaning
+  "transparent", but IXI used to hack the XPM library in its early days to
+  handle transparency as "#Transparent". This makes IXI format not compatible
+  with the official XPM format, and so not readable neither by the official XPM
+  library nor any of the programs built on top of it.
+<p>
+  The only solutions are either to stick on IXI programs which can deal with
+  their format or convert your files to the standard XPM format. This can be
+  done simply by changing "#Transparent" to "None".
+
+
+<h2><a name="Q3">3. Why does my program core dumps using XPM ?</a></h2>
+<p>
+  Be sure the XpmAttributes structure you pass by reference has a valid
+  valuemask. You can give NULL instead if you don't want to use an
+  XpmAttributes but if you do, you MUST initialize its valuemask component to
+  some valid value, at least 0, otherwise unpredictable errors can occur.
+<p>
+  So instead of doing something like:
+<pre>
+      XpmAttributes attrib;
+
+      XpmReadFileToPixmap(dpy, d, filename, &amp;pixmap, &amp;mask, &amp;attrib);
+</pre>
+<p>
+  you should do:
+<pre>
+      XpmAttributes attrib;
+
+      attrib.valuemask = 0;
+      XpmReadFileToPixmap(dpy, d, filename, &amp;pixmap, &amp;mask, &amp;attrib);
+</pre>
+
+
+<h2><a name="Q4">4. Why does my program core dumps using XPM with a widget ?</a></h2>
+<ul>
+<li>First the XPM library is Xlib level, so don't pass your widget as a
+    Drawable parameter. A Drawable is either a Window or a Pixmap. The widget's
+    window can do the job but:
+
+<li>Then a widget only gets a Window when realized, so passing XtWindow(widget)
+    with a not yet realized widget is wrong. Either realize you widget first or
+    use another window. Since the Drawable parameter is only used to specify
+    the screen to which the pixmap must be created on, most of the time the
+    default root window is just fine.
+</ul>
+
+
+<h2><a name="Q5">5. How can I get a non rectangular icon using XPM ?</a></h2>
+<p>
+  The X Window System does not support transparent color. However there are
+  several ways you can use to get the same visual effect using XPM:
+<ul>
+<li>First you can use the None color to get a shape mask and use it as
+    explained below (question 7).
+
+<li>Second you can define a symbolic color name such as "mask" in the XPM
+    format file, then use the color overriding mechanism to set this symbolic
+    color to the color of the underlying object. Note that in this case the XPM
+    library won't create a shape mask, and that if the color of the underlying
+    object is changed then you'll have to create a new pixmap.
+</ul>
+
+
+<h2><a name="Q6">6. What exactly triggers the creation of a mask when using XPM ?</a></h2>
+<p>
+  Basically a mask is created if "None" is used as one of the color of the
+  pixmap. Be aware that this is not only true if it is used in the XPM of the
+  pixmap since the colors can be overridden at load time. So a mask is created
+  if the "None" color is used at load time, coming either from the XPM
+  definition or the color overriding.
+
+
+<h2><a name="Q7">7. How should I use the mask ?</a></h2>
+<p>
+  There are basically two ways of using the mask:
+<ul>
+<li>Use the mask as a shapemask with the X11 Nonrectangular Saphe Window
+    Extension. Typically this is what should be done when the icon is used in a
+    desktop.
+
+<li>Use the mask as a clipmask in the GC you pass to XCopyArea when drawing the
+    pixmap. So the "transparent" pixels being not actually drawn will get the
+    underlying pixels colors.
+</ul>
+
+
+<h2><a name="Q8">8. Is there a string to pixmap converter for Motif ?</a></h2>
+<p>
+ Yes, Motif 2.0 or later does support XPM pixmaps as well as XBM bitmaps.
+
+
+<h2><a name="Q9">9. How can I edit XPM icons ?</a></h2>
+<p>
+  As listed below several editors either commercial or not are supporting the
+  XPM format. However, pixmap is the one I would recommend since it is freely
+  available and, being fully dedicated to XPM, it allows to edit all the
+  special things, such as the symbolic color names, which makes XPM different
+  from all the other image formats. Pixmap can always be found by ftp from
+  ftp.x.org (contrib) and avahi.inria.fr (pub/pixmap).
+<p>
+Last Update: 3 August 1994
+<table border=1>
+<caption>XPM Icon Editors</caption>
+<tr><th>Program<th>Infos<th>Source/Author<th>Platforms<th>SA<th>XPM<th>cost
+<tr><td>pixmap<td><ul>
+   <li><a href="ftp://ftp.x.org/contrib/application/pixmap/pixmap2.6.tar.gz">ftp://ftp.x.org/contrib/application/pixmap/pixmap2.6.tar.gz</a>
+   <li>requires 3.4 or higher revision of Xpm lib.
+   <li>supports all XPM format features
+   <li>current version doesn't work on 24-plane displays
+</ul>
+<td>Lionel Mallet<td>source<td>yes<td>3<td>NC
+
+<tr><td>pixt<td><ul>
+   <li><a href="ftp://ftp.x.org/contrib/pixt.tar.Z">ftp://ftp.x.org/contrib/pixt.tar.Z</a>
+   <li>doesn't work on 24-plane displays
+   <li>last updated November 1991
+</ul>
+<td>J. Michael Flanery<td>source<td>yes<td>1<td>NC
+
+<tr><td>pixed<td><ul>
+   <li>part of X.desktop
+   <li>current version doesn't work on 24-plane displays
+</ul>
+<td>IXI<td>Many UNIX<td>no<td>3<td>N/A
+
+<tr><td>olpixmap<td><ul>
+   <li>packaged with the OLIT (OpenLook) toolkit
+</ul>
+<td>USL<td>Sun, SVR4.2, UnixWare<td>no<td>1<td>N/A
+
+<tr><td>xfedor<td><ul>
+   <li>only uses XLIB
+   <li>doesn't work on 24-plane displays
+</ul>
+<td>Daniel Dardailler<td>source<td>yes<td>3<td>NC
+
+<tr><td>SCOpaint<td><ul>
+   <li>included with the ODT package
+</ul>
+<td>SCO/Wing Eng<td>ODT<td>yes<td>2.8<td>N/A
+
+<tr><td>pme.icn<td><ul>
+   <li>written in the Icon language
+</ul>
+<td>Icon Project<td>source<td>yes<td>3<td>NC
+
+<tr><td>PixEditT<td><ul>
+   <li>there is currently no support for editing the colormap
+</ul>
+<td>Free Widget Foundation<td>source<td>yes<td>3<td>NC
+
+<tr><td>xscribble<td><ul>
+   <li>requires the FWF, 8-bit pseudocolor
+   <li><a href="ftp://ftp.cis.ufl.edu/pub/thoth">ftp://ftp.cis.ufl.edu/pub/thoth</a>
+   <li>Alpha version (last updated April 1993)
+</ul>
+<td>Robert Forsman<td>source<td>yes<td>?<td>NC
+
+<tr><td>vueicon<td><ul>
+   <li>included with Vue3.0
+</ul>
+<td>Hewlett-Packard<td>HP<td>yes<td>3<td>N/A
+
+<tr><td>iconedit V3<td>&nbsp;<td>SunSoft<td>Sparc/Sun3<td>yes<td>2<td>N/A
+
+<tr><td>Pixmap Editor<td><ul>
+   <li>this is a Widget, not a complete program
+</ul>
+<td>ICS<td>?<td>yes<td>?<td>?
+
+<tr><td>ezX<td>&nbsp;<td>Sunrise Softwarey<td>?<td>?<td>?<td>N/A
+
+<tr><td>XPaint<td><ul>
+     <li>full featured, works on all displays
+     <li>current release is 2.1.1 (last update January 1994)
+</ul>
+<td>David Koblas<td>source<td>yes<td>3<td>NC
+
+<tr><td>Phoenix<td><ul>
+    <li>full featured, 24-bit painting program, requires Motif.
+    <li><a href="ftp://nic.funet.fi/pub/graphics/packages/phoenix">ftp://nic.funet.fi/pub/graphics/packages/phoenix</a>
+    <li>Beta version (last updated September 1993)
+</ul>
+<td>ohtcolor@niksula.hut.fi<td>source<td>yes<td>3<td>NC
+
+<tr><td>pixed<td><ul>
+    <li>pixed is part of the TeleUSE UIMS
+    <li>More info is available from service@ignite.alsys.com
+</ul>
+<td>Alsys<td>Many UNIX<td>yes<td>3<td>N/A
+
+<tr><td>display<td><ul>
+   <li><a href="ftp://ftp.x.org/contrib/application/ImageMagick/ImageMagick-3.2.tar.gz">ftp://ftp.x.org/contrib/application/ImageMagick/ImageMagick-3.2.tar.gz</a>
+   <li>lots of image conversion and manipulation features
+</ul>
+<td>John Cristy<td>source<td>yes<td>3<td>NC
+</table>
+
+<p>
+SA - Stand Alone program<br>
+NC - No Charge (i.e. free); most programs are copyrighted.<br>
+XPM - XPM format supported<br>
+source - built from source code; likely works on all standard X platforms<br>
+N/A - icon editor is normally distributed with other software
+
+<p>
+Send updates, additions, corrections, etc. to <a
+href="mailto:dan@bristol.com">dan@bristol.com</a>
+
+
+<h2><a name="Q10">10. Is there a collection of icons somewhere ?</a></h2>
+<p>
+  At least there is one freely available: Anthony's X Icon Library. You can
+  found it on several ftp servers, such as <a href="ftp://server.berkeley.edu/pub/AIcons">server.berkeley.edu/pub/AIcons</a>. It
+  contains only small icons (less than about 100x100 pixels in size) which are
+  stored in groups in a logical way. Color icons are stored in XPM format and
+  Black & White icons in XBM.
+
+
+<h2><a name="Q11">11. The documentation fails to print out. Why ?</a></h2>
+<p>
+  The PostScript documentation file is formatted for US letter paper. Frame
+  Maker tries very hard to ensure that you have the right paper and punts if
+  you don't. However, you can easily work around this problem by applying the
+  following patch. If for some reason applying the patch fails, you can still
+  do it by hand. Just locate the corresponding block in the PS file and remove
+  the lines with a leading '-' character.
+  By the way, this applies to any doc generated by Frame Maker. The
+  corresponding block might be slightly different depending on which version of
+  Frame Maker was used, but it is still easy to locate.
+
+<pre>
+*** xpm.PS      Wed Sep 11 15:47:43 1996
+--- xpm-A4.PS   Thu Nov 21 09:27:28 1996
+***************
+*** 647,668 ****
+        0 ne /edown exch def 
+        /yscale exch def
+        /xscale exch def
+-       FMLevel1 {
+-               manualfeed {setmanualfeed} if
+-               /FMdicttop countdictstack 1 add def 
+-               /FMoptop count def 
+-               setpapername 
+-               manualfeed {true} {papersize} ifelse 
+-               {manualpapersize} {false} ifelse 
+-               {desperatepapersize} {false} ifelse 
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-               count -1 FMoptop {pop pop} for
+-               countdictstack -1 FMdicttop {pop end} for 
+-               }
+-               {{1 dict dup /PageSize [paperwidth paperheight]put setpagedevice}stopped
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-                {1 dict dup /ManualFeed manualfeed put setpagedevice } stopped pop }
+-       ifelse 
+        
+        FMPColor {
+                currentcolorscreen
+--- 647,652 ----
+</pre>
+
+
+<hr>
+<h2><a name="copy">Copyright (C) 1989-95 GROUPE BULL</a></h2>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+<p>
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+<p>
+Except as contained in this notice, the name of GROUPE BULL shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from GROUPE BULL.
+</body>
+</html>
diff --git a/FILES b/FILES
new file mode 100644 (file)
index 0000000..e1bf3fa
--- /dev/null
+++ b/FILES
@@ -0,0 +1,68 @@
+CHANGES
+COPYRIGHT
+FAQ.html
+FILES
+Imakefile
+Makefile.noX
+README.html
+README.AMIGA
+README.MSW
+namecvt
+lib
+lib/Imakefile
+lib/Makefile.noX
+lib/Makefile.AmigaGCC
+lib/Smakefile
+lib/Attrib.c
+lib/CrBufFrI.c
+lib/CrBufFrP.c
+lib/CrDatFrI.c
+lib/CrDatFrP.c
+lib/CrIFrBuf.c
+lib/CrIFrDat.c
+lib/CrIFrP.c
+lib/CrPFrBuf.c
+lib/CrPFrDat.c
+lib/CrPFrI.c
+lib/Image.c
+lib/Info.c
+lib/RdFToBuf.c
+lib/RdFToDat.c
+lib/RdFToI.c
+lib/RdFToP.c
+lib/WrFFrBuf.c
+lib/WrFFrDat.c
+lib/WrFFrI.c
+lib/WrFFrP.c
+lib/amigax.h
+lib/amigax.c
+lib/create.c
+lib/data.c
+lib/descrip.mms
+lib/hashtab.c
+lib/make.com
+lib/misc.c
+lib/parse.c
+lib/rgb.c
+lib/rgbtab.h
+lib/scan.c
+lib/simx.h
+lib/simx.c
+lib/xpm.h
+lib/XpmI.h
+lib/Xpm-def.cpp
+doc
+doc/xpm.PS
+sxpm
+sxpm/Imakefile
+sxpm/Makefile.noX
+sxpm/plaid.xpm
+sxpm/plaid_ext.xpm
+sxpm/plaid_mask.xpm
+sxpm/sxpm.c
+sxpm/sxpm.man
+cxpm
+cxpm/Imakefile
+cxpm/Makefile.noX
+cxpm/cxpm.c
+cxpm/cxpm.man
diff --git a/Makefile.am b/Makefile.am
new file mode 100755 (executable)
index 0000000..a289a24
--- /dev/null
@@ -0,0 +1,23 @@
+# Daniel Stone disowns all copyright on this file; no warranty is given as to its
+# suitability or otherwise.
+
+SUBDIRS = doc include src sxpm cxpm
+
+ACLOCAL_AMFLAGS = -I m4
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xpm.pc
+
+EXTRA_DIST = COPYRIGHT NEWS.old
+
+MAINTAINERCLEANFILES = ChangeLog INSTALL
+
+.PHONY: ChangeLog INSTALL
+
+INSTALL:
+       $(INSTALL_CMD)
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog INSTALL
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..9d14a39
--- /dev/null
+++ b/README
@@ -0,0 +1,25 @@
+libXpm - X Pixmap (XPM) image file format library
+
+All questions regarding this software should be directed at the
+Xorg mailing list:
+
+        http://lists.freedesktop.org/mailman/listinfo/xorg
+
+Please submit bug reports to the Xorg bugzilla:
+
+        https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+
+The master development code repository can be found at:
+
+        git://anongit.freedesktop.org/git/xorg/lib/libXpm
+
+        http://cgit.freedesktop.org/xorg/lib/libXpm
+
+For patch submission instructions, see:
+
+       http://www.x.org/wiki/Development/Documentation/SubmittingPatches
+
+For more information on the git code manager, see:
+
+        http://wiki.x.org/wiki/GitPage
+
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644 (file)
index 0000000..b7501e8
--- /dev/null
@@ -0,0 +1,46 @@
+# ===========================================================================
+#          http://www.nongnu.org/autoconf-archive/ax_define_dir.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
+#
+# DESCRIPTION
+#
+#   This macro sets VARNAME to the expansion of the DIR variable, taking
+#   care of fixing up ${prefix} and such.
+#
+#   VARNAME is then offered as both an output variable and a C preprocessor
+#   symbol.
+#
+#   Example:
+#
+#      AX_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Stepan Kasal <kasal@ucw.cz>
+#   Copyright (c) 2008 Andreas Schwab <schwab@suse.de>
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2008 Alexandre Oliva
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.
+
+AU_ALIAS([AC_DEFINE_DIR], [AX_DEFINE_DIR])
+AC_DEFUN([AX_DEFINE_DIR], [
+  prefix_NONE=
+  exec_prefix_NONE=
+  test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+  test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
+dnl refers to ${prefix}.  Thus we have to use `eval' twice.
+  eval ax_define_dir="\"[$]$2\""
+  eval ax_define_dir="\"$ax_define_dir\""
+  AC_SUBST($1, "$ax_define_dir")
+  AC_DEFINE_UNQUOTED($1, "$ax_define_dir", [$3])
+  test "$prefix_NONE" && prefix=NONE
+  test "$exec_prefix_NONE" && exec_prefix=NONE
+])
diff --git a/autogen.sh b/autogen.sh
new file mode 100644 (file)
index 0000000..904cd67
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..057c056
--- /dev/null
@@ -0,0 +1,69 @@
+# Initialize Autoconf
+AC_PREREQ([2.60])
+AC_INIT([libXpm],
+        [3.5.9],
+        [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
+        [libXpm])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_HEADERS([config.h])
+
+# Initialize Automake
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AM_MAINTAINER_MODE
+
+# Initialize libtool
+AC_PROG_LIBTOOL
+
+# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS
+m4_ifndef([XORG_MACROS_VERSION],
+          [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.8)
+XORG_DEFAULT_OPTIONS
+
+# Checks for library functions
+AC_CHECK_FUNCS([strlcat])
+
+# Obtain compiler/linker options for dependencies
+PKG_CHECK_MODULES(XPM, xproto x11)
+PKG_CHECK_MODULES(SXPM, xt xext xextproto, build_sxpm=true, build_sxpm=false)
+AM_CONDITIONAL(BUILD_SXPM, test x$build_sxpm = xtrue)
+
+# Internationalization & localization support
+AC_SEARCH_LIBS([gettext], [intl], [USE_GETTEXT="yes"], [USE_GETTEXT="no"])
+AC_MSG_CHECKING([where to install localized messages])
+AC_ARG_WITH([localedir], AS_HELP_STRING([--with-localedir=<path>],
+       [Path to install message files in (default: datadir/locale)]),
+       [LOCALEDIR=${withval}], [LOCALEDIR=${datadir}/locale])
+AX_DEFINE_DIR([LOCALEDIR], [LOCALEDIR], [Location of translated messages])
+if test "x$LOCALEDIR" = "xno" -o "x$USE_GETTEXT" = "xno" ; then
+       AC_MSG_RESULT([nowhere])
+       USE_GETTEXT="no"
+else
+       AC_MSG_RESULT([$LOCALEDIR])
+fi
+
+if test "x$USE_GETTEXT" = "xyes" ; then
+       AC_DEFINE([USE_GETTEXT], 1, 
+                 [Define to 1 if you want to use the gettext() function.])
+fi
+AM_CONDITIONAL(USE_GETTEXT, test "x$USE_GETTEXT" = "xyes")
+
+# Optional feature: When ___.xpm is requested, also look for ___.xpm.Z & .gz
+# Replaces ZFILEDEF = -DSTAT_ZFILE in old Imakefile
+AC_ARG_ENABLE(stat-zfile,
+       AS_HELP_STRING([--enable-stat-zfile],
+                       [Search for files with .Z & .gz extensions automatically @<:@default=yes@:>@]),
+              [STAT_ZFILE=$enableval], [STAT_ZFILE=yes])
+if test x$STAT_ZFILE = xyes ; then
+       AC_DEFINE(STAT_ZFILE, 1, [Define to 1 to automatically look for files with .Z & .gz extensions])
+fi
+
+AC_CONFIG_FILES([Makefile
+                 doc/Makefile
+                 include/Makefile
+                 src/Makefile
+                 sxpm/Makefile
+                 cxpm/Makefile
+                 xpm.pc])
+AC_OUTPUT
diff --git a/cxpm/Makefile.am b/cxpm/Makefile.am
new file mode 100755 (executable)
index 0000000..e7481a0
--- /dev/null
@@ -0,0 +1,30 @@
+bin_PROGRAMS = cxpm
+
+AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include/X11
+AM_CFLAGS = $(CWARNFLAGS) $(XPM_CFLAGS)
+
+cxpm_SOURCES = cxpm.c
+
+# Man page
+appmandir = $(APP_MAN_DIR)
+
+appman_PRE = cxpm.man
+appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@)
+
+EXTRA_DIST = $(appman_PRE)
+CLEANFILES = $(appman_DATA)
+
+SUFFIXES = .$(APP_MAN_SUFFIX) .man
+
+# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
+.man.$(APP_MAN_SUFFIX):
+       $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
+
+if USE_GETTEXT
+noinst_DATA = cxpm.po
+
+cxpm.po: $(cxpm_SOURCES:%=$(srcdir)/%)
+       $(AM_V_GEN)xgettext -c"L10N_Comments" -d cxpm -n $(cxpm_SOURCES:%=$(srcdir)/%)
+
+CLEANFILES += cxpm.po
+endif
diff --git a/cxpm/cxpm.c b/cxpm/cxpm.c
new file mode 100755 (executable)
index 0000000..49296ee
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 1998 Arnaud LE HORS
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * Arnaud LE HORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Arnaud LE HORS shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Arnaud LE HORS.
+ */
+
+/*****************************************************************************\
+* cxpm.c:                                                                     *
+*                                                                             *
+*  Check XPM File program                                                     *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#define CXPMPROG
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#ifdef USE_GETTEXT
+#include <locale.h>
+#include <libintl.h>
+#else
+#define gettext(a) (a)
+#endif
+
+#undef xpmGetC
+#define xpmGetC(data) sGetc(data, data->stream.file)
+#define Getc sGetc
+#define Ungetc sUngetc
+
+
+/*
+ * special getc and ungetc counting read lines and characters
+ * note that 's' could stand both for "special" and "slow" ;-)
+ */
+static int
+sGetc(xpmData *data, FILE *file)
+{
+    int c = getc(data->stream.file);
+    if (c == '\n') {
+        data->lineNum++;
+        data->charNum = 0;
+    } else {
+        data->charNum++;
+    }
+    return c;
+}
+
+static void
+sUngetc(xpmData *data, int c, FILE *file)
+{
+    ungetc(c, data->stream.file);
+    if (c == '\n') {
+        data->lineNum--;
+        data->charNum = 0;
+    } else {
+        data->charNum--;
+    }
+}
+
+/* include all the code we need (yeah, I know, quite ugly...) */
+#include "data.c"
+#include "parse.c"
+#include "RdFToI.c"    /* only for OpenReadFile and xpmDataClose */
+#include "hashtab.c"
+#include "misc.c"
+#include "Attrib.c"
+#include "Image.c"
+
+static void
+ErrorMessage(
+    int ErrorStatus,
+    xpmData *data)
+
+{
+    char *error = NULL;
+
+    switch (ErrorStatus) {
+    case XpmSuccess:
+       return;
+    case XpmOpenFailed:
+       /* L10N_Comments : Error produced when filename does not exist 
+          or insufficient permissions to open (i.e. cxpm /no/such/file ) */
+       error = gettext("Cannot open file");
+       break;
+    case XpmFileInvalid:
+       /* L10N_Comments : Error produced when filename can be read, but
+          is not an XPM file (i.e. cxpm /dev/null ) */
+       error = gettext("Invalid XPM file");
+       break;
+    case XpmNoMemory:
+       /* L10N_Comments : Error produced when filename can be read, but
+          is too big for memory 
+          (i.e. limit datasize 32 ; cxpm /usr/dt/backdrops/Crochet.pm ) */
+       error = gettext("Not enough memory");
+       break;
+    case XpmColorFailed:
+       /* L10N_Comments : Error produced when filename can be read, but
+          contains an invalid color specification (need to create test case)*/
+       error = gettext("Failed to parse color");
+       break;
+    }
+
+    if (error) {
+       /* L10N_Comments : Wrapper around above Xpm errors - %s is
+          replaced with the contents of the error message retrieved above */
+       fprintf(stderr, gettext("Xpm Error: %s.\n"), error);
+       if (ErrorStatus == XpmFileInvalid && data)
+       /* L10N_Comments : Error produced when filename can be read, but
+          is not an XPM file (i.e. cxpm /dev/null ) */
+         fprintf(stderr, gettext("Error found line %d near character %d\n"),
+                 data->lineNum + 1,
+                 data->charNum + 1);
+       exit(1);
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    XpmImage image;
+    char *filename;
+    int ErrorStatus;
+    xpmData data;
+
+#ifdef USE_GETTEXT
+    setlocale(LC_ALL,"");
+    bindtextdomain("cxpm",LOCALEDIR);
+    textdomain("cxpm");
+#endif
+
+    if (argc > 1) {
+        if (!strcmp(argv[1], "-?") || !strncmp(argv[1], "-h", 2)) {
+           /* L10N_Comments : Usage message produced by running cxpm -h
+               %s will be replaced by argv[0] (program name) */
+           fprintf(stderr, gettext("Usage: %s [filename]\n"), argv[0]);
+           exit(1);
+       }
+        filename = argv[1];
+    } else {
+        filename = NULL;
+    }
+
+    xpmInitXpmImage(&image);
+
+    if ((ErrorStatus = OpenReadFile(filename, &data)) != XpmSuccess)
+       ErrorMessage(ErrorStatus, NULL);
+
+    ErrorStatus = xpmParseData(&data, &image, NULL);
+    ErrorMessage(ErrorStatus, &data);
+
+    xpmDataClose(&data);
+    XpmFreeXpmImage(&image);
+
+    exit(0);
+}
diff --git a/cxpm/cxpm.man b/cxpm/cxpm.man
new file mode 100644 (file)
index 0000000..21d63fd
--- /dev/null
@@ -0,0 +1,49 @@
+.\"Copyright (C) 1998 Arnaud LE HORS
+.\"
+.\"Permission is hereby granted, free of charge, to any person obtaining a copy
+.\"of this software and associated documentation files (the "Software"), to
+.\"deal in the Software without restriction, including without limitation the
+.\"rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+.\"sell copies of the Software, and to permit persons to whom the Software is
+.\"furnished to do so, subject to the following conditions:
+.\"
+.\"The above copyright notice and this permission notice shall be included in
+.\"all copies or substantial portions of the Software.
+.\"
+.\"THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+.\"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+.\"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+.\"Arnaud LE HORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+.\"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+.\"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\"Except as contained in this notice, the name of Arnaud LE HORS shall not be
+.\"used in advertising or otherwise to promote the sale, use or other dealings
+.\"in this Software without prior written authorization from Arnaud LE HORS.
+.\"
+.nr )S 12
+.TH CXPM 1
+.PD
+.ad b
+.SH NAME
+cxpm \- Check an XPM (X PixMap) file - XPM 1, 2, or 3.
+.SH SYNOPSIS
+\fBcxpm\fR
+[\|\fIfilename\fP\|] 
+.SH DESCRIPTION
+.PP
+The \fBcxpm\fP program can be used to check the format of any XPM (version 1, 2,
+or 3) file. On error, unlike \fBsxpm\fR, \fBcxpm\fR prints out an error message
+indicating where the parser choked. This should help finding out what's wrong
+with an XPM file but do not expect too much from it though. This is not even
+close from being some kind of lint program for XPM. First, it stops at the
+first error it encounters - so several fix and retry cycles may be necessary to
+get your file to parse successfully. Second, \fBcxpm\fP only cares about
+the format. If, for instance, your pixmap uses too many colors for your system
+you still may experience difficulties displaying it. Be warned.
+.PP
+When no \fIfilename\fP is given \fBcxpm\fR reads from the standard input.
+.SH AUTHOR
+Arnaud Le Hors    (lehors@sophia.inria.fr)
+.br
+Copyright (C) 1998 by Arnaud LE HORS.
diff --git a/debian/README.source b/debian/README.source
new file mode 100644 (file)
index 0000000..34ab4bf
--- /dev/null
@@ -0,0 +1,73 @@
+------------------------------------------------------
+Quick Guide To Patching This Package For The Impatient
+------------------------------------------------------
+
+1. Make sure you have quilt installed
+2. Unpack the package as usual with "dpkg-source -x"
+3. Run the "patch" target in debian/rules
+4. Create a new patch with "quilt new" (see quilt(1))
+5. Edit all the files you want to include in the patch with "quilt edit" 
+   (see quilt(1)).
+6. Write the patch with "quilt refresh" (see quilt(1))
+7. Run the "clean" target in debian/rules
+
+Alternatively, instead of using quilt directly, you can drop the patch in to 
+debian/patches and add the name of the patch to debian/patches/series.
+
+------------------------------------
+Guide To The X Strike Force Packages
+------------------------------------
+
+The X Strike Force team maintains X packages in git repositories on
+git.debian.org in the pkg-xorg subdirectory. Most upstream packages
+are actually maintained in git repositories as well, so they often
+just need to be pulled into git.debian.org in a "upstream-*" branch.
+Otherwise, the upstream sources are manually installed in the Debian
+git repository.
+
+The .orig.tar.gz upstream source file could be generated this
+"upstream-*" branch in the Debian git repository but it is actually
+copied from upstream tarballs directly.
+
+Due to X.org being highly modular, packaging all X.org applications
+as their own independent packages would have created too many Debian
+packages. For this reason, some X.org applications have been grouped
+into larger packages: xutils, xutils-dev, x11-apps, x11-session-utils,
+x11-utils, x11-xfs-utils, x11-xkb-utils, x11-xserver-utils.
+Most packages, including the X.org server itself and all libraries
+and drivers are, however maintained independently.
+
+The Debian packaging is added by creating the "debian-*" git branch
+which contains the aforementioned "upstream-*" branch plus the debian/
+repository files.
+When a patch has to be applied to the Debian package, two solutions
+are involved:
+* If the patch is available in one of the upstream branches, it
+  may be git'cherry-picked into the Debian repository. In this
+  case, it appears directly in the .diff.gz.
+* Otherwise, the patch is added to debian/patches/ which is managed
+  with quilt as documented in /usr/share/doc/quilt/README.source.
+
+quilt is actually invoked by the Debian X packaging through a larger
+set of scripts called XSFBS. XSFBS brings some other X specific
+features such as managing dependencies and conflicts due to the video
+and input driver ABIs.
+XSFBS itself is maintained in a separate repository at
+  git://git.debian.org/pkg-xorg/xsfbs.git
+and it is pulled inside the other Debian X repositories when needed.
+
+The XSFBS patching system requires a build dependency on quilt. Also
+a dependency on $(STAMP_DIR)/patch has to be added to debian/rules
+so that the XSFBS patching occurs before the actual build. So the
+very first target of the build (likely the one running autoreconf)
+should depend on $(STAMP_DIR)/patch. It should also not depend on
+anything so that parallel builds are correctly supported (nothing
+should probably run while patching is being done). And finally, the
+clean target should depend on the xsfclean target so that patches
+are unapplied on clean.
+
+When the upstream sources contain some DFSG-nonfree files, they are
+listed in text files in debian/prune/ in the "debian-*" branch of
+the Debian repository. XSFBS' scripts then take care of removing
+these listed files during the build so as to generate a modified
+DFSG-free .orig.tar.gz tarball.
diff --git a/debian/changelog b/debian/changelog
new file mode 100755 (executable)
index 0000000..2bf60a1
--- /dev/null
@@ -0,0 +1,188 @@
+libxpm (1:3.5.9-2slp2) unstable; urgency=low
+
+  * change the Makefile for gcc 4.5
+  * Git: 165.213.180.234:slp/pkgs/xorg/lib/libxpm
+  * Tag: libxpm_3.5.9-2slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Wed, 30 Mar 2011 10:43:19 +0900
+
+libxpm (1:3.5.9-1slp2) unstable; urgency=low
+
+  * [X11R7.6] upgrade package 
+  * Git: 165.213.180.234:slp/pkgs/xorg/lib/libxpm
+  * Tag: libxpm_3.5.9-1slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Thu, 06 Jan 2011 10:43:46 +0900
+
+libxpm (1:3.5.8-5slp2) unstable; urgency=low
+
+  * Add --as-needed
+  * Git: 165.213.180.234:/git/slp/pkgs/xorg/lib/libxpm
+  * Tag: libxpm_3.5.8-5slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Sat, 20 Nov 2010 15:24:32 +0900
+
+libxpm (1:3.5.8-4slp2) unstable; urgency=low
+
+  * Update maintainer
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/X11
+  * Tag: libxpm_3.5.8-4slp2
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Wed, 21 Apr 2010 13:58:48 +0900
+
+libxpm (1:3.5.8-3slp2) unstable; urgency=low
+
+  * modify the package name
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Thu, 25 Mar 2010 17:56:40 +0900
+
+libxpm (1:3.5.8-2) unstable; urgency=low
+
+  * Import debian packages
+  * Install .la files
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 07 Dec 2009 10:30:13 +0900
+
+libxpm (1:3.5.8-1) unstable; urgency=low
+
+  [ Timo Aaltonen ]
+  * New upstream release.
+  * Bump the build-dep on xutils-dev (>= 1:7.5~1).
+
+  [ Julien Cristau ]
+  * Bump Standards-Version to 3.8.3.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 25 Nov 2009 19:31:08 +0100
+
+libxpm (1:3.5.7-2) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * Drop -1 debian revisions from build-deps.
+  * Bump Standards-Version to 3.7.3.
+  * Drop the XS- prefix from Vcs-* control fields.
+  * libxpm4{,-dbg} don't need to depend on x11-common.
+  * Add xpm.PS.gz to the -dev package (closes: #525551).
+  * Don't handle nostrip in DEB_BUILD_OPTIONS explicitly, dh_strip does the
+    right thing.
+  * Use filter instead of findstring to parse DEB_BUILD_OPTIONS in
+    debian/rules.
+  * Add README.source, bump Standards-Version to 3.8.1.
+  * Run autoreconf at build time.
+  * Allow parallel builds.
+  * Move -dbg package to new debug section.
+  * Don't pass -l and -L options to dh_shlibdeps, it seems to be useless
+    nowadays.
+
+  [ Brice Goglin ]
+  * Add a link to www.X.org and a reference to the upstream module
+    in the long description.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 10 Jun 2009 14:59:30 +0200
+
+libxpm (1:3.5.7-1) unstable; urgency=low
+
+  * New upstream release.
+  * Add the upstream URL to debian/copyright.
+  * Use binary:Version instead of the deprecated Source-Version.
+  * Add myself to uploaders, and remove Branden with his permission.
+
+ -- Julien Cristau <jcristau@debian.org>  Sat, 25 Aug 2007 10:50:50 +0200
+
+libxpm (1:3.5.6-3) unstable; urgency=low
+
+  * Put binary packages in the correct sections.
+  * Run dh_shlibdeps with -L libxpm4 -l debian/libxpm4/usr/lib so xpmutils
+    gets a dependency on libxpm4.  Fixes bug noticed by checklib.
+
+ -- Julien Cristau <jcristau@debian.org>  Mon, 21 May 2007 17:35:32 +0200
+
+libxpm (1:3.5.6-2) unstable; urgency=low
+
+  * Upload to unstable.
+  * Add XS-Vcs-Browser.
+  * Remove Fabio from Uploaders, with his permission.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 11 Apr 2007 16:31:32 +0200
+
+libxpm (1:3.5.6-1) experimental; urgency=low
+
+  * New upstream release.
+  * Add XS-Vcs-Git header to debian/control.
+  * Drop obsolete CVS information from the long descriptions.
+  * Install the upstream changelog.
+
+ -- Julien Cristau <jcristau@debian.org>  Fri, 16 Feb 2007 16:24:44 +0100
+
+libxpm (1:3.5.5-2) unstable; urgency=low
+
+  [ Andres Salomon ]
+  * Test for obj-$(DEB_BUILD_GNU_TYPE) before creating it during build;
+    idempotency fix.
+
+  [ Drew Parsons ]
+  * dbg package has priority extra.
+
+ -- David Nusinow <dnusinow@debian.org>  Wed, 30 Aug 2006 17:12:38 -0400
+
+libxpm (1:3.5.5-1) experimental; urgency=low
+
+  * New upstream release
+  * Run dh_install with --list-missing
+  * Bump debhelper compat to 5
+  * Remove extra x11-common dep in the -dev package
+  * Version x11-common pre-dep in the -dev package to use 1:7.0.0 to match the
+    rest of Debian and shut lintian up
+  * Add the sxpm and cxpm manpages to xpm-utils
+
+ -- David Nusinow <dnusinow@debian.org>  Mon,  3 Jul 2006 19:23:49 -0400
+
+libxpm (1:3.5.4.2-3) unstable; urgency=low
+
+  * Reorder makeshlib command in rules file so that ldconfig is run
+    properly. Thanks Drew Parsons and Steve Langasek.
+
+ -- David Nusinow <dnusinow@debian.org>  Tue, 18 Apr 2006 21:50:00 -0400
+
+libxpm (1:3.5.4.2-2) unstable; urgency=low
+
+  * Upload to unstable
+
+ -- David Nusinow <dnusinow@debian.org>  Thu, 23 Mar 2006 22:45:13 -0500
+
+libxpm (1:3.5.4.2-1) experimental; urgency=low
+
+  * First upload to Debian
+
+ -- David Nusinow <dnusinow@debian.org>  Thu, 29 Dec 2005 20:54:06 -0500
+
+libxpm (1:3.5.2-5) breezy; urgency=low
+
+  * Add a Build-Depends on libxext-dev.  For my next stunning move, I'll
+    actually pay attention to what I'm doing.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Sat, 23 Jul 2005 01:33:31 +1000
+
+libxpm (1:3.5.2-4) breezy; urgency=low
+
+  * Bump Build-Depends on libx11-dev, libxt-dev, libxext-dev and
+    x11proto-core-dev to avoid _XOPEN_SOURCE.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Sat, 23 Jul 2005 00:24:13 +1000
+
+libxpm (1:3.5.2-3) breezy; urgency=low
+
+  * Fix cat-walks-across-keyboard attack in debian/control.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Wed, 20 Jul 2005 21:18:57 +1000
+
+libxpm (1:3.5.2-2) breezy; urgency=low
+
+  * blah blah xpmutils Replaces: xbase-clients (<< 6.8.2-38) blah blah
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Wed, 20 Jul 2005 18:45:27 +1000
+
+libxpm (1:3.5.2-1) breezy; urgency=low
+
+  * First libxpm release.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Mon, 16 May 2005 22:10:17 +1000
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..84722aa
--- /dev/null
@@ -0,0 +1,87 @@
+Source: libxpm
+Section: x11
+Priority: optional
+Maintainer: Sung-Jin Park <sj76.park@samsung.com>, Sangjin Lee <lsj119@samsung.com>, Debian X Strike Force <debian-x@lists.debian.org>
+Uploaders: SooChan Lim <sc1.lim@samsung.com>, Sung-Jin Park <sj76.park@samsung.com>, DDavid Nusinow <dnusinow@debian.org>, Julien Cristau <jcristau@debian.org>
+Build-Depends: debhelper (>= 5.0.0), automake, libtool, xutils-dev (>= 1:7.5-1slp2), libx11-dev (>= 1:0.99.2), libxt-dev (>= 1:0.99.1-5), x11proto-core-dev (>= 7.0.1), libxext-dev (>= 1:0.99.1), pkg-config
+Standards-Version: 3.8.3
+Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/libxpm
+Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/libxpm.git
+
+Package: libxpm4
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: X11 pixmap library
+ libXpm provides support and common operation for the XPM pixmap format, which
+ is commonly used in legacy X applications.  XPM is an extension of the
+ monochrome XBM bitmap specificied in the X protocol.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXpm
+
+Package: libxpm4-dbg
+Section: debug
+Architecture: any
+Priority: extra
+Depends: ${shlibs:Depends}, ${misc:Depends}, libxpm4 (= ${binary:Version})
+Description: X11 pixmap library (debug package)
+ libXpm provides support and common operation for the XPM pixmap format, which
+ is commonly used in legacy X applications.  XPM is an extension of the
+ monochrome XBM bitmap specificied in the X protocol.
+ .
+ This package contains the debug versions of the library found in libxpm4.
+ Non-developers likely have little use for this package.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXpm
+
+Package: libxpm-dev
+Section: libdevel
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, libxpm4 (= ${binary:Version}), libx11-dev, x11proto-core-dev
+Pre-Depends: x11-common (>= 1:7.0.0)
+Description: X11 pixmap library (development headers)
+ libXpm provides support and common operation for the XPM pixmap format, which
+ is commonly used in legacy X applications.  XPM is an extension of the
+ monochrome XBM bitmap specificied in the X protocol.
+ .
+ This package contains the development headers for the library found in
+ libxpm4.  Non-developers likely have little use for this package.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXpm
+
+Package: xpmutils
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Replaces: xbase-clients (<< 6.8.2-38)
+Description: X11 pixmap utilities
+ This package provides two tools, cxpm and sxpm.
+ .
+ cxpm is a tool to check the integrity of an XPM file.
+ .
+ sxpm is a tool to view XPM files, and takes a number of options.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libXpm
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..a0488f7
--- /dev/null
@@ -0,0 +1,25 @@
+This package was downloaded from
+http://xorg.freedesktop.org/releases/individual/lib/
+
+Copyright (C) 1989-95 GROUPE BULL
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of GROUPE BULL shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from GROUPE BULL.
diff --git a/debian/libxpm-dev.docs b/debian/libxpm-dev.docs
new file mode 100644 (file)
index 0000000..406202c
--- /dev/null
@@ -0,0 +1 @@
+xpm.PS.gz
diff --git a/debian/libxpm-dev.install b/debian/libxpm-dev.install
new file mode 100755 (executable)
index 0000000..f624126
--- /dev/null
@@ -0,0 +1,5 @@
+usr/include/X11/*
+usr/lib/libXpm.a
+usr/lib/libXpm.so
+usr/lib/libXpm.la
+usr/lib/pkgconfig/xpm.pc
diff --git a/debian/libxpm4.install b/debian/libxpm4.install
new file mode 100644 (file)
index 0000000..84b8f2d
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/libXpm.so.4*
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..0038f00
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/make -f
+# debian/rules for the Debian libxpm package.
+# Copyright Â© 2004 Scott James Remnant <scott@netsplit.com>
+# Copyright Â© 2005 Daniel Stone <daniel@fooishbar.org>
+# Copyright Â© 2005 David Nusinow <dnusinow@debian.org>
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# set this to the name of the main shlib's binary package
+PACKAGE = libxpm4
+
+include debian/xsfbs/xsfbs.mk
+
+CFLAGS = -Wall -g
+LDFLAGS +=  -Wl,--hash-style=both -Wl,--as-needed
+ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       MAKEFLAGS += -j$(NUMJOBS)
+endif
+
+DEB_HOST_ARCH      ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_HOST_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
+       confflags += --build=$(DEB_HOST_GNU_TYPE)
+else
+       confflags += --build=$(DEB_HOST_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+#      confflags += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+endif
+
+
+build: build-stamp
+build-stamp:
+       dh_testdir
+       autoreconf -vfi
+       mkdir -p obj-$(DEB_BUILD_GNU_TYPE)
+       cd obj-$(DEB_BUILD_GNU_TYPE) && \
+       ../configure --prefix=/usr --mandir=\$${prefix}/share/man \
+                    --infodir=\$${prefix}/share/info $(confflags) \
+                    CFLAGS="$(CFLAGS)" \
+                    LDFLAGS="$(LDFLAGS)" 
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE)
+       >$@
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp
+
+       rm -f config.cache config.log config.status
+       rm -f */config.cache */config.log */config.status
+       rm -f conftest* */conftest*
+       rm -rf autom4te.cache */autom4te.cache
+       rm -rf obj-*
+       rm -f aclocal.m4 compile config.guess config.h.in config.sub configure
+       rm -f INSTALL depcomp install-sh ltmain.sh missing mkinstalldirs
+       rm -f $$(find -name Makefile.in)
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+
+#      dh_installdocs
+       dh_install --sourcedir=debian/tmp --list-missing
+#      dh_installchangelogs ChangeLog
+       dh_link
+       dh_strip --dbg-package=$(PACKAGE)-dbg
+       dh_compress
+       dh_fixperms
+       dh_makeshlibs
+       dh_shlibdeps
+       dh_installdeb
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+# Build architecture-independent files here.
+binary-indep: build install
+# Nothing to do
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/debian/watch b/debian/watch
new file mode 100644 (file)
index 0000000..2d4cb52
--- /dev/null
@@ -0,0 +1,2 @@
+version=3
+http://xorg.freedesktop.org/releases/individual/lib/ libXpm-(.*)\.tar\.gz
diff --git a/debian/xpmutils.install b/debian/xpmutils.install
new file mode 100644 (file)
index 0000000..30db576
--- /dev/null
@@ -0,0 +1,4 @@
+usr/bin/cxpm
+usr/bin/sxpm
+usr/share/man/man1/sxpm.1
+usr/share/man/man1/cxpm.1
diff --git a/debian/xsfbs/repack.sh b/debian/xsfbs/repack.sh
new file mode 100644 (file)
index 0000000..5935cc9
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+if ! [ -d debian/prune ]; then
+       exit 0
+fi
+
+if [ "x$1" != x--upstream-version ]; then
+       exit 1
+fi
+
+version="$2"
+filename="$3"
+
+if [ -z "$version" ] || ! [ -f "$filename" ]; then
+       exit 1
+fi
+
+dir="$(pwd)"
+tempdir="$(mktemp -d)"
+
+cd "$tempdir"
+tar xf "$dir/$filename"
+cat "$dir"/debian/prune/* | while read file; do rm -f */$file; done
+
+tar czf "$dir/$filename" *
+cd "$dir"
+rm -rf "$tempdir"
+echo "Done pruning upstream tarball"
+
+exit 0
diff --git a/debian/xsfbs/xsfbs.mk b/debian/xsfbs/xsfbs.mk
new file mode 100644 (file)
index 0000000..5e16b10
--- /dev/null
@@ -0,0 +1,276 @@
+#!/usr/bin/make -f
+
+# Debian X Strike Force Build System (XSFBS): Make portion
+
+# Copyright 1996 Stephen Early
+# Copyright 1997 Mark Eichin
+# Copyright 1998-2005, 2007 Branden Robinson
+# Copyright 2005 David Nusinow
+#
+# Licensed under the GNU General Public License, version 2.  See the file
+# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
+
+# Originally by Stephen Early <sde1000@debian.org>
+# Modified by Mark W. Eichin <eichin@kitten.gen.ma.us>
+# Modified by Adam Heath <doogie@debian.org>
+# Modified by Branden Robinson <branden@debian.org>
+# Modified by Fabio Massimo Di Nitto <fabbione@fabbione.net>
+# Modified by David Nusinow <dnusinow@debian.org>
+# Acknowledgements to Manoj Srivastava.
+
+# Pass $(DH_OPTIONS) into the environment for debhelper's benefit.
+export DH_OPTIONS
+
+# force quilt to not use ~/.quiltrc and to use debian/patches
+QUILT = QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null
+
+# Set up parameters for the upstream build environment.
+
+# Determine (source) package name from Debian changelog.
+SOURCE_NAME:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Source:' | awk '{print $$2}')
+
+# Determine package version from Debian changelog.
+SOURCE_VERSION:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Version:' | awk '{print $$2}')
+
+# Determine upstream version number.
+UPSTREAM_VERSION:=$(shell echo $(SOURCE_VERSION) | sed 's/-.*//')
+
+# Determine the source version without the epoch for make-orig-tar-gz
+NO_EPOCH_VER:=$(shell echo $(UPSTREAM_VERSION) | sed 's/^.://')
+
+# Figure out who's building this package.
+BUILDER:=$(shell echo $${DEBEMAIL:-$${EMAIL:-$$(echo $$LOGNAME@$$(cat /etc/mailname 2>/dev/null))}})
+
+# Find out if this is an official build; an official build has nothing but
+# digits, dots, and/or the codename of a release in the Debian part of the
+# version number.  Anything else indicates an unofficial build.
+OFFICIAL_BUILD:=$(shell VERSION=$(SOURCE_VERSION); if ! expr "$$(echo $${VERSION\#\#*-} | sed 's/\(woody\|sarge\|etch\|lenny\)//g')" : ".*[^0-9.].*" >/dev/null 2>&1; then echo yes; fi)
+
+# Set up parameters for the Debian build environment.
+
+# Determine our architecture.
+BUILD_ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
+# Work around some old-time dpkg braindamage.
+BUILD_ARCH:=$(subst i486,i386,$(BUILD_ARCH))
+# The DEB_HOST_ARCH variable may be set per the Debian cross-compilation policy.
+ifdef DEB_HOST_ARCH
+ ARCH:=$(DEB_HOST_ARCH)
+else
+ # dpkg-cross sets the ARCH environment variable; if set, use it.
+ ifdef ARCH
+  ARCH:=$(ARCH)
+ else
+  ARCH:=$(BUILD_ARCH)
+ endif
+endif
+
+# $(STAMP_DIR) houses stamp files for complex targets.
+STAMP_DIR:=stampdir
+
+# $(DEBTREEDIR) is where all install rules are told (via $(DESTDIR)) to place
+# their files.
+DEBTREEDIR:=$(CURDIR)/debian/tmp
+
+# All "important" targets have four lines:
+#   1) A target name that is invoked by a package-building tool or the user.
+#      This consists of a dependency on a "$(STAMP_DIR)/"-prefixed counterpart.
+#   2) A line delcaring 1) as a phony target (".PHONY:").
+#   3) A "$(STAMP_DIR)/"-prefixed target which does the actual work, and may
+#   depend on other targets.
+#   4) A line declaring 3) as a member of the $(stampdir_targets) variable; the
+#   "$(STAMP_DIR)/" prefix is omitted.
+#
+# This indirection is needed so that the "stamp" files that signify when a rule
+# is done can be located in a separate "stampdir".  Recall that make has no way
+# to know when a goal has been met for a phony target (like "build" or
+# "install").
+#
+# At the end of each "$(STAMP_DIR)/" target, be sure to run the command ">$@"
+# so that the target will not be run again.  Removing the file will make Make
+# run the target over.
+
+# All phony targets should be declared as dependencies of .PHONY, even if they
+# do not have "($STAMP_DIR)/"-prefixed counterparts.
+
+# Define a harmless default rule to keep things from going nuts by accident.
+.PHONY: default
+default:
+
+# Set up the $(STAMP_DIR) directory.
+.PHONY: stampdir
+stampdir_targets+=stampdir
+stampdir: $(STAMP_DIR)/stampdir
+$(STAMP_DIR)/stampdir:
+       mkdir $(STAMP_DIR)
+       >$@
+
+# Set up the package build directory as quilt expects to find it.
+.PHONY: prepare
+stampdir_targets+=prepare
+prepare: $(STAMP_DIR)/prepare
+$(STAMP_DIR)/prepare: $(STAMP_DIR)/log $(STAMP_DIR)/genscripts
+       >$@
+
+.PHONY: log
+stampdir_targets+=log
+log: $(STAMP_DIR)/log
+$(STAMP_DIR)/log: $(STAMP_DIR)/stampdir
+       mkdir -p $(STAMP_DIR)/log
+
+# Apply all patches to the upstream source.
+.PHONY: patch
+stampdir_targets+=patch
+patch: $(STAMP_DIR)/patch
+$(STAMP_DIR)/patch: $(STAMP_DIR)/prepare
+       if ! [ `which quilt` ]; then \
+               echo "Couldn't find quilt. Please install it or add it to the build-depends for this package."; \
+               exit 1; \
+       fi; \
+       if $(QUILT) next >/dev/null 2>&1; then \
+         echo -n "Applying patches..."; \
+         if $(QUILT) push -a -v >$(STAMP_DIR)/log/patch 2>&1; then \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "failed! (check $(STAMP_DIR)/log/patch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "No patches to apply"; \
+       fi; \
+       >$@
+
+# Revert all patches to the upstream source.
+.PHONY: unpatch
+unpatch: $(STAMP_DIR)/log
+       rm -f $(STAMP_DIR)/patch
+       @echo -n "Unapplying patches..."; \
+       if $(QUILT) applied >/dev/null 2>/dev/null; then \
+         if $(QUILT) pop -a -v >$(STAMP_DIR)/log/unpatch 2>&1; then \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "failed! (check $(STAMP_DIR)/log/unpatch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "nothing to do."; \
+       fi
+
+# Clean the generated maintainer scripts.
+.PHONY: cleanscripts
+cleanscripts:
+       rm -f $(STAMP_DIR)/genscripts
+       rm -f debian/*.config \
+             debian/*.postinst \
+             debian/*.postrm \
+             debian/*.preinst \
+             debian/*.prerm
+
+# Clean the package build tree.
+.PHONY: xsfclean
+xsfclean: cleanscripts unpatch
+       dh_testdir
+       rm -rf .pc
+       rm -rf $(STAMP_DIR)
+       dh_clean
+
+# Remove files from the upstream source tree that we don't need, or which have
+# licensing problems.  It must be run before creating the .orig.tar.gz.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: prune-upstream-tree
+prune-upstream-tree:
+       # Ensure we're in the correct directory.
+       dh_testdir
+       grep -rvh '^#' debian/prune/ | xargs --no-run-if-empty rm -rf
+
+# Verify that there are no offsets or fuzz in the patches we apply.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: patch-audit
+patch-audit: prepare unpatch
+       @echo -n "Auditing patches..."; \
+       >$(STAMP_DIR)/log/patch; \
+       FUZZY=; \
+       while [ -n "$$($(QUILT) next)" ]; do \
+         RESULT=$$($(QUILT) push -v | tee -a $(STAMP_DIR)/log/patch | grep ^Hunk | sed 's/^Hunk.*\(succeeded\|FAILED\).*/\1/');\
+         case "$$RESULT" in \
+           succeeded) \
+             echo "fuzzy patch: $$($(QUILT) top)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) top); \
+             FUZZY=yes; \
+             ;; \
+           FAILED) \
+             echo "broken patch: $$($(QUILT) next)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) next); \
+             exit 1; \
+             ;; \
+         esac; \
+       done; \
+       if [ -n "$$FUZZY" ]; then \
+         echo "there were fuzzy patches; please fix."; \
+         exit 1; \
+       else \
+         echo "done."; \
+       fi
+
+# Generate the maintainer scripts.
+.PHONY: genscripts
+stampdir_targets+=genscripts
+genscripts: $(STAMP_DIR)/genscripts
+$(STAMP_DIR)/genscripts: $(STAMP_DIR)/stampdir
+       for FILE in debian/*.config.in \
+                   debian/*.postinst.in \
+                   debian/*.postrm.in \
+                   debian/*.preinst.in \
+                   debian/*.prerm.in; do \
+         if [ -e "$$FILE" ]; then \
+           MAINTSCRIPT=$$(echo $$FILE | sed 's/.in$$//'); \
+           sed -n '1,/^#INCLUDE_SHELL_LIB#$$/p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >$$MAINTSCRIPT.tmp; \
+           cat debian/xsfbs/xsfbs.sh >>$$MAINTSCRIPT.tmp; \
+           sed -n '/^#INCLUDE_SHELL_LIB#$$/,$$p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >>$$MAINTSCRIPT.tmp; \
+           sed -e 's/@SOURCE_VERSION@/$(SOURCE_VERSION)/' \
+               -e 's/@OFFICIAL_BUILD@/$(OFFICIAL_BUILD)/' \
+             <$$MAINTSCRIPT.tmp >$$MAINTSCRIPT; \
+           rm $$MAINTSCRIPT.tmp; \
+         fi; \
+       done
+       # Validate syntax of generated shell scripts.
+       #sh debian/scripts/validate-posix-sh debian/*.config \
+       #                                    debian/*.postinst \
+       #                                    debian/*.postrm \
+       #                                    debian/*.preinst \
+       #                                    debian/*.prerm
+       >$@
+
+SERVERMINVERS = $(shell cat /usr/share/xserver-xorg/serverminver 2>/dev/null)
+VIDEOABI = $(shell cat /usr/share/xserver-xorg/videoabiver 2>/dev/null)
+INPUTABI = $(shell cat /usr/share/xserver-xorg/inputabiver 2>/dev/null)
+SERVER_DEPENDS = xserver-xorg-core (>= $(SERVERMINVERS))
+VIDDRIVER_PROVIDES = xserver-xorg-video-$(VIDEOABI)
+INPDRIVER_PROVIDES = xserver-xorg-input-$(INPUTABI)
+ifeq ($(PACKAGE),)
+PACKAGE=$(shell awk '/^Package:/ { print $$2; exit }' < debian/control)
+endif
+
+.PHONY: serverabi
+serverabi: install
+ifeq ($(SERVERMINVERS),)
+       @echo error: xserver-xorg-dev needs to be installed
+       @exit 1
+else
+       echo "xserver:Depends=$(SERVER_DEPENDS)" >> debian/$(PACKAGE).substvars
+       echo "xviddriver:Provides=$(VIDDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+       echo "xinpdriver:Provides=$(INPDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+endif
+
+# vim:set noet ai sts=8 sw=8 tw=0:
diff --git a/debian/xsfbs/xsfbs.sh b/debian/xsfbs/xsfbs.sh
new file mode 100644 (file)
index 0000000..813fd8d
--- /dev/null
@@ -0,0 +1,622 @@
+# This is the X Strike Force shell library for X Window System package
+# maintainer scripts.  It serves to define shell functions commonly used by
+# such packages, and performs some error checking necessary for proper operation
+# of those functions.  By itself, it does not "do" much; the maintainer scripts
+# invoke the functions defined here to accomplish package installation and
+# removal tasks.
+
+# If you are reading this within a Debian package maintainer script (e.g.,
+# /var/lib/dpkg/info/PACKAGE.{config,preinst,postinst,prerm,postrm}), you can
+# skip past this library by scanning forward in this file to the string
+# "GOBSTOPPER".
+
+SOURCE_VERSION=@SOURCE_VERSION@
+OFFICIAL_BUILD=@OFFICIAL_BUILD@
+
+# Use special abnormal exit codes so that problems with this library are more
+# easily tracked down.
+SHELL_LIB_INTERNAL_ERROR=86
+SHELL_LIB_THROWN_ERROR=74
+SHELL_LIB_USAGE_ERROR=99
+
+# old -> new variable names
+if [ -z "$DEBUG_XORG_PACKAGE" ] && [ -n "$DEBUG_XFREE86_PACKAGE" ]; then
+  DEBUG_XORG_PACKAGE="$DEBUG_XFREE86_PACKAGE"
+fi
+if [ -z "$DEBUG_XORG_DEBCONF" ] && [ -n "$DEBUG_XFREE86_DEBCONF" ]; then
+  DEBUG_XORG_DEBCONF="$DEBUG_XFREE86_DEBCONF"
+fi
+
+# initial sanity checks
+if [ -z "$THIS_PACKAGE" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_PACKAGE shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of this package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ -z "$THIS_SCRIPT" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_SCRIPT shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of the
+"$THIS_PACKAGE" package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ "$1" = "reconfigure" ] || [ -n "$DEBCONF_RECONFIGURE" ]; then
+  RECONFIGURE="true"
+else
+  RECONFIGURE=
+fi
+
+if ([ "$1" = "install" ] || [ "$1" = "configure" ]) && [ -z "$2" ]; then
+  FIRSTINST="yes"
+fi
+
+if [ -z "$RECONFIGURE" ] && [ -z "$FIRSTINST" ]; then
+  UPGRADE="yes"
+fi
+
+trap "message;\
+      message \"Received signal.  Aborting $THIS_PACKAGE package $THIS_SCRIPT script.\";\
+      message;\
+      exit 1" HUP INT QUIT TERM
+
+reject_nondigits () {
+  # syntax: reject_nondigits [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters other than decimal digits and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain anything but digits?
+    if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+      # can't use die(), because it wraps message() which wraps this function
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \
+           "possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+reject_unlikely_path_chars () {
+  # syntax: reject_unlikely_path_chars [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters unlikely to be seen in a path and which the shell might
+  # interpret and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain any funny characters?
+    if expr "$1" : '.*[!$&()*;<>?|].*' > /dev/null 2>&1; then
+      # can't use die(), because I want to avoid forward references
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \
+           "encountered possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+# Query the terminal to establish a default number of columns to use for
+# displaying messages to the user.  This is used only as a fallback in the
+# event the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while
+# the script is running, and this cannot, only being calculated once.)
+DEFCOLUMNS=$(stty size 2> /dev/null | awk '{print $2}') || true
+if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+  DEFCOLUMNS=80
+fi
+
+message () {
+  # pretty-print messages of arbitrary length
+  reject_nondigits "$COLUMNS"
+  echo "$*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} >&2
+}
+
+observe () {
+  # syntax: observe message ...
+  #
+  # issue observational message suitable for logging someday when support for
+  # it exists in dpkg
+  if [ -n "$DEBUG_XORG_PACKAGE" ]; then
+    message "$THIS_PACKAGE $THIS_SCRIPT note: $*"
+  fi
+}
+
+warn () {
+  # syntax: warn message ...
+  #
+  # issue warning message suitable for logging someday when support for
+  # it exists in dpkg; also send to standard error
+  message "$THIS_PACKAGE $THIS_SCRIPT warning: $*"
+}
+
+die () {
+  # syntax: die message ...
+  #
+  # exit script with error message
+  message "$THIS_PACKAGE $THIS_SCRIPT error: $*"
+  exit $SHELL_LIB_THROWN_ERROR
+}
+
+internal_error () {
+  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
+  message "internal error: $*"
+  if [ -n "$OFFICIAL_BUILD" ]; then
+    message "Please report a bug in the $THIS_SCRIPT script of the" \
+            "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+            "Tracking System.  Include all messages above that mention the" \
+            "$THIS_PACKAGE package.  Visit " \
+            "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+            "instructions, read the file" \
+            "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+            "package, or install the reportbug package and use the command of" \
+            "the same name to file a report."
+  fi
+  exit $SHELL_LIB_INTERNAL_ERROR
+}
+
+usage_error () {
+  message "usage error: $*"
+  message "Please report a bug in the $THIS_SCRIPT script of the" \
+          "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+          "Tracking System.  Include all messages above that mention the" \
+          "$THIS_PACKAGE package.  Visit " \
+          "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+          "instructions, read the file" \
+          "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+          "package, or install the reportbug package and use the command of" \
+          "the same name to file a report."
+  exit $SHELL_LIB_USAGE_ERROR
+}
+
+font_update () {
+  # run $UPDATECMDS in $FONTDIRS
+
+  local dir cmd shortcmd x_font_dir_prefix
+
+  x_font_dir_prefix="/usr/share/fonts/X11"
+
+  if [ -z "$UPDATECMDS" ]; then
+    usage_error "font_update() called but \$UPDATECMDS not set"
+  fi
+  if [ -z "$FONTDIRS" ]; then
+    usage_error "font_update() called but \$FONTDIRS not set"
+  fi
+
+  reject_unlikely_path_chars "$UPDATECMDS"
+  reject_unlikely_path_chars "$FONTDIRS"
+
+  for dir in $FONTDIRS; do
+    if [ -d "$x_font_dir_prefix/$dir" ]; then
+      for cmd in $UPDATECMDS; do
+        if which "$cmd" > /dev/null 2>&1; then
+          shortcmd=${cmd##*/}
+          observe "running $shortcmd in $dir font directory"
+         cmd_opts=
+          if [ "$shortcmd" = "update-fonts-alias" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-dir" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-scale" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          $cmd $cmd_opts $dir || warn "$cmd $cmd_opts $dir" \
+                              "failed; font directory data may not" \
+                              "be up to date"
+        else
+          warn "$cmd not found; not updating corresponding $dir font" \
+               "directory data"
+        fi
+      done
+    else
+      warn "$dir is not a directory; not updating font directory data"
+    fi
+  done
+}
+
+remove_conffile_prepare () {
+  # syntax: remove_conffile_prepare filename official_md5sum ...
+  #
+  # Check a conffile "filename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 2 ]; then
+    usage_error "remove_conffile_prepare() called with wrong number of" \
+                "arguments; expected at least 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+  shift
+
+  # does the conffile even exist?
+  if [ -e "$conffile" ]; then
+    # calculate its checksum
+    current_checksum=$(md5sum < "$conffile" | sed 's/[[:space:]].*//')
+    # compare it to each supplied checksum
+    while [ -n "$1" ]; do
+      if [ "$current_checksum" = "$1" ]; then
+        # we found a match; move the confffile and stop looking
+        observe "preparing obsolete conffile $conffile for removal"
+        mv "$conffile" "$conffile.$THIS_PACKAGE-tmp"
+        break
+      fi
+      shift
+    done
+  fi
+}
+
+remove_conffile_lookup () {
+  # syntax: remove_conffile_lookup package filename
+  #
+  # Lookup the md5sum of a conffile in dpkg's database, and prepare for removal
+  # if it matches the actual file's md5sum.
+  #
+  # Call this function when you would call remove_conffile_prepare but only
+  # want to check against dpkg's status database instead of known checksums.
+
+  local package conffile old_md5sum
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "remove_conffile_lookup() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  package="$1"
+  conffile="$2"
+
+  if ! [ -e "$conffile" ]; then
+    return
+  fi
+  old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$package" | \
+    awk '{ if (match($0, "^ '"$conffile"' ")) print $2}')"
+  if [ -n "$old_md5sum" ]; then
+    remove_conffile_prepare "$conffile" "$old_md5sum"
+  fi
+}
+
+remove_conffile_commit () {
+  # syntax: remove_conffile_commit filename
+  #
+  # Complete the removal of a conffile "filename" that has become obsolete.
+  #
+  # Call this function from a postinst script after having used
+  # remove_conffile_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_commit() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, remove it
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "committing removal of obsolete conffile $conffile"
+    rm "$conffile.$THIS_PACKAGE-tmp"
+  fi
+}
+
+remove_conffile_rollback () {
+  # syntax: remove_conffile_rollback filename
+  #
+  # Roll back the removal of a conffile "filename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" is  after having used remove_conffile_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_rollback() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, move it
+  # back
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "rolling back removal of obsolete conffile $conffile"
+    mv "$conffile.$THIS_PACKAGE-tmp" "$conffile"
+  fi
+}
+
+replace_conffile_with_symlink_prepare () {
+  # syntax: replace_conffile_with_symlink_prepare oldfilename newfilename \
+  # official_md5sum ...
+  #
+  # Check a conffile "oldfilename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails. Otherwise copy it
+  # to newfilename and let dpkg handle it through conffiles mechanism.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 3 ]; then
+    usage_error "replace_conffile_with_symlink_prepare() called with wrong" \
+                " number of arguments; expected at least 3, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  shift
+  newconffile="$1"
+  shift
+
+  remove_conffile_prepare "$_oldconffile" "$@"
+  # If $oldconffile still exists, then md5sums didn't match.
+  # Copy it to new one.
+  if [ -f "$oldconffile" ]; then
+    cp "$oldconffile" "$newconffile"
+  fi
+
+}
+
+replace_conffile_with_symlink_commit () {
+  # syntax: replace_conffile_with_symlink_commit oldfilename
+  #
+  # Complete the removal of a conffile "oldfilename" that has been
+  # replaced by a symlink.
+  #
+  # Call this function from a postinst script after having used
+  # replace_conffile_with_symlink_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "replace_conffile_with_symlink_commit() called with wrong" \
+                "number of arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  remove_conffile_commit "$conffile"
+}
+
+replace_conffile_with_symlink_rollback () {
+  # syntax: replace_conffile_with_symlink_rollback oldfilename newfilename
+  #
+  # Roll back the replacing of a conffile "oldfilename" with symlink to
+  # "newfilename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" and verify $2 to ensure the package failed to upgrade
+  # from a version (or install over a version removed-but-not-purged) prior
+  # to the one in which the conffile was obsoleted.
+  # You should have  used replace_conffile_with_symlink_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "replace_conffile_with_symlink_rollback() called with wrong" \
+                "number of arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  newconffile="$2"
+
+  remove_conffile_rollback "$_oldconffile"
+  if [ -f "$newconffile" ]; then
+    rm "$newconffile"
+  fi
+}
+
+run () {
+  # syntax: run command [ argument ... ]
+  #
+  # Run specified command with optional arguments and report its exit status.
+  # Useful for commands whose exit status may be nonzero, but still acceptable,
+  # or commands whose failure is not fatal to us.
+  #
+  # NOTE: Do *not* use this function with db_get or db_metaget commands; in
+  # those cases the return value of the debconf command *must* be checked
+  # before the string returned by debconf is used for anything.
+
+  local retval
+
+  # validate arguments
+  if [ $# -lt 1 ]; then
+    usage_error "run() called with wrong number of arguments; expected at" \
+                "least 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  "$@" || retval=$?
+
+  if [ ${retval:-0} -ne 0 ]; then
+    observe "command \"$*\" exited with status $retval"
+  fi
+}
+
+make_symlink_sane () {
+  # syntax: make_symlink_sane symlink target
+  #
+  # Ensure that the symbolic link symlink exists, and points to target.
+  #
+  # If symlink does not exist, create it and point it at target.
+  #
+  # If symlink exists but is not a symbolic link, back it up.
+  #
+  # If symlink exists, is a symbolic link, but points to the wrong location, fix
+  # it.
+  #
+  # If symlink exists, is a symbolic link, and already points to target, do
+  # nothing.
+  #
+  # This function wouldn't be needed if ln had an -I, --idempotent option.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "make_symlink_sane() called with wrong number of arguments;" \
+      "expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local symlink target
+
+  symlink="$1"
+  target="$2"
+
+  if [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$target" ]; then
+      observe "link from $symlink to $target already exists"
+  else
+    observe "creating symbolic link from $symlink to $target"
+    mkdir -p "${target%/*}" "${symlink%/*}"
+    ln -s -b -S ".dpkg-old" "$target" "$symlink"
+  fi
+}
+
+migrate_dir_to_symlink () {
+  # syntax: migrate_dir_to_symlink old_location new_location
+  #
+  # Per Debian Policy section 6.5.4, "A directory will never be replaced by a
+  # symbolic link to a directory or vice versa; instead, the existing state
+  # (symlink or not) will be left alone and dpkg will follow the symlink if
+  # there is one."
+  #
+  # We have to do it ourselves.
+  #
+  # This function moves the contents of old_location, a directory, into
+  # new_location, a directory, then makes old_location a symbolic link to
+  # new_location.
+  #
+  # old_location need not exist, but if it does, it must be a directory (or a
+  # symlink to a directory).  If it is not, it is backed up.  If new_location
+  # exists already and is not a directory, it is backed up.
+  #
+  # This function should be called from a package's preinst so that other
+  # packages unpacked after this one --- but before this package's postinst runs
+  # --- are unpacked into new_location even if their payloads contain
+  # old_location filespecs.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "migrate_dir_to_symlink() called with wrong number of"
+                "arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local new old
+
+  old="$1"
+  new="$2"
+
+  # Is old location a symlink?
+  if [ -L "$old" ]; then
+    # Does it already point to new location?
+    if [ "$(readlink "$old")" = "$new" ]; then
+      # Nothing to do; migration has already been done.
+      observe "migration of $old to $new already done"
+      return 0
+    else
+      # Back it up.
+      warn "backing up symbolic link $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+    fi
+  fi
+
+  # Does old location exist, but is not a directory?
+  if [ -e "$old" ] && ! [ -d "$old" ]; then
+      # Back it up.
+      warn "backing up non-directory $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+  fi
+
+  observe "migrating $old to $new"
+
+  # Is new location a symlink?
+  if [ -L "$new" ]; then
+    # Does it point the wrong way, i.e., back to where we're migrating from?
+    if [ "$(readlink "$new")" = "$old" ]; then
+      # Get rid of it.
+      observe "removing symbolic link $new which points to $old"
+      rm "$new"
+    else
+      # Back it up.
+      warn "backing up symbolic link $new as $new.dpkg-old"
+      mv -b "$new" "$new.dpkg-old"
+    fi
+  fi
+
+  # Does new location exist, but is not a directory?
+  if [ -e "$new" ] && ! [ -d "$new" ]; then
+    warn "backing up non-directory $new as $new.dpkg-old"
+    mv -b "$new" "$new.dpkg-old"
+  fi
+
+  # Create new directory if it does not yet exist.
+  if ! [ -e "$new" ]; then
+    observe "creating $new"
+    mkdir -p "$new"
+  fi
+
+  # Copy files in old location to new location.  Back up any filenames that
+  # already exist in the new location with the extension ".dpkg-old".
+  observe "copying files from $old to $new"
+  if ! (cd "$old" && cp -a -b -S ".dpkg-old" . "$new"); then
+    die "error(s) encountered while copying files from $old to $new"
+  fi
+
+  # Remove files at old location.
+  observe "removing $old"
+  rm -r "$old"
+
+  # Create symlink from old location to new location.
+  make_symlink_sane "$old" "$new"
+}
+
+# vim:set ai et sw=2 ts=2 tw=80:
+
+# GOBSTOPPER: The X Strike Force shell library ends here.
diff --git a/doc/FAQ.html b/doc/FAQ.html
new file mode 100755 (executable)
index 0000000..18d4ee6
--- /dev/null
@@ -0,0 +1,344 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html lang="en">
+<HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<TITLE>FAQ XPM</TITLE>
+</HEAD>
+
+<body>
+<h1 align="center">The XPM<br>
+Frequently Asked Questions</h1>
+<p>
+This article contains the answers to some Frequently Asked Questions about the
+XPM format and/or library. If you don't find the answer to your problem here,
+then you can mail either to lehors@sophia.inria.fr or to the mailing list
+xpm-talk@sophia.inria.fr.
+
+
+<h2>Contents</h2>
+
+<ol>
+<li><a href="#Q1">How do I convert my images to or from XPM ?</a>
+<li><a href="#Q2">Why are my XPM files said to be invalid ?</a>
+<li><a href="#Q3">Why does my program core dumps using XPM ?</a>
+<li><a href="#Q4">Why does my program core dumps using XPM with a widget ?</a>
+<li><a href="#Q5">How can I get a non rectangular icon using XPM ?</a>
+<li><a href="#Q6">What exactly triggers the creation of a mask when using XPM ?</a>
+<li><a href="#Q7">How should I use the mask ?</a>
+<li><a href="#Q8">Is there a string to pixmap converter somewhere ?</a>
+<li><a href="#Q9">How can I edit XPM icons ?</a>
+<li><a href="#Q10">Is there a collection of icons somewhere ?</a>
+<li><a href="#Q11">The documentation fails to print out. Why ?</a>
+<li><a href="#copy">Copyright</a>
+</ol>
+
+
+<h2><a name="Q1">1. How do I convert my images to or from XPM ?</a></h2>
+<p>
+  Netpbm is surely the best image conversion package that I know of. It defines
+  formats for color, gray and monochrome images and provides a set of filters.
+  Thus a GIF image can be converted to XPM with something like:
+<p>
+  $ giftoppm youricon.gif | ppmtoxpm > youricon.xpm
+<p>
+  The latest release can be found at least from wuarchive.wustl.edu
+  (128.252.135.4), directory /graphics/graphics/packages/NetPBM
+
+
+<h2><a name="Q2">2. Why are my XPM files said to be invalid ?</a></h2>
+<p>
+  There are three official versions of the XPM format. The XPM library since
+  version 3.3 can read all them but writes out only XPM 3. Also the small
+  program called sxpm which is part of the XPM library package can be used to
+  automatically translate XPM 1 and 2 files to XPM 3 with a command such as:
+<p>
+  $ sxpm -nod yourxpm1or2file -o yourxpm3file
+<p>
+  Also, the XPM format defines "None" to be the color name meaning
+  "transparent", but IXI used to hack the XPM library in its early days to
+  handle transparency as "#Transparent". This makes IXI format not compatible
+  with the official XPM format, and so not readable neither by the official XPM
+  library nor any of the programs built on top of it.
+<p>
+  The only solutions are either to stick on IXI programs which can deal with
+  their format or convert your files to the standard XPM format. This can be
+  done simply by changing "#Transparent" to "None".
+
+
+<h2><a name="Q3">3. Why does my program core dumps using XPM ?</a></h2>
+<p>
+  Be sure the XpmAttributes structure you pass by reference has a valid
+  valuemask. You can give NULL instead if you don't want to use an
+  XpmAttributes but if you do, you MUST initialize its valuemask component to
+  some valid value, at least 0, otherwise unpredictable errors can occur.
+<p>
+  So instead of doing something like:
+<pre>
+      XpmAttributes attrib;
+
+      XpmReadFileToPixmap(dpy, d, filename, &amp;pixmap, &amp;mask, &amp;attrib);
+</pre>
+<p>
+  you should do:
+<pre>
+      XpmAttributes attrib;
+
+      attrib.valuemask = 0;
+      XpmReadFileToPixmap(dpy, d, filename, &amp;pixmap, &amp;mask, &amp;attrib);
+</pre>
+
+
+<h2><a name="Q4">4. Why does my program core dumps using XPM with a widget ?</a></h2>
+<ul>
+<li>First the XPM library is Xlib level, so don't pass your widget as a
+    Drawable parameter. A Drawable is either a Window or a Pixmap. The widget's
+    window can do the job but:
+
+<li>Then a widget only gets a Window when realized, so passing XtWindow(widget)
+    with a not yet realized widget is wrong. Either realize you widget first or
+    use another window. Since the Drawable parameter is only used to specify
+    the screen to which the pixmap must be created on, most of the time the
+    default root window is just fine.
+</ul>
+
+
+<h2><a name="Q5">5. How can I get a non rectangular icon using XPM ?</a></h2>
+<p>
+  The X Window System does not support transparent color. However there are
+  several ways you can use to get the same visual effect using XPM:
+<ul>
+<li>First you can use the None color to get a shape mask and use it as
+    explained below (question 7).
+
+<li>Second you can define a symbolic color name such as "mask" in the XPM
+    format file, then use the color overriding mechanism to set this symbolic
+    color to the color of the underlying object. Note that in this case the XPM
+    library won't create a shape mask, and that if the color of the underlying
+    object is changed then you'll have to create a new pixmap.
+</ul>
+
+
+<h2><a name="Q6">6. What exactly triggers the creation of a mask when using XPM ?</a></h2>
+<p>
+  Basically a mask is created if "None" is used as one of the color of the
+  pixmap. Be aware that this is not only true if it is used in the XPM of the
+  pixmap since the colors can be overridden at load time. So a mask is created
+  if the "None" color is used at load time, coming either from the XPM
+  definition or the color overriding.
+
+
+<h2><a name="Q7">7. How should I use the mask ?</a></h2>
+<p>
+  There are basically two ways of using the mask:
+<ul>
+<li>Use the mask as a shapemask with the X11 Nonrectangular Saphe Window
+    Extension. Typically this is what should be done when the icon is used in a
+    desktop.
+
+<li>Use the mask as a clipmask in the GC you pass to XCopyArea when drawing the
+    pixmap. So the "transparent" pixels being not actually drawn will get the
+    underlying pixels colors.
+</ul>
+
+
+<h2><a name="Q8">8. Is there a string to pixmap converter for Motif ?</a></h2>
+<p>
+ Yes, Motif 2.0 or later does support XPM pixmaps as well as XBM bitmaps.
+
+
+<h2><a name="Q9">9. How can I edit XPM icons ?</a></h2>
+<p>
+  As listed below several editors either commercial or not are supporting the
+  XPM format. However, pixmap is the one I would recommend since it is freely
+  available and, being fully dedicated to XPM, it allows to edit all the
+  special things, such as the symbolic color names, which makes XPM different
+  from all the other image formats. Pixmap can always be found by ftp from
+  ftp.x.org (contrib) and avahi.inria.fr (pub/pixmap).
+<p>
+Last Update: 3 August 1994
+<table border=1>
+<caption>XPM Icon Editors</caption>
+<tr><th>Program<th>Infos<th>Source/Author<th>Platforms<th>SA<th>XPM<th>cost
+<tr><td>pixmap<td><ul>
+   <li><a href="ftp://ftp.x.org/contrib/application/pixmap/pixmap2.6.tar.gz">ftp://ftp.x.org/contrib/application/pixmap/pixmap2.6.tar.gz</a>
+   <li>requires 3.4 or higher revision of Xpm lib.
+   <li>supports all XPM format features
+   <li>current version doesn't work on 24-plane displays
+</ul>
+<td>Lionel Mallet<td>source<td>yes<td>3<td>NC
+
+<tr><td>pixt<td><ul>
+   <li><a href="ftp://ftp.x.org/contrib/pixt.tar.Z">ftp://ftp.x.org/contrib/pixt.tar.Z</a>
+   <li>doesn't work on 24-plane displays
+   <li>last updated November 1991
+</ul>
+<td>J. Michael Flanery<td>source<td>yes<td>1<td>NC
+
+<tr><td>pixed<td><ul>
+   <li>part of X.desktop
+   <li>current version doesn't work on 24-plane displays
+</ul>
+<td>IXI<td>Many UNIX<td>no<td>3<td>N/A
+
+<tr><td>olpixmap<td><ul>
+   <li>packaged with the OLIT (OpenLook) toolkit
+</ul>
+<td>USL<td>Sun, SVR4.2, UnixWare<td>no<td>1<td>N/A
+
+<tr><td>xfedor<td><ul>
+   <li>only uses XLIB
+   <li>doesn't work on 24-plane displays
+</ul>
+<td>Daniel Dardailler<td>source<td>yes<td>3<td>NC
+
+<tr><td>SCOpaint<td><ul>
+   <li>included with the ODT package
+</ul>
+<td>SCO/Wing Eng<td>ODT<td>yes<td>2.8<td>N/A
+
+<tr><td>pme.icn<td><ul>
+   <li>written in the Icon language
+</ul>
+<td>Icon Project<td>source<td>yes<td>3<td>NC
+
+<tr><td>PixEditT<td><ul>
+   <li>there is currently no support for editing the colormap
+</ul>
+<td>Free Widget Foundation<td>source<td>yes<td>3<td>NC
+
+<tr><td>xscribble<td><ul>
+   <li>requires the FWF, 8-bit pseudocolor
+   <li><a href="ftp://ftp.cis.ufl.edu/pub/thoth">ftp://ftp.cis.ufl.edu/pub/thoth</a>
+   <li>Alpha version (last updated April 1993)
+</ul>
+<td>Robert Forsman<td>source<td>yes<td>?<td>NC
+
+<tr><td>vueicon<td><ul>
+   <li>included with Vue3.0
+</ul>
+<td>Hewlett-Packard<td>HP<td>yes<td>3<td>N/A
+
+<tr><td>iconedit V3<td>&nbsp;<td>SunSoft<td>Sparc/Sun3<td>yes<td>2<td>N/A
+
+<tr><td>Pixmap Editor<td><ul>
+   <li>this is a Widget, not a complete program
+</ul>
+<td>ICS<td>?<td>yes<td>?<td>?
+
+<tr><td>ezX<td>&nbsp;<td>Sunrise Softwarey<td>?<td>?<td>?<td>N/A
+
+<tr><td>XPaint<td><ul>
+     <li>full featured, works on all displays
+     <li>current release is 2.1.1 (last update January 1994)
+</ul>
+<td>David Koblas<td>source<td>yes<td>3<td>NC
+
+<tr><td>Phoenix<td><ul>
+    <li>full featured, 24-bit painting program, requires Motif.
+    <li><a href="ftp://nic.funet.fi/pub/graphics/packages/phoenix">ftp://nic.funet.fi/pub/graphics/packages/phoenix</a>
+    <li>Beta version (last updated September 1993)
+</ul>
+<td>ohtcolor@niksula.hut.fi<td>source<td>yes<td>3<td>NC
+
+<tr><td>pixed<td><ul>
+    <li>pixed is part of the TeleUSE UIMS
+    <li>More info is available from service@ignite.alsys.com
+</ul>
+<td>Alsys<td>Many UNIX<td>yes<td>3<td>N/A
+
+<tr><td>display<td><ul>
+   <li><a href="ftp://ftp.x.org/contrib/application/ImageMagick/ImageMagick-3.2.tar.gz">ftp://ftp.x.org/contrib/application/ImageMagick/ImageMagick-3.2.tar.gz</a>
+   <li>lots of image conversion and manipulation features
+</ul>
+<td>John Cristy<td>source<td>yes<td>3<td>NC
+</table>
+
+<p>
+SA - Stand Alone program<br>
+NC - No Charge (i.e. free); most programs are copyrighted.<br>
+XPM - XPM format supported<br>
+source - built from source code; likely works on all standard X platforms<br>
+N/A - icon editor is normally distributed with other software
+
+<p>
+Send updates, additions, corrections, etc. to <a
+href="mailto:dan@bristol.com">dan@bristol.com</a>
+
+
+<h2><a name="Q10">10. Is there a collection of icons somewhere ?</a></h2>
+<p>
+  At least there is one freely available: Anthony's X Icon Library. You can
+  found it on several ftp servers, such as <a href="ftp://server.berkeley.edu/pub/AIcons">server.berkeley.edu/pub/AIcons</a>. It
+  contains only small icons (less than about 100x100 pixels in size) which are
+  stored in groups in a logical way. Color icons are stored in XPM format and
+  Black & White icons in XBM.
+
+
+<h2><a name="Q11">11. The documentation fails to print out. Why ?</a></h2>
+<p>
+  The PostScript documentation file is formatted for US letter paper. Frame
+  Maker tries very hard to ensure that you have the right paper and punts if
+  you don't. However, you can easily work around this problem by applying the
+  following patch. If for some reason applying the patch fails, you can still
+  do it by hand. Just locate the corresponding block in the PS file and remove
+  the lines with a leading '-' character.
+  By the way, this applies to any doc generated by Frame Maker. The
+  corresponding block might be slightly different depending on which version of
+  Frame Maker was used, but it is still easy to locate.
+
+<pre>
+*** xpm.PS      Wed Sep 11 15:47:43 1996
+--- xpm-A4.PS   Thu Nov 21 09:27:28 1996
+***************
+*** 647,668 ****
+        0 ne /edown exch def 
+        /yscale exch def
+        /xscale exch def
+-       FMLevel1 {
+-               manualfeed {setmanualfeed} if
+-               /FMdicttop countdictstack 1 add def 
+-               /FMoptop count def 
+-               setpapername 
+-               manualfeed {true} {papersize} ifelse 
+-               {manualpapersize} {false} ifelse 
+-               {desperatepapersize} {false} ifelse 
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-               count -1 FMoptop {pop pop} for
+-               countdictstack -1 FMdicttop {pop end} for 
+-               }
+-               {{1 dict dup /PageSize [paperwidth paperheight]put setpagedevice}stopped
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-                {1 dict dup /ManualFeed manualfeed put setpagedevice } stopped pop }
+-       ifelse 
+        
+        FMPColor {
+                currentcolorscreen
+--- 647,652 ----
+</pre>
+
+
+<hr>
+<h2><a name="copy">Copyright (C) 1989-95 GROUPE BULL</a></h2>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+<p>
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+<p>
+Except as contained in this notice, the name of GROUPE BULL shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from GROUPE BULL.
+</body>
+</html>
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100755 (executable)
index 0000000..5119700
--- /dev/null
@@ -0,0 +1,6 @@
+EXTRA_DIST = \
+       xpm.PS.gz \
+       FAQ.html \
+       README.AMIGA \
+       README.html \
+       README.MSW
diff --git a/doc/README.AMIGA b/doc/README.AMIGA
new file mode 100755 (executable)
index 0000000..7a40137
--- /dev/null
@@ -0,0 +1,10 @@
+The XPM library for Amiga works best with AmigaOS 3.x, but will work
+(with limited color support) with earlier OS versions too. It can be
+compiled with both SAS/C and GCC (makefiles are included).
+
+All functions except the Xpm*Pixmap* functions are supported.
+
+I have also written some Amiga-specific utility functions (not
+included). Contact me if you would like to have them too.
+
+-Lorens Younes (d93-hyo@nada.kth.se)
diff --git a/doc/README.MSW b/doc/README.MSW
new file mode 100755 (executable)
index 0000000..f631525
--- /dev/null
@@ -0,0 +1,127 @@
+
+README.MSW     hedu@cul-ipn.uni-kiel.de        5/94
+
+               The XPM library for MS-Windows
+               
+Motivated by the wxWindows library, which is a (freely available) toolkit
+for developing multi-platform, graphical applications from the same body 
+of C++ code, I wanted to have XPM pixmaps for MS-windows. Instead of rewriting 
+a XPM-parser I managed to port the XPM-library-code to MS-windows.
+Thanks to Anaud Le Hors this became a part of the official XPM-library.
+
+Until now it's only used together with wxWindows. And even there it's more 
+a kind of beta. But it should be possible to run it as a simple libxpm.a 
+without wxWindows.
+
+The key is a transformation of some X types plus some basic X functions.
+There is not yet a special MSW-API, so you should know the X types used.
+
+The following is done in simx.h:
+
+typedef HDC Display;
+typedef COLORREF Pixel;
+
+typedef struct {
+    Pixel pixel;
+    BYTE red, green, blue;
+}      XColor;
+
+typedef struct {
+    HBITMAP bitmap;
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+}      XImage;
+
+With these defines and the according functions from simx.c you can call
+XPM-functions the way it's done under X windows. It can look like this:
+
+       ErrorStatus=XpmCreateImageFromData(&dc, data, 
+                               &ximage,(XImage **)NULL, &xpmAttr);
+       ms_bitmap = ximage->bitmap;
+       // releases the malloc,but do not destroy the bitmap
+       XImageFree(ximage);
+       
+Supported functions are the Xpm*Image* but not the Xpm*Pixmap*.
+
+DRAWBACKS:
+The main drawback is the missing support for Colormaps! There was nothing for
+it in wxWindows, so I did not know how to deal with Colormaps.
+
+The size of the pixmaps is bounded by malloc() (width*height*2 < 64K).
+
+Close colors do not look that close. But that seems to be the window system.
+
+Neither a special API for MSW nor a special MSW documentation other than this.
+(I can only point you to wxxpm as an example , see below.)
+
+INSTALLATION:
+There is not yet a makefile with it. Simply take all the *.c files
+into your project except the files related to Pixmap operations: *P*.c.
+!!!You MUST set FOR_MSW on the preprocessor options!!!
+(You might uncomment NEED_STRCASECMP in xpm.h if it's in your lib)
+This should compile into libxpm.a. Good luck...
+
+FTP:  
+wxWindows is currently available from the Artificial Intelligence
+Applications Institute (University of Edinburgh) by anonymous FTP.
+       skye.aiai.ed.ac.uk  pub/wxwin/
+or read http://burray.aiai.ed.ac.uk/aiai/aiai.html
+
+wxxpm, XPM support for wxWindows, the latest version is available at
+       yoda.cul-ipn.uni-kiel.de pub/wxxpm/
+       and maybe in the contrib or tools of wxWindows
+       
+Please contact me if you have suggestions, comments or problems!
+
+================================================================
+Some fixes and comments by Jan Wielemaker (jan@swi.psy.uva.nl),
+Oct 24, 1996:
+
+       * Please try not to disturb me on this, XPM is not my
+       piece of cake.
+
+       * Hermann Dunkel has appearently moved in virtual space.
+
+Changes:
+
+       * I've used the xpm package under NT 4.0 and MSVC++ 4.2.
+
+       * I've made a big performance improvement in 
+       ParseAndPutPixels(), fixed creation of the mask in
+       SetColor() in create.c.  I looked into XCreateImage()
+       in simx.c, but commented out my improvement for reasons
+       you'll find there.  If you know what is going on, statement
+       (1) does not apply to you.
+
+Comments on installation:
+
+       * Donot include the to/from pixmap files into the project.
+       These are the ones containing a capital P somewhere in their
+       name.  You can also first include all, and then remove all
+       the files you get errors on :-)
+
+       * The DC that is requested should be a valid memory DC, thus
+       CreateCompatibleDC(NULL) provides a good generic one, but
+       GetDC(NULL) doesn't!  This costed me some time.
+
+       * The real difficulty is using the mask, mostly due to the
+       bad documentation.  If 95 or NT is your target, use:
+
+       MaskBlt(context.hdc,    // Destination DC
+               x, y, w, h,     // Destination area
+               mhdc,           // Memory DC with the image selected
+               sx, sy,         // Source X,Y
+               msk,            // HBITMAP of the mask
+               sx, sy,         // Mask X,Y
+               MAKEROP4(SRCPAINT, SRCCOPY));   // The magic op code.
+================================================================
+
+
+--
+   ////|\\\\   \\\\\\  Hermann Dunkel
+     O   O     //////  IPN Uni Kiel, Germany
+       |       \\\\\\  Tel: +49 431 / 880 3144
+     \___/     //////  E-mail: hedu@cul-ipn.uni-kiel.de
+      \_/      \\\\\\  X.400 : c=de;a=d400;p=uni-kiel;ou=nw-didaktik;s=dunkel
+
diff --git a/doc/README.html b/doc/README.html
new file mode 100755 (executable)
index 0000000..6711f23
--- /dev/null
@@ -0,0 +1,303 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html lang="en">
+<HEAD>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<TITLE>XPM README</TITLE>
+</HEAD>
+
+<body>
+<h1 align="center">XPM README</h1>
+
+<h2>Contents</h2>
+
+<ol>
+<li><a href="#sec1">What Is XPM?</a>
+<li><a href="#sec2">Where to get XPM?</a>
+<li><a href="#sec3">Documentation</a>
+<li><a href="#sec4">Installation</a>
+<ol>
+<li><a href="#sec4.1">With imake</a>
+<li><a href="#sec4.2">Without imake</a>
+</ol>
+<li><a href="#sec5">SXPM</a>
+<li><a href="#sec6">CXPM</a>
+<li><a href="#sec7">Other Tools</a>
+<li><a href="#sec8">Discussion</a>
+<li><a href="#copy">Copyright</a>
+</ol>
+
+
+<h2><a name="sec1">1. What Is XPM?</a></h2>
+<p>
+XPM (X PixMap) is a format for storing/retrieving X pixmaps to/from files.
+<p>
+Here is provided a library containing a set of four functions, similar to the
+X bitmap functions as defined in the Xlib: <code>XpmCreatePixmapFromData</code>,
+<code>XpmCreateDataFromPixmap</code>, <code>XpmReadFileToPixmap</code> and <code>XpmWriteFileFromPixmap</code> for
+respectively including, storing, reading and writing this format, plus four
+other: <code>XpmCreateImageFromData</code>, <code>XpmCreateDataFromImage</code>, <code>XpmReadFileToImage</code> and
+<code>XpmWriteFileFromImage</code> for working with images instead of pixmaps.
+<p>
+This new version provides a C includable format, defaults for different types
+of display: monochrome/color/grayscale, hotspot coordinates and symbol names
+for colors for overriding default colors when creating the pixmap. It provides
+a mechanism for storing information while reading a file which is re-used
+while writing. This way comments, default colors and symbol names aren't lost.
+It also handles "transparent pixels" by returning a shape mask in addition to
+the created pixmap.
+<p>
+See the XPM Manual for details.
+
+
+<h2><a name="sec2">2. Where to get XPM?</a></h2>
+<p>
+New XPM updates are announced on the comp.windows.x newsgroup, and on the
+"xpm-talk" list and you can always consult the XPM Home page at <a
+href="http://www.inria.fr/koala/lehors/xpm.html">http://www.inria.fr/koala/lehors/xpm.html</a>
+<p>The latest "official" XPM release can always be found at:
+<br>Boston, USA: <a
+href="ftp://ftp.x.org/contrib">ftp://ftp.x.org/contrib</a>
+<br>Sophia Antipolis, France: <a
+href="ftp://koala.inria.fr/pub/xpm">ftp://koala.inria.fr/pub/xpm</a>
+
+
+<h2><a name="sec3">3. Documentation</a></h2>
+<p>
+Old users might read the <a href="CHANGES">CHANGES</a> file for a history
+of changes interesting the user.
+<p>
+Read the doc. The documentation is in PostScript format (<a
+href="doc/xpm.PS">doc/xpm.PS</a>) and has been produced with
+FrameMaker. The source files are available on request.
+<p>
+A <a href="FAQ.html">FAQ</a> (Frequently Asked Questions) is also provided,
+so if you experience any problem you should have a look at this file.
+
+
+<h2><a name="sec4">4. Installation</a></h2>
+<p>
+To obtain the XPM library, first uncompress and untar the compressed tar file
+in an appropriate directory.
+<p>
+Then you can either compile XPM via "imake" or in a stand-alone way.
+
+<h3><a name="sec4.1">4.1. With imake</a></h3>
+<p>
+       Imakefiles are provided to build both shared and unshared libraries.
+       However, building a shared lib is very OS dependent and often requires
+       specific files which are not available. Also config files are often not
+       set correctly for this task. So if it fails you can avoid trying to
+       build one and simply build the static library instead. In order to do
+       so you should edit the top Imakefile to add -DSharedLibXpm=NO to the
+       definition of IMAKE_DEFINES as described.
+<p>
+       The compilation and installation of the library and the sxpm program
+       should only require you to edit the top Imakefile. But you should do so
+       in order to specify the locations where the various files should be
+       installed and to set the DEFINES variable accordingly to your system.
+<p>
+       On Solaris 2.* the compilation works only in the native svr4
+       environment, avoid the bsd one or it won't compile. Especially you
+       should be using /opt/SUNWspro/bin/cc and not /usr/ucb/cc.
+       Also since the compiler is no longer part of the OS distribution a lot
+       of people use gcc instead. This is fine, but be aware that the imake
+       tool you get as part of the X Window System on a solaris box is
+       configured for cc. Therefore the compilation using the generated
+       Makefiles will not succeed unless you have changed the default
+       configuration. An easy work around is to directly edit the generated
+       lib/Makefile to change '-K pic' to '-fpic'. Fixing your imake
+       configuration would be better though.
+<p>
+       On Linux, if you do not use ELF yet you'd better get the binary
+       distribution available from sunsite. Because it's really a pain to
+       build a shared lib and the current XPM distribution doesn't contain
+       the jump files you would need to do so. On the other hand people have
+       had no problems building it using ELF.
+<p>
+       Then execute the following command:
+<pre>
+               xmkmf -a
+</pre>
+<p>
+       or if this option is not supported by your version of xmkmf:
+<pre>
+               xmkmf
+               make Makefiles
+               make includes
+               make depend             (optional)
+</pre>
+<p>
+       Then simply execute: 
+<pre>
+               make
+</pre>
+<p>
+       which will build the XPM library and the sxpm application. 
+       Then do:
+<pre>
+               make install
+               make install.man
+</pre>
+<p>
+       which will install the library and the sxpm program and man page.
+<p>
+       If it fails, be sure you have set the DEFINES correctly in the top
+       Imakefile to suit your machine.
+
+<h4>NOTE ON USING IMAKE:</h4>
+<p>
+       Building the XPM distribution with imake requires to have imake
+       <strong>correctly installed and configured</strong> on your
+       system. I do my best at tweaking the Imakefiles so they work with
+       as many imake flavors people might have as possible but there is
+       nothing I can do against wrong imake configurations. So if your
+       build fails using imake, don't send me email for advice. Get your
+       imake configuration fixed or forget about it!
+
+
+<h3><a name="sec4.2">4.2. Without imake</a></h3>
+<p>
+       A set of makefiles is provided for those who do not have imake
+       available on their system. However, this is only provided as a
+       convenience and you should be considered as a starting point and not as
+       something ready to use. These makefiles, called Makefile.noX, will most
+       likely require some editing in order be set accordingly to your system.
+<p>
+       Once this setting is done, you should be able to compile XPM, by
+       executing the following command:
+<pre>
+               make -f Makefile.noX
+</pre>
+<p>
+       Then to install it, do:
+<pre>
+               make -f Makefile.noX install
+</pre>
+
+
+<h2><a name="sec5">5. SXPM</a></h2>
+<p>
+In addition to the library the sxpm tool is provided to show XPM file and
+convert them from XPM1 or XPM2 to XPM version 3. If you have previously done
+'make' or 'make all' you should already have it, otherwise just do:
+<pre>
+                     cd sxpm; make
+</pre>
+<p>
+This application shows you most of the features of XPM and its source can be
+used to quickly see how to use the provided functions.
+<p>
+By executing 'sxpm -help' you will get the usage.
+<p>
+Executing 'sxpm -plaid' will show a demo of the XpmCreatePixmapFromData
+function. The pixmap is created from the static variable plaid defined in the
+sxpm.c file. sxpm will end when you press the key 'q' in the created window.
+<p>
+Executing 'sxpm -plaid -sc lines_in_mix blue' will show the feature of
+overriding color symbols giving a colorname, executing 'sxpm -plaid -sp
+lines_in_mix 1' will show overriding giving a pixel value, and executing 'sxpm
+-plaid -cp red 0' will show overriding giving a color value.
+<p>
+Then you should try 'sxpm -plaid -o output' to get an output file using the
+XpmWriteFileFromPixmap function.
+<p>
+You can now try 'sxpm -plaid -o - -nod -rgb /usr/lib/X11/rgb.txt' to directly
+get the pixmap printed out on the standard output with colornames instead of
+rgb values.
+<p>
+Then you should try 'sxpm plaid.xpm' to use the XpmReadFileToPixmap function,
+and 'cat plaid_mask.xpm|sxpm' to see how "transparent pixels" are handled.
+<p>
+The XpmCreatePixmapFromData function is on purpose called without any XpmInfos
+flag to show the utility of this one. Indeed, compare the color section of the
+two files foo and bar obtained from 'sxpm -nod -plaid -o foo' and 'sxpm -nod
+plaid.xpm -o bar'. All the default colors and also the comments have been
+restored.
+<p>
+To end look at plaid_ext.xpm and try "sxpm -nod plaid_ext.xpm -v" to see how
+extensions are handled.
+<p>
+Of course, other combinations are allowed and should be tried. Thus, 'sxpm
+plaid.xpm -o output -nod' will show you how to convert a file from XPM1 or XPM2
+to a XPM version 3 using sxpm.
+<p>
+See the manual page for more detail.
+
+
+<h2><a name="sec6">6. CXPM</a></h2>
+<p>
+The cxpm tool is provided to help you figure out whether an XPM file is correct
+or not with regard to its format. If you have previously done 'make' or
+'make all' you should already have it, otherwise just do:
+<pre>
+                     cd cxpm; make
+</pre>
+<p>
+The related man page will tell you everything about it but here is a simple
+example of what it does:
+<pre>
+$ ./cxpm bogus_pixmap
+Xpm Error: Invalid XPM file.
+Error found line 3 near character 5
+</pre>
+<p>
+It is pretty limited but at least, unlike sxpm, it gives you some hint on where
+the error occured within the file.
+
+
+<h2><a name="sec7">7. Other Tools</a></h2>
+<p>
+Several converters dealing with XPM and a pixmap editor can be found in the
+xpm-contrib distribution. Also I recommend the use of netpbm to do any kind of
+general image operations such as scaling, resizing, dithering, and to convert
+from and to any other image format.
+
+<h2><a name="sec8">8. Discussion</a></h2>
+<p>
+There is a mailing list to discuss about XPM which is <a
+href="mailto:xpm-talk@sophia.inria.fr">xpm-talk@sophia.inria.fr</a>.
+Any request to subscribe should be sent to <a
+href="mailto:xpm-talk-request@sophia.inria.fr">xpm-talk-request@sophia.inria.fr</a>.
+The archive of the xpm-talk list is available through the web at
+<a
+href="http://zenon.inria.fr/koala/xpm-talk-hypermail">http://zenon.inria.fr/koala/xpm-talk-hypermail</a>
+and through ftp at <a
+href="ftp://koala.inria.fr/pub/xpm/xpm-talk-archive">ftp://koala.inria.fr/pub/xpm/xpm-talk-archive</a>
+<p>
+Please mail any bug reports or modifications done, comments, suggestions,
+requests for updates or patches to port on another machine to:
+
+<p>Email: <a href="lehors@sophia.inria.fr">lehors@sophia.inria.fr</a>
+<br>Phone: +33 (0)4 93 65 78 89
+<br>Surface Mail:<br>
+Arnaud Le Hors<br>
+Inria BP.93<br>
+2004, Route des lucioles<br>
+06902 Sophia Antipolis Cedex<br>
+FRANCE
+
+
+<hr>
+<h2><a name="copy">Copyright (C) 1989-95 GROUPE BULL</a></h2>
+<p>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to
+deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+sell copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+<p>
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+<p>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+<p>
+Except as contained in this notice, the name of GROUPE BULL shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from GROUPE BULL.
+</body>
diff --git a/doc/xpm.PS.gz b/doc/xpm.PS.gz
new file mode 100755 (executable)
index 0000000..40e25de
Binary files /dev/null and b/doc/xpm.PS.gz differ
diff --git a/include/Makefile.am b/include/Makefile.am
new file mode 100755 (executable)
index 0000000..99970a5
--- /dev/null
@@ -0,0 +1 @@
+nobase_include_HEADERS = X11/xpm.h
diff --git a/include/X11/xpm.h b/include/X11/xpm.h
new file mode 100755 (executable)
index 0000000..38c62d8
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* xpm.h:                                                                      *
+*                                                                             *
+*  XPM library                                                                *
+*  Include file                                                               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#ifndef XPM_h
+#define XPM_h
+
+/*
+ * first some identification numbers:
+ * the version and revision numbers are determined with the following rule:
+ * SO Major number = LIB minor version number.
+ * SO Minor number = LIB sub-minor version number.
+ * e.g: Xpm version 3.2f
+ *      we forget the 3 which is the format number, 2 gives 2, and f gives 6.
+ *      thus we have XpmVersion = 2 and XpmRevision = 6
+ *      which gives  SOXPMLIBREV = 2.6
+ *
+ * Then the XpmIncludeVersion number is built from these numbers.
+ */
+#define XpmFormat 3
+#define XpmVersion 4
+#define XpmRevision 11
+#define XpmIncludeVersion ((XpmFormat * 100 + XpmVersion) * 100 + XpmRevision)
+
+#ifndef XPM_NUMBERS
+
+#ifdef FOR_MSW
+# define SYSV                  /* uses memcpy string.h etc. */
+# include <malloc.h>
+# include "simx.h"             /* defines some X stuff using MSW types */
+#define NEED_STRCASECMP                /* at least for MSVC++ */
+#else /* FOR_MSW */
+# ifdef AMIGA
+#  include "amigax.h"
+# else /* not AMIGA */
+#  include <X11/Xlib.h>
+#  include <X11/Xutil.h>
+# endif /* not AMIGA */
+#endif /* FOR_MSW */
+
+/* let's define Pixel if it is not done yet */
+#if ! defined(_XtIntrinsic_h) && ! defined(PIXEL_ALREADY_TYPEDEFED)
+typedef unsigned long Pixel;   /* Index into colormap */
+# define PIXEL_ALREADY_TYPEDEFED
+#endif
+
+/* Return ErrorStatus codes:
+ * null     if full success
+ * positive if partial success
+ * negative if failure
+ */
+
+#define XpmColorError    1
+#define XpmSuccess       0
+#define XpmOpenFailed   -1
+#define XpmFileInvalid  -2
+#define XpmNoMemory     -3
+#define XpmColorFailed  -4
+
+typedef struct {
+    char *name;                        /* Symbolic color name */
+    char *value;               /* Color value */
+    Pixel pixel;               /* Color pixel */
+}      XpmColorSymbol;
+
+typedef struct {
+    char *name;                        /* name of the extension */
+    unsigned int nlines;       /* number of lines in this extension */
+    char **lines;              /* pointer to the extension array of strings */
+}      XpmExtension;
+
+typedef struct {
+    char *string;              /* characters string */
+    char *symbolic;            /* symbolic name */
+    char *m_color;             /* monochrom default */
+    char *g4_color;            /* 4 level grayscale default */
+    char *g_color;             /* other level grayscale default */
+    char *c_color;             /* color default */
+}      XpmColor;
+
+typedef struct {
+    unsigned int width;                /* image width */
+    unsigned int height;       /* image height */
+    unsigned int cpp;          /* number of characters per pixel */
+    unsigned int ncolors;      /* number of colors */
+    XpmColor *colorTable;      /* list of related colors */
+    unsigned int *data;                /* image data */
+}      XpmImage;
+
+typedef struct {
+    unsigned long valuemask;   /* Specifies which attributes are defined */
+    char *hints_cmt;           /* Comment of the hints section */
+    char *colors_cmt;          /* Comment of the colors section */
+    char *pixels_cmt;          /* Comment of the pixels section */
+    unsigned int x_hotspot;    /* Returns the x hotspot's coordinate */
+    unsigned int y_hotspot;    /* Returns the y hotspot's coordinate */
+    unsigned int nextensions;  /* number of extensions */
+    XpmExtension *extensions;  /* pointer to array of extensions */
+}      XpmInfo;
+
+typedef int (*XpmAllocColorFunc)(
+    Display*                   /* display */,
+    Colormap                   /* colormap */,
+    char*                      /* colorname */,
+    XColor*                    /* xcolor */,
+    void*                      /* closure */
+);
+
+typedef int (*XpmFreeColorsFunc)(
+    Display*                   /* display */,
+    Colormap                   /* colormap */,
+    Pixel*                     /* pixels */,
+    int                                /* npixels */,
+    void*                      /* closure */
+);
+
+typedef struct {
+    unsigned long valuemask;           /* Specifies which attributes are
+                                          defined */
+
+    Visual *visual;                    /* Specifies the visual to use */
+    Colormap colormap;                 /* Specifies the colormap to use */
+    unsigned int depth;                        /* Specifies the depth */
+    unsigned int width;                        /* Returns the width of the created
+                                          pixmap */
+    unsigned int height;               /* Returns the height of the created
+                                          pixmap */
+    unsigned int x_hotspot;            /* Returns the x hotspot's
+                                          coordinate */
+    unsigned int y_hotspot;            /* Returns the y hotspot's
+                                          coordinate */
+    unsigned int cpp;                  /* Specifies the number of char per
+                                          pixel */
+    Pixel *pixels;                     /* List of used color pixels */
+    unsigned int npixels;              /* Number of used pixels */
+    XpmColorSymbol *colorsymbols;      /* List of color symbols to override */
+    unsigned int numsymbols;           /* Number of symbols */
+    char *rgb_fname;                   /* RGB text file name */
+    unsigned int nextensions;          /* Number of extensions */
+    XpmExtension *extensions;          /* List of extensions */
+
+    unsigned int ncolors;               /* Number of colors */
+    XpmColor *colorTable;               /* List of colors */
+/* 3.2 backward compatibility code */
+    char *hints_cmt;                    /* Comment of the hints section */
+    char *colors_cmt;                   /* Comment of the colors section */
+    char *pixels_cmt;                   /* Comment of the pixels section */
+/* end 3.2 bc */
+    unsigned int mask_pixel;            /* Color table index of transparent
+                                           color */
+
+    /* Color Allocation Directives */
+    Bool exactColors;                  /* Only use exact colors for visual */
+    unsigned int closeness;            /* Allowable RGB deviation */
+    unsigned int red_closeness;                /* Allowable red deviation */
+    unsigned int green_closeness;      /* Allowable green deviation */
+    unsigned int blue_closeness;       /* Allowable blue deviation */
+    int color_key;                     /* Use colors from this color set */
+
+    Pixel *alloc_pixels;               /* Returns the list of alloc'ed color
+                                          pixels */
+    int nalloc_pixels;                 /* Returns the number of alloc'ed
+                                          color pixels */
+
+    Bool alloc_close_colors;           /* Specify whether close colors should
+                                          be allocated using XAllocColor
+                                          or not */
+    int bitmap_format;                 /* Specify the format of 1bit depth
+                                          images: ZPixmap or XYBitmap */
+
+    /* Color functions */
+    XpmAllocColorFunc alloc_color;     /* Application color allocator */
+    XpmFreeColorsFunc free_colors;     /* Application color de-allocator */
+    void *color_closure;               /* Application private data to pass to
+                                          alloc_color and free_colors */
+
+}      XpmAttributes;
+
+/* XpmAttributes value masks bits */
+#define XpmVisual         (1L<<0)
+#define XpmColormap       (1L<<1)
+#define XpmDepth          (1L<<2)
+#define XpmSize                   (1L<<3)      /* width & height */
+#define XpmHotspot        (1L<<4)      /* x_hotspot & y_hotspot */
+#define XpmCharsPerPixel   (1L<<5)
+#define XpmColorSymbols           (1L<<6)
+#define XpmRgbFilename    (1L<<7)
+/* 3.2 backward compatibility code */
+#define XpmInfos          (1L<<8)
+#define XpmReturnInfos    XpmInfos
+/* end 3.2 bc */
+#define XpmReturnPixels           (1L<<9)
+#define XpmExtensions      (1L<<10)
+#define XpmReturnExtensions XpmExtensions
+
+#define XpmExactColors     (1L<<11)
+#define XpmCloseness      (1L<<12)
+#define XpmRGBCloseness           (1L<<13)
+#define XpmColorKey       (1L<<14)
+
+#define XpmColorTable      (1L<<15)
+#define XpmReturnColorTable XpmColorTable
+
+#define XpmReturnAllocPixels (1L<<16)
+#define XpmAllocCloseColors (1L<<17)
+#define XpmBitmapFormat    (1L<<18)
+
+#define XpmAllocColor      (1L<<19)
+#define XpmFreeColors      (1L<<20)
+#define XpmColorClosure    (1L<<21)
+
+
+/* XpmInfo value masks bits */
+#define XpmComments        XpmInfos
+#define XpmReturnComments  XpmComments
+
+/* XpmAttributes mask_pixel value when there is no mask */
+#ifndef FOR_MSW
+#define XpmUndefPixel 0x80000000
+#else
+/* int is only 16 bit for MSW */
+#define XpmUndefPixel 0x8000
+#endif
+
+/*
+ * color keys for visual type, they must fit along with the number key of
+ * each related element in xpmColorKeys[] defined in XpmI.h
+ */
+#define XPM_MONO       2
+#define XPM_GREY4      3
+#define XPM_GRAY4      3
+#define XPM_GREY       4
+#define XPM_GRAY       4
+#define XPM_COLOR      5
+
+
+/* macros for forward declarations of functions with prototypes */
+#define FUNC(f, t, p) extern t f p
+#define LFUNC(f, t, p) static t f p
+
+
+/*
+ * functions declarations
+ */
+
+_XFUNCPROTOBEGIN
+
+/* FOR_MSW, all ..Pixmap.. are excluded, only the ..XImage.. are used */
+/* Same for Amiga! */
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+    FUNC(XpmCreatePixmapFromData, int, (Display *display,
+                                       Drawable d,
+                                       char **data,
+                                       Pixmap *pixmap_return,
+                                       Pixmap *shapemask_return,
+                                       XpmAttributes *attributes));
+
+    FUNC(XpmCreateDataFromPixmap, int, (Display *display,
+                                       char ***data_return,
+                                       Pixmap pixmap,
+                                       Pixmap shapemask,
+                                       XpmAttributes *attributes));
+
+    FUNC(XpmReadFileToPixmap, int, (Display *display,
+                                   Drawable d,
+                                   char *filename,
+                                   Pixmap *pixmap_return,
+                                   Pixmap *shapemask_return,
+                                   XpmAttributes *attributes));
+
+    FUNC(XpmWriteFileFromPixmap, int, (Display *display,
+                                      char *filename,
+                                      Pixmap pixmap,
+                                      Pixmap shapemask,
+                                      XpmAttributes *attributes));
+#endif
+
+    FUNC(XpmCreateImageFromData, int, (Display *display,
+                                      char **data,
+                                      XImage **image_return,
+                                      XImage **shapemask_return,
+                                      XpmAttributes *attributes));
+
+    FUNC(XpmCreateDataFromImage, int, (Display *display,
+                                      char ***data_return,
+                                      XImage *image,
+                                      XImage *shapeimage,
+                                      XpmAttributes *attributes));
+
+    FUNC(XpmReadFileToImage, int, (Display *display,
+                                  char *filename,
+                                  XImage **image_return,
+                                  XImage **shapeimage_return,
+                                  XpmAttributes *attributes));
+
+    FUNC(XpmWriteFileFromImage, int, (Display *display,
+                                     char *filename,
+                                     XImage *image,
+                                     XImage *shapeimage,
+                                     XpmAttributes *attributes));
+
+    FUNC(XpmCreateImageFromBuffer, int, (Display *display,
+                                        char *buffer,
+                                        XImage **image_return,
+                                        XImage **shapemask_return,
+                                        XpmAttributes *attributes));
+#if !defined(FOR_MSW) && !defined(AMIGA)
+    FUNC(XpmCreatePixmapFromBuffer, int, (Display *display,
+                                         Drawable d,
+                                         char *buffer,
+                                         Pixmap *pixmap_return,
+                                         Pixmap *shapemask_return,
+                                         XpmAttributes *attributes));
+
+    FUNC(XpmCreateBufferFromImage, int, (Display *display,
+                                        char **buffer_return,
+                                        XImage *image,
+                                        XImage *shapeimage,
+                                        XpmAttributes *attributes));
+
+    FUNC(XpmCreateBufferFromPixmap, int, (Display *display,
+                                         char **buffer_return,
+                                         Pixmap pixmap,
+                                         Pixmap shapemask,
+                                         XpmAttributes *attributes));
+#endif
+    FUNC(XpmReadFileToBuffer, int, (char *filename, char **buffer_return));
+    FUNC(XpmWriteFileFromBuffer, int, (char *filename, char *buffer));
+
+    FUNC(XpmReadFileToData, int, (char *filename, char ***data_return));
+    FUNC(XpmWriteFileFromData, int, (char *filename, char **data));
+
+    FUNC(XpmAttributesSize, int, (void));
+    FUNC(XpmFreeAttributes, void, (XpmAttributes *attributes));
+    FUNC(XpmFreeExtensions, void, (XpmExtension *extensions,
+                                  int nextensions));
+
+    FUNC(XpmFreeXpmImage, void, (XpmImage *image));
+    FUNC(XpmFreeXpmInfo, void, (XpmInfo *info));
+    FUNC(XpmGetErrorString, char *, (int errcode));
+    FUNC(XpmLibraryVersion, int, (void));
+
+    /* XpmImage functions */
+    FUNC(XpmReadFileToXpmImage, int, (char *filename,
+                                     XpmImage *image,
+                                     XpmInfo *info));
+
+    FUNC(XpmWriteFileFromXpmImage, int, (char *filename,
+                                        XpmImage *image,
+                                        XpmInfo *info));
+#if !defined(FOR_MSW) && !defined(AMIGA)
+    FUNC(XpmCreatePixmapFromXpmImage, int, (Display *display,
+                                           Drawable d,
+                                           XpmImage *image,
+                                           Pixmap *pixmap_return,
+                                           Pixmap *shapemask_return,
+                                           XpmAttributes *attributes));
+#endif
+    FUNC(XpmCreateImageFromXpmImage, int, (Display *display,
+                                          XpmImage *image,
+                                          XImage **image_return,
+                                          XImage **shapeimage_return,
+                                          XpmAttributes *attributes));
+
+    FUNC(XpmCreateXpmImageFromImage, int, (Display *display,
+                                          XImage *image,
+                                          XImage *shapeimage,
+                                          XpmImage *xpmimage,
+                                          XpmAttributes *attributes));
+#if !defined(FOR_MSW) && !defined(AMIGA)
+    FUNC(XpmCreateXpmImageFromPixmap, int, (Display *display,
+                                           Pixmap pixmap,
+                                           Pixmap shapemask,
+                                           XpmImage *xpmimage,
+                                           XpmAttributes *attributes));
+#endif
+    FUNC(XpmCreateDataFromXpmImage, int, (char ***data_return,
+                                         XpmImage *image,
+                                         XpmInfo *info));
+
+    FUNC(XpmCreateXpmImageFromData, int, (char **data,
+                                         XpmImage *image,
+                                         XpmInfo *info));
+
+    FUNC(XpmCreateXpmImageFromBuffer, int, (char *buffer,
+                                           XpmImage *image,
+                                           XpmInfo *info));
+
+    FUNC(XpmCreateBufferFromXpmImage, int, (char **buffer_return,
+                                           XpmImage *image,
+                                           XpmInfo *info));
+
+    FUNC(XpmGetParseError, int, (char *filename,
+                                int *linenum_return,
+                                int *charnum_return));
+
+    FUNC(XpmFree, void, (void *ptr));
+
+_XFUNCPROTOEND
+
+/* backward compatibility */
+
+/* for version 3.0c */
+#define XpmPixmapColorError  XpmColorError
+#define XpmPixmapSuccess     XpmSuccess
+#define XpmPixmapOpenFailed  XpmOpenFailed
+#define XpmPixmapFileInvalid XpmFileInvalid
+#define XpmPixmapNoMemory    XpmNoMemory
+#define XpmPixmapColorFailed XpmColorFailed
+
+#define XpmReadPixmapFile(dpy, d, file, pix, mask, att) \
+    XpmReadFileToPixmap(dpy, d, file, pix, mask, att)
+#define XpmWritePixmapFile(dpy, file, pix, mask, att) \
+    XpmWriteFileFromPixmap(dpy, file, pix, mask, att)
+
+/* for version 3.0b */
+#define PixmapColorError  XpmColorError
+#define PixmapSuccess     XpmSuccess
+#define PixmapOpenFailed  XpmOpenFailed
+#define PixmapFileInvalid XpmFileInvalid
+#define PixmapNoMemory    XpmNoMemory
+#define PixmapColorFailed XpmColorFailed
+
+#define ColorSymbol XpmColorSymbol
+
+#define XReadPixmapFile(dpy, d, file, pix, mask, att) \
+    XpmReadFileToPixmap(dpy, d, file, pix, mask, att)
+#define XWritePixmapFile(dpy, file, pix, mask, att) \
+    XpmWriteFileFromPixmap(dpy, file, pix, mask, att)
+#define XCreatePixmapFromData(dpy, d, data, pix, mask, att) \
+    XpmCreatePixmapFromData(dpy, d, data, pix, mask, att)
+#define XCreateDataFromPixmap(dpy, data, pix, mask, att) \
+    XpmCreateDataFromPixmap(dpy, data, pix, mask, att)
+
+#endif /* XPM_NUMBERS */
+#endif
diff --git a/m4/ax_define_dir.m4 b/m4/ax_define_dir.m4
new file mode 100755 (executable)
index 0000000..b74d155
--- /dev/null
@@ -0,0 +1,49 @@
+# ===========================================================================
+#       http://www.gnu.org/software/autoconf-archive/ax_define_dir.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION])
+#
+# DESCRIPTION
+#
+#   This macro sets VARNAME to the expansion of the DIR variable, taking
+#   care of fixing up ${prefix} and such.
+#
+#   VARNAME is then offered as both an output variable and a C preprocessor
+#   symbol.
+#
+#   Example:
+#
+#     AX_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.])
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Stepan Kasal <kasal@ucw.cz>
+#   Copyright (c) 2008 Andreas Schwab <schwab@suse.de>
+#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
+#   Copyright (c) 2008 Alexandre Oliva
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 6
+
+AU_ALIAS([AC_DEFINE_DIR], [AX_DEFINE_DIR])
+AC_DEFUN([AX_DEFINE_DIR], [
+  prefix_NONE=
+  exec_prefix_NONE=
+  test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix
+  test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix
+dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn
+dnl refers to ${prefix}.  Thus we have to use `eval' twice.
+  eval ax_define_dir="\"[$]$2\""
+  eval ax_define_dir="\"$ax_define_dir\""
+  AC_SUBST($1, "$ax_define_dir")
+  AC_DEFINE_UNQUOTED($1, "$ax_define_dir", [$3])
+  test "$prefix_NONE" && prefix=NONE
+  test "$exec_prefix_NONE" && exec_prefix=NONE
+])
diff --git a/packaging/libXpm.spec b/packaging/libXpm.spec
new file mode 100644 (file)
index 0000000..07a5bad
--- /dev/null
@@ -0,0 +1,80 @@
+
+Name:       libXpm
+Summary:    X.Org X11 libXpm runtime library
+Version:    3.5.9
+Release:    1
+Group:      System/Libraries
+License:    MIT
+URL:        http://www.x.org/
+Source0:    http://xorg.freedesktop.org/releases/individual/lib/%{name}-%{version}.tar.gz
+Requires(post):  /sbin/ldconfig
+Requires(postun):  /sbin/ldconfig
+BuildRequires:  pkgconfig(xorg-macros)
+BuildRequires:  pkgconfig(xproto)
+BuildRequires:  pkgconfig(x11)
+BuildRequires:  pkgconfig(xext)
+BuildRequires:  pkgconfig(xau)
+BuildRequires:  pkgconfig(xt)
+BuildRequires:  gettext
+
+BuildRoot:  %{_tmppath}/%{name}-%{version}-build
+
+%description
+Description: %{summary}
+
+
+%package devel
+Summary:    Development components for the libXpm library
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Description: %{summary}
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+
+%reconfigure \
+       LDFLAGS="-Wl,--hash-style=both -Wl,--as-needed"
+
+# Call make instruction with smp support
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+
+%clean
+rm -rf %{buildroot}
+
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING ChangeLog
+%{_libdir}/libXpm.so.4
+%{_libdir}/libXpm.so.4.11.0
+
+
+%files devel
+%defattr(-,root,root,-)
+%{_bindir}/cxpm
+%{_bindir}/sxpm
+%dir %{_includedir}/X11
+%{_includedir}/X11/xpm.h
+%{_libdir}/libXpm.so
+%{_libdir}/pkgconfig/xpm.pc
+#%dir %{_mandir}/man1x
+%doc %{_mandir}/man1/*.1*
+
diff --git a/src/Attrib.c b/src/Attrib.c
new file mode 100644 (file)
index 0000000..cb304df
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* Attrib.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Functions related to the XpmAttributes structure                           *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+/* 3.2 backward compatibility code */
+LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors,
+                                XpmColor ***oldct));
+
+LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, unsigned int ncolors));
+
+/*
+ * Create a colortable compatible with the old style colortable
+ */
+static int
+CreateOldColorTable(
+    XpmColor     *ct,
+    unsigned int   ncolors,
+    XpmColor   ***oldct)
+{
+    XpmColor **colorTable, **color;
+    unsigned int a;
+
+    if (ncolors >= UINT_MAX / sizeof(XpmColor *)) 
+       return XpmNoMemory;
+
+    colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *));
+    if (!colorTable) {
+       *oldct = NULL;
+       return (XpmNoMemory);
+    }
+    for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++)
+       *color = ct;
+    *oldct = colorTable;
+    return (XpmSuccess);
+}
+
+static void
+FreeOldColorTable(
+    XpmColor   **colorTable,
+    unsigned int  ncolors)
+{
+    unsigned int a, b;
+    XpmColor **color;
+    char **sptr;
+
+    if (colorTable) {
+       for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+           for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++)
+               if (*sptr)
+                   XpmFree(*sptr);
+       }
+       XpmFree(*colorTable);
+       XpmFree(colorTable);
+    }
+}
+
+/* end 3.2 bc */
+
+/*
+ * Free the computed color table
+ */
+void
+xpmFreeColorTable(
+    XpmColor   *colorTable,
+    int                 ncolors)
+{
+    int a, b;
+    XpmColor *color;
+    char **sptr;
+
+    if (colorTable) {
+       for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+           for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++)
+               if (*sptr)
+                   XpmFree(*sptr);
+       }
+       XpmFree(colorTable);
+    }
+}
+
+/*
+ * Free array of extensions
+ */
+void
+XpmFreeExtensions(
+    XpmExtension       *extensions,
+    int                         nextensions)
+{
+    unsigned int i, j, nlines;
+    XpmExtension *ext;
+    char **sptr;
+
+    if (extensions  && nextensions > 0) {
+       for (i = 0, ext = extensions; i < nextensions; i++, ext++) {
+           if (ext->name)
+               XpmFree(ext->name);
+           nlines = ext->nlines;
+           for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++)
+               if (sptr && *sptr)
+                   XpmFree(*sptr);
+           if (ext->lines)
+               XpmFree(ext->lines);
+       }
+       XpmFree(extensions);
+    }
+}
+
+/*
+ * Return the XpmAttributes structure size
+ */
+
+int
+XpmAttributesSize(void)
+{
+    return sizeof(XpmAttributes);
+}
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitAttributes(XpmAttributes *attributes)
+{
+    if (attributes) {
+       attributes->pixels = NULL;
+       attributes->npixels = 0;
+       attributes->colorTable = NULL;
+       attributes->ncolors = 0;
+/* 3.2 backward compatibility code */
+       attributes->hints_cmt = NULL;
+       attributes->colors_cmt = NULL;
+       attributes->pixels_cmt = NULL;
+/* end 3.2 bc */
+       if (attributes->valuemask & XpmReturnExtensions) {
+           attributes->extensions = NULL;
+           attributes->nextensions = 0;
+       }
+       if (attributes->valuemask & XpmReturnAllocPixels) {
+           attributes->alloc_pixels = NULL;
+           attributes->nalloc_pixels = 0;
+       }
+    }
+}
+
+/*
+ * Fill in the XpmAttributes with the XpmImage and the XpmInfo
+ */
+void
+xpmSetAttributes(
+    XpmAttributes      *attributes,
+    XpmImage           *image,
+    XpmInfo            *info)
+{
+    if (attributes->valuemask & XpmReturnColorTable) {
+       attributes->colorTable = image->colorTable;
+       attributes->ncolors = image->ncolors;
+
+       /* avoid deletion of copied data */
+       image->ncolors = 0;
+       image->colorTable = NULL;
+    }
+/* 3.2 backward compatibility code */
+    else if (attributes->valuemask & XpmReturnInfos) {
+       int ErrorStatus;
+
+       ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors,
+                                         (XpmColor ***)
+                                         &attributes->colorTable);
+
+       /* if error just say we can't return requested data */
+       if (ErrorStatus != XpmSuccess) {
+           attributes->valuemask &= ~XpmReturnInfos;
+           if (!(attributes->valuemask & XpmReturnPixels)) {
+               XpmFree(attributes->pixels);
+               attributes->pixels = NULL;
+               attributes->npixels = 0;
+           }
+           attributes->ncolors = 0;
+       } else {
+           attributes->ncolors = image->ncolors;
+           attributes->hints_cmt = info->hints_cmt;
+           attributes->colors_cmt = info->colors_cmt;
+           attributes->pixels_cmt = info->pixels_cmt;
+
+           /* avoid deletion of copied data */
+           image->ncolors = 0;
+           image->colorTable = NULL;
+           info->hints_cmt = NULL;
+           info->colors_cmt = NULL;
+           info->pixels_cmt = NULL;
+       }
+    }
+/* end 3.2 bc */
+    if (attributes->valuemask & XpmReturnExtensions) {
+       attributes->extensions = info->extensions;
+       attributes->nextensions = info->nextensions;
+
+       /* avoid deletion of copied data */
+       info->extensions = NULL;
+       info->nextensions = 0;
+    }
+    if (info->valuemask & XpmHotspot) {
+       attributes->valuemask |= XpmHotspot;
+       attributes->x_hotspot = info->x_hotspot;
+       attributes->y_hotspot = info->y_hotspot;
+    }
+    attributes->valuemask |= XpmCharsPerPixel;
+    attributes->cpp = image->cpp;
+    attributes->valuemask |= XpmSize;
+    attributes->width = image->width;
+    attributes->height = image->height;
+}
+
+/*
+ * Free the XpmAttributes structure members
+ * but the structure itself
+ */
+void
+XpmFreeAttributes(XpmAttributes *attributes)
+{
+    if (attributes->valuemask & XpmReturnPixels && attributes->npixels) {
+       XpmFree(attributes->pixels);
+       attributes->pixels = NULL;
+       attributes->npixels = 0;
+    }
+    if (attributes->valuemask & XpmReturnColorTable) {
+       xpmFreeColorTable(attributes->colorTable, attributes->ncolors);
+       attributes->colorTable = NULL;
+       attributes->ncolors = 0;
+    }
+/* 3.2 backward compatibility code */
+    else if (attributes->valuemask & XpmInfos) {
+       if (attributes->colorTable) {
+           FreeOldColorTable((XpmColor **) attributes->colorTable,
+                             attributes->ncolors);
+           attributes->colorTable = NULL;
+           attributes->ncolors = 0;
+       }
+       if (attributes->hints_cmt) {
+           XpmFree(attributes->hints_cmt);
+           attributes->hints_cmt = NULL;
+       }
+       if (attributes->colors_cmt) {
+           XpmFree(attributes->colors_cmt);
+           attributes->colors_cmt = NULL;
+       }
+       if (attributes->pixels_cmt) {
+           XpmFree(attributes->pixels_cmt);
+           attributes->pixels_cmt = NULL;
+       }
+       if (attributes->pixels) {
+           XpmFree(attributes->pixels);
+           attributes->pixels = NULL;
+           attributes->npixels = 0;
+       }
+    }
+/* end 3.2 bc */
+    if (attributes->valuemask & XpmReturnExtensions
+       && attributes->nextensions) {
+       XpmFreeExtensions(attributes->extensions, attributes->nextensions);
+       attributes->extensions = NULL;
+       attributes->nextensions = 0;
+    }
+    if (attributes->valuemask & XpmReturnAllocPixels
+       && attributes->nalloc_pixels) {
+       XpmFree(attributes->alloc_pixels);
+       attributes->alloc_pixels = NULL;
+       attributes->nalloc_pixels = 0;
+    }
+    attributes->valuemask = 0;
+}
diff --git a/src/CrBufFrI.c b/src/CrBufFrI.c
new file mode 100755 (executable)
index 0000000..113a45c
--- /dev/null
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrBufFrI.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan an image and possibly its mask and create an XPM buffer               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size,
+                        unsigned int *used_size, XpmColor *colors,
+                        unsigned int ncolors, unsigned int cpp));
+
+LFUNC(WritePixels, void, (char *dataptr, unsigned int data_size,
+                         unsigned int *used_size,
+                         unsigned int width, unsigned int height,
+                         unsigned int cpp, unsigned int *pixels,
+                         XpmColor *colors));
+
+LFUNC(WriteExtensions, void, (char *dataptr, unsigned int data_size,
+                             unsigned int *used_size,
+                             XpmExtension *ext, unsigned int num));
+
+LFUNC(ExtensionsSize, unsigned int, (XpmExtension *ext, unsigned int num));
+LFUNC(CommentsSize, int, (XpmInfo *info));
+
+int
+XpmCreateBufferFromImage(
+    Display             *display,
+    char               **buffer_return,
+    XImage              *image,
+    XImage              *shapeimage,
+    XpmAttributes       *attributes)
+{
+    XpmImage xpmimage;
+    XpmInfo info;
+    int ErrorStatus;
+
+    /* initialize return value */
+    if (buffer_return)
+       *buffer_return = NULL;
+
+    /* create an XpmImage from the image */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+                                            &xpmimage, attributes);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /* create the buffer from the XpmImage */
+    if (attributes) {
+       xpmSetInfo(&info, attributes);
+       ErrorStatus =
+           XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info);
+    } else
+       ErrorStatus =
+           XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL);
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&xpmimage);
+
+    return (ErrorStatus);
+}
+
+
+#undef RETURN
+#define RETURN(status) \
+do \
+{ \
+      ErrorStatus = status; \
+      goto error; \
+}while(0)
+
+int
+XpmCreateBufferFromXpmImage(
+    char       **buffer_return,
+    XpmImage    *image,
+    XpmInfo     *info)
+{
+    /* calculation variables */
+    int ErrorStatus;
+    char buf[BUFSIZ];
+    unsigned int cmts, extensions, ext_size = 0;
+    unsigned int l, cmt_size = 0;
+    char *ptr = NULL, *p;
+    unsigned int ptr_size, used_size, tmp;
+
+    *buffer_return = NULL;
+
+    cmts = info && (info->valuemask & XpmComments);
+    extensions = info && (info->valuemask & XpmExtensions)
+       && info->nextensions;
+
+    /* compute the extensions and comments size */
+    if (extensions)
+       ext_size = ExtensionsSize(info->extensions, info->nextensions);
+    if (cmts)
+       cmt_size = CommentsSize(info);
+
+    /* write the header line */
+#ifndef VOID_SPRINTF
+    used_size =
+#endif
+    sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n");
+#ifdef VOID_SPRINTF
+    used_size = strlen(buf);
+#endif
+    ptr_size = used_size + ext_size + cmt_size + 1; /* ptr_size can't be 0 */
+    if(ptr_size <= used_size ||
+       ptr_size <= ext_size  ||
+       ptr_size <= cmt_size)
+    {
+        return XpmNoMemory;
+    }
+    ptr = (char *) XpmMalloc(ptr_size);
+    if (!ptr)
+       return XpmNoMemory;
+    strcpy(ptr, buf);
+
+    /* write the values line */
+    if (cmts && info->hints_cmt) {
+#ifndef VOID_SPRINTF
+       used_size +=
+#endif
+       snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->hints_cmt);
+#ifdef VOID_SPRINTF
+       used_size += strlen(info->hints_cmt) + 5;
+#endif
+    }
+#ifndef VOID_SPRINTF
+    l =
+#endif
+    sprintf(buf, "\"%d %d %d %d", image->width, image->height,
+           image->ncolors, image->cpp);
+#ifdef VOID_SPRINTF
+    l = strlen(buf);
+#endif
+
+    if (info && (info->valuemask & XpmHotspot)) {
+#ifndef VOID_SPRINTF
+       l +=
+#endif
+       snprintf(buf + l, sizeof(buf)-l, " %d %d", info->x_hotspot, info->y_hotspot);
+#ifdef VOID_SPRINTF
+       l = strlen(buf);
+#endif
+    }
+    if (extensions) {
+#ifndef VOID_SPRINTF
+       l +=
+#endif
+       sprintf(buf + l, " XPMEXT");
+#ifdef VOID_SPRINTF
+       l = strlen(buf);
+#endif
+    }
+#ifndef VOID_SPRINTF
+    l +=
+#endif
+    sprintf(buf + l, "\",\n");
+#ifdef VOID_SPRINTF
+    l = strlen(buf);
+#endif
+    ptr_size += l;
+    if(ptr_size <= l)
+        RETURN(XpmNoMemory);
+    p = (char *) XpmRealloc(ptr, ptr_size);
+    if (!p)
+       RETURN(XpmNoMemory);
+    ptr = p;
+    strcpy(ptr + used_size, buf);
+    used_size += l;
+
+    /* write colors */
+    if (cmts && info->colors_cmt) {
+#ifndef VOID_SPRINTF
+       used_size +=
+#endif
+       snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->colors_cmt);
+#ifdef VOID_SPRINTF
+       used_size += strlen(info->colors_cmt) + 5;
+#endif
+    }
+    ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size,
+                             image->colorTable, image->ncolors, image->cpp);
+    if (ErrorStatus != XpmSuccess)
+       RETURN(ErrorStatus);
+
+    /*
+     * now we know the exact size we need, realloc the data
+     * 4 = 1 (for '"') + 3 (for '",\n')
+     * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n')
+     */
+     if(image->width  > UINT_MAX / image->cpp ||
+       (tmp = image->width * image->cpp + 4) <= 4 ||
+        image->height > UINT_MAX / tmp ||
+       (tmp = image->height * tmp + 1) <= 1 ||
+       (ptr_size += tmp) <= tmp)
+       RETURN(XpmNoMemory);
+
+    p = (char *) XpmRealloc(ptr, ptr_size);
+    if (!p)
+       RETURN(XpmNoMemory);
+    ptr = p;
+
+    /* print pixels */
+    if (cmts && info->pixels_cmt) {
+#ifndef VOID_SPRINTF
+       used_size +=
+#endif
+       snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->pixels_cmt);
+#ifdef VOID_SPRINTF
+       used_size += strlen(info->pixels_cmt) + 5;
+#endif
+    }
+    WritePixels(ptr + used_size, ptr_size - used_size, &used_size, image->width, image->height,
+               image->cpp, image->data, image->colorTable);
+
+    /* print extensions */
+    if (extensions)
+       WriteExtensions(ptr + used_size, ptr_size-used_size, &used_size,
+                       info->extensions, info->nextensions);
+
+    /* close the array */
+    strcpy(ptr + used_size, "};\n");
+
+    *buffer_return = ptr;
+
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (ptr)
+       XpmFree(ptr);
+    return (ErrorStatus);
+}
+
+
+static int
+WriteColors(
+    char               **dataptr,
+    unsigned int        *data_size,
+    unsigned int        *used_size,
+    XpmColor            *colors,
+    unsigned int         ncolors,
+    unsigned int         cpp)
+{
+    char buf[BUFSIZ] = {0};
+    unsigned int a, key, l;
+    char *s, *s2;
+    char **defaults;
+
+    *buf = '"';
+    for (a = 0; a < ncolors; a++, colors++) {
+
+       defaults = (char **) colors;
+       s = buf + 1;
+       if(cpp > (sizeof(buf) - (s-buf)))
+               return(XpmNoMemory);
+       strncpy(s, *defaults++, cpp);
+       s += cpp;
+
+       for (key = 1; key <= NKEYS; key++, defaults++) {
+           if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+               s +=
+#endif
+               /* assume C99 compliance */
+               snprintf(s, sizeof(buf) - (s-buf), "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+               s += strlen(s);
+#endif
+               /* now let's check if s points out-of-bounds */
+               if((s-buf) > sizeof(buf))
+                       return(XpmNoMemory);
+           }
+       }
+       if(sizeof(buf) - (s-buf) < 4)
+               return(XpmNoMemory);
+       strcpy(s, "\",\n");
+       l = s + 3 - buf;
+       if( *data_size                   >= UINT_MAX-l ||
+           *data_size + l               <= *used_size ||
+          (*data_size + l - *used_size) <= sizeof(buf))
+               return(XpmNoMemory);
+       s = (char *) XpmRealloc(*dataptr, *data_size + l);
+       if (!s)
+           return (XpmNoMemory);
+       *data_size += l;
+       strcpy(s + *used_size, buf);
+       *used_size += l;
+       *dataptr = s;
+    }
+    return (XpmSuccess);
+}
+
+static void
+WritePixels(
+    char               *dataptr,
+    unsigned int        data_size,
+    unsigned int       *used_size,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int        cpp,
+    unsigned int       *pixels,
+    XpmColor           *colors)
+{
+    char *s = dataptr;
+    unsigned int x, y, h;
+
+    if(height <= 1)
+       return;
+
+    h = height - 1;
+    for (y = 0; y < h; y++) {
+       *s++ = '"';
+       for (x = 0; x < width; x++, pixels++) {
+           if(cpp >= (data_size - (s-dataptr)))
+               return;
+           strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? :-\ */
+           s += cpp;
+       }
+       if((data_size - (s-dataptr)) < 4)
+               return;
+       strcpy(s, "\",\n");
+       s += 3;
+    }
+    /* duplicate some code to avoid a test in the loop */
+    *s++ = '"';
+    for (x = 0; x < width; x++, pixels++) {
+       if(cpp >= (data_size - (s-dataptr)))
+           return;
+       strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? */
+       s += cpp;
+    }
+    *s++ = '"';
+    *used_size += s - dataptr;
+}
+
+static unsigned int
+ExtensionsSize(
+    XpmExtension       *ext,
+    unsigned int        num)
+{
+    unsigned int x, y, a, size;
+    char **line;
+
+    size = 0;
+    if(num == 0)
+       return(0); /* ok? */
+    for (x = 0; x < num; x++, ext++) {
+       /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
+       size += strlen(ext->name) + 11;
+       a = ext->nlines; /* how can we trust ext->nlines to be not out-of-bounds? */
+       for (y = 0, line = ext->lines; y < a; y++, line++)
+           /* 4 = 3 (for ',\n"') + 1 (for '"') */
+           size += strlen(*line) + 4;
+    }
+    /* 13 is for ',\n"XPMENDEXT"' */
+    if(size > UINT_MAX - 13) /* unlikely */
+       return(0);
+    return size + 13;
+}
+
+static void
+WriteExtensions(
+    char               *dataptr,
+    unsigned int        data_size,
+    unsigned int       *used_size,
+    XpmExtension       *ext,
+    unsigned int        num)
+{
+    unsigned int x, y, a;
+    char **line;
+    char *s = dataptr;
+
+    for (x = 0; x < num; x++, ext++) {
+#ifndef VOID_SPRINTF
+       s +=
+#endif
+       snprintf(s, data_size - (s-dataptr), ",\n\"XPMEXT %s\"", ext->name);
+#ifdef VOID_SPRINTF
+       s += strlen(ext->name) + 11;
+#endif
+       a = ext->nlines;
+       for (y = 0, line = ext->lines; y < a; y++, line++) {
+#ifndef VOID_SPRINTF
+           s +=
+#endif
+           snprintf(s, data_size - (s-dataptr), ",\n\"%s\"", *line);
+#ifdef VOID_SPRINTF
+           s += strlen(*line) + 4;
+#endif
+       }
+    }
+    strncpy(s, ",\n\"XPMENDEXT\"", data_size - (s-dataptr)-1);
+    *used_size += s - dataptr + 13;
+}
+
+static int
+CommentsSize(XpmInfo *info)
+{
+    int size = 0;
+
+    /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
+    /* wrap possible but *very* unlikely */
+    if (info->hints_cmt)
+       size += 5 + strlen(info->hints_cmt);
+
+    if (info->colors_cmt)
+       size += 5 + strlen(info->colors_cmt);
+
+    if (info->pixels_cmt)
+       size += 5 + strlen(info->pixels_cmt);
+
+    return size;
+}
diff --git a/src/CrBufFrP.c b/src/CrBufFrP.c
new file mode 100644 (file)
index 0000000..de3e776
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrBufFrP.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan a pixmap and possibly its mask and create an XPM buffer               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreateBufferFromPixmap(
+    Display             *display,
+    char               **buffer_return,
+    Pixmap               pixmap,
+    Pixmap               shapemask,
+    XpmAttributes       *attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+       width = attributes->width;
+       height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+       xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+       xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+                                &width, &height);
+
+    /* create the buffer */
+    ErrorStatus = XpmCreateBufferFromImage(display, buffer_return, ximage,
+                                          shapeimage, attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+       XDestroyImage(ximage);
+    if (shapeimage)
+       XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
diff --git a/src/CrDatFrI.c b/src/CrDatFrI.c
new file mode 100755 (executable)
index 0000000..0dacf51
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrDataFI.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan an image and possibly its mask and create an XPM array                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size,
+                         XpmColor *colors, unsigned int ncolors,
+                         unsigned int cpp));
+
+LFUNC(CreatePixels, void, (char **dataptr, unsigned int data_size,
+                          unsigned int width,
+                          unsigned int height, unsigned int cpp,
+                          unsigned int *pixels, XpmColor *colors));
+
+LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num,
+                             unsigned int *ext_size,
+                             unsigned int *ext_nlines));
+
+LFUNC(CreateExtensions, void, (char **dataptr, unsigned int data_size,
+                              unsigned int offset,
+                              XpmExtension *ext, unsigned int num,
+                              unsigned int ext_nlines));
+
+int
+XpmCreateDataFromImage(
+    Display              *display,
+    char               ***data_return,
+    XImage               *image,
+    XImage               *shapeimage,
+    XpmAttributes        *attributes)
+{
+    XpmImage xpmimage;
+    XpmInfo info;
+    int ErrorStatus;
+
+    /* initialize return value */
+    if (data_return)
+       *data_return = NULL;
+
+    /* create an XpmImage from the image */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+                                            &xpmimage, attributes);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /* create the data from the XpmImage */
+    if (attributes) {
+       xpmSetInfo(&info, attributes);
+       ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info);
+    } else
+       ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL);
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&xpmimage);
+
+    return (ErrorStatus);
+}
+
+#undef RETURN
+#define RETURN(status) \
+do \
+{ \
+      ErrorStatus = status; \
+      goto exit; \
+} while(0)
+
+int
+XpmCreateDataFromXpmImage(
+    char       ***data_return,
+    XpmImage     *image,
+    XpmInfo      *info)
+{
+    /* calculation variables */
+    int ErrorStatus;
+    char buf[BUFSIZ];
+    char **header = NULL, **data, **sptr, **sptr2, *s;
+    unsigned int header_size, header_nlines;
+    unsigned int data_size, data_nlines;
+    unsigned int extensions = 0, ext_size = 0, ext_nlines = 0;
+    unsigned int offset, l, n;
+
+    *data_return = NULL;
+
+    extensions = info && (info->valuemask & XpmExtensions)
+       && info->nextensions;
+
+    /* compute the number of extensions lines and size */
+    if (extensions)
+       CountExtensions(info->extensions, info->nextensions,
+                       &ext_size, &ext_nlines);
+
+    /*
+     * alloc a temporary array of char pointer for the header section which
+     * is the hints line + the color table lines
+     */
+    header_nlines = 1 + image->ncolors; /* this may wrap and/or become 0 */
+
+    /* 2nd check superfluous if we do not need header_nlines any further */
+    if(header_nlines <= image->ncolors ||
+       header_nlines >= UINT_MAX / sizeof(char *))
+       return(XpmNoMemory);
+
+    header_size = sizeof(char *) * header_nlines;
+    if (header_size >= UINT_MAX / sizeof(char *))
+       return (XpmNoMemory);
+    header = (char **) XpmCalloc(header_size, sizeof(char *)); /* can we trust image->ncolors */
+    if (!header)
+       return (XpmNoMemory);
+
+    /* print the hints line */
+    s = buf;
+#ifndef VOID_SPRINTF
+    s +=
+#endif
+    sprintf(s, "%d %d %d %d", image->width, image->height,
+           image->ncolors, image->cpp);
+#ifdef VOID_SPRINTF
+    s += strlen(s);
+#endif
+
+    if (info && (info->valuemask & XpmHotspot)) {
+#ifndef VOID_SPRINTF
+       s +=
+#endif
+       sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot);
+#ifdef VOID_SPRINTF
+       s += strlen(s);
+#endif
+    }
+    if (extensions) {
+       strcpy(s, " XPMEXT");
+       s += 7;
+    }
+    l = s - buf + 1;
+    *header = (char *) XpmMalloc(l);
+    if (!*header)
+       RETURN(XpmNoMemory);
+    header_size += l;
+    strcpy(*header, buf);
+
+    /* print colors */
+    ErrorStatus = CreateColors(header + 1, &header_size,
+                              image->colorTable, image->ncolors, image->cpp);
+
+    if (ErrorStatus != XpmSuccess)
+       RETURN(ErrorStatus);
+
+    /* now we know the size needed, alloc the data and copy the header lines */
+    offset = image->width * image->cpp + 1;
+
+    if(offset <= image->width || offset <= image->cpp)
+       RETURN(XpmNoMemory);
+
+    if( (image->height + ext_nlines) >= UINT_MAX / sizeof(char *))
+       RETURN(XpmNoMemory);
+    data_size = (image->height + ext_nlines) * sizeof(char *);
+
+    if (image->height > UINT_MAX / offset ||
+        image->height * offset > UINT_MAX - data_size)
+       RETURN(XpmNoMemory);
+    data_size += image->height * offset;
+
+    if( (header_size + ext_size) >= (UINT_MAX - data_size) )
+       RETURN(XpmNoMemory);
+    data_size += header_size + ext_size;
+
+    data = (char **) XpmMalloc(data_size);
+    if (!data)
+       RETURN(XpmNoMemory);
+
+    data_nlines = header_nlines + image->height + ext_nlines;
+    *data = (char *) (data + data_nlines);
+
+    /* can header have less elements then n suggests? */
+    n = image->ncolors;
+    for (l = 0, sptr = data, sptr2 = header; l <= n && sptr && sptr2; l++, sptr++, sptr2++) {
+       strcpy(*sptr, *sptr2);
+       *(sptr + 1) = *sptr + strlen(*sptr2) + 1;
+    }
+
+    /* print pixels */
+    data[header_nlines] = (char *) data + header_size
+       + (image->height + ext_nlines) * sizeof(char *);
+
+    CreatePixels(data + header_nlines, data_size-header_nlines, image->width, image->height,
+                image->cpp, image->data, image->colorTable);
+
+    /* print extensions */
+    if (extensions)
+       CreateExtensions(data + header_nlines + image->height - 1,
+                        data_size - header_nlines - image->height + 1, offset,
+                        info->extensions, info->nextensions,
+                        ext_nlines);
+
+    *data_return = data;
+    ErrorStatus = XpmSuccess;
+
+/* exit point, free only locally allocated variables */
+exit:
+    if (header) {
+       for (l = 0; l < header_nlines; l++)
+           if (header[l])
+               XpmFree(header[l]);
+               XpmFree(header);
+    }
+    return(ErrorStatus);
+}
+
+static int
+CreateColors(
+    char               **dataptr,
+    unsigned int        *data_size,
+    XpmColor            *colors,
+    unsigned int         ncolors,
+    unsigned int         cpp)
+{
+    char buf[BUFSIZ];
+    unsigned int a, key, l;
+    char *s, *s2;
+    char **defaults;
+
+    /* can ncolors be trusted here? */
+    for (a = 0; a < ncolors; a++, colors++, dataptr++) {
+
+       defaults = (char **) colors;
+       if(sizeof(buf) <= cpp)
+           return(XpmNoMemory);
+       strncpy(buf, *defaults++, cpp);
+       s = buf + cpp;
+
+       if(sizeof(buf) <= (s-buf))
+               return XpmNoMemory;
+
+       for (key = 1; key <= NKEYS; key++, defaults++) {
+           if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+               s +=
+#endif
+               /* assume C99 compliance */
+                       snprintf(s, sizeof(buf)-(s-buf), "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+               s += strlen(s);
+#endif
+               /* does s point out-of-bounds? */
+               if(sizeof(buf) < (s-buf))
+                       return XpmNoMemory;
+           }
+       }
+       /* what about using strdup()? */
+       l = s - buf + 1;
+       s = (char *) XpmMalloc(l);
+       if (!s)
+           return (XpmNoMemory);
+       *data_size += l;
+       *dataptr = strcpy(s, buf);
+    }
+    return (XpmSuccess);
+}
+
+static void
+CreatePixels(
+    char               **dataptr,
+    unsigned int         data_size,
+    unsigned int         width,
+    unsigned int         height,
+    unsigned int         cpp,
+    unsigned int        *pixels,
+    XpmColor            *colors)
+{
+    char *s;
+    unsigned int x, y, h, offset;
+
+    if(height <= 1)
+       return;
+
+    h = height - 1;
+
+    offset = width * cpp + 1;
+
+    if(offset <= width || offset <= cpp)
+       return;
+
+    /* why trust h? */
+    for (y = 0; y < h; y++, dataptr++) {
+       s = *dataptr;
+       /* why trust width? */
+       for (x = 0; x < width; x++, pixels++) {
+           if(cpp > (data_size - (s - *dataptr)))
+               return;
+           strncpy(s, colors[*pixels].string, cpp); /* why trust pixel? */
+           s += cpp;
+       }
+       *s = '\0';
+       if(offset > data_size)
+               return;
+       *(dataptr + 1) = *dataptr + offset;
+    }
+    /* duplicate some code to avoid a test in the loop */
+    s = *dataptr;
+    /* why trust width? */
+    for (x = 0; x < width; x++, pixels++) {
+       if(cpp > data_size - (s - *dataptr))
+               return;
+       strncpy(s, colors[*pixels].string, cpp); /* why should we trust *pixel? */
+       s += cpp;
+    }
+    *s = '\0';
+}
+
+static void
+CountExtensions(
+    XpmExtension       *ext,
+    unsigned int        num,
+    unsigned int       *ext_size,
+    unsigned int       *ext_nlines)
+{
+    unsigned int x, y, a, size, nlines;
+    char **line;
+
+    size = 0;
+    nlines = 0;
+    for (x = 0; x < num; x++, ext++) {
+       /* 1 for the name */
+       nlines += ext->nlines + 1;
+       /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */
+       size += strlen(ext->name) + 8;
+       a = ext->nlines;
+       for (y = 0, line = ext->lines; y < a; y++, line++)
+           size += strlen(*line) + 1;
+    }
+    /* 10 and 1 are for the ending "XPMENDEXT" */
+    *ext_size = size + 10;
+    *ext_nlines = nlines + 1;
+}
+
+static void
+CreateExtensions(
+    char               **dataptr,
+    unsigned int         data_size,
+    unsigned int         offset,
+    XpmExtension        *ext,
+    unsigned int         num,
+    unsigned int         ext_nlines)
+{
+    unsigned int x, y, a, b;
+    char **line;
+
+    *(dataptr + 1) = *dataptr + offset;
+    dataptr++;
+    a = 0;
+    for (x = 0; x < num; x++, ext++) {
+       snprintf(*dataptr, data_size, "XPMEXT %s", ext->name);
+       a++;
+       if (a < ext_nlines)
+           *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
+       dataptr++;
+       b = ext->nlines; /* can we trust these values? */
+       for (y = 0, line = ext->lines; y < b; y++, line++) {
+           strcpy(*dataptr, *line);
+           a++;
+           if (a < ext_nlines)
+               *(dataptr + 1) = *dataptr + strlen(*line) + 1;
+           dataptr++;
+       }
+    }
+    strcpy(*dataptr, "XPMENDEXT");
+}
diff --git a/src/CrDatFrP.c b/src/CrDatFrP.c
new file mode 100644 (file)
index 0000000..0e17fee
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrDataFP.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Scan a pixmap and possibly its mask and create an XPM array                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreateDataFromPixmap(
+    Display              *display,
+    char               ***data_return,
+    Pixmap                pixmap,
+    Pixmap                shapemask,
+    XpmAttributes        *attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+       width = attributes->width;
+       height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+       xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+       xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+                                &width, &height);
+
+    /* create the data */
+    ErrorStatus = XpmCreateDataFromImage(display, data_return, ximage,
+                                        shapeimage, attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+       XDestroyImage(ximage);
+    if (shapeimage)
+       XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
diff --git a/src/CrIFrBuf.c b/src/CrIFrBuf.c
new file mode 100644 (file)
index 0000000..b6b12ca
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrIFrBuf.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm buffer (file in memory) and create the image and possibly its *
+*  mask                                                                       *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(OpenBuffer, void, (char *buffer, xpmData *mdata));
+
+int
+XpmCreateImageFromBuffer(
+    Display             *display,
+    char                *buffer,
+    XImage             **image_return,
+    XImage             **shapeimage_return,
+    XpmAttributes       *attributes)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+    xpmData mdata;
+
+    xpmInitXpmImage(&image);
+    xpmInitXpmInfo(&info);
+
+    /* open buffer to read */
+    OpenBuffer(buffer, &mdata);
+
+    /* create the XImage from the XpmData */
+    if (attributes) {
+       xpmInitAttributes(attributes);
+       xpmSetInfoMask(&info, attributes);
+       ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+                                           image_return, shapeimage_return,
+                                           &image, &info, attributes);
+    } else
+       ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+                                           image_return, shapeimage_return,
+                                           &image, NULL, attributes);
+    if (attributes) {
+       if (ErrorStatus >= 0)           /* no fatal error */
+           xpmSetAttributes(attributes, &image, &info);
+       XpmFreeXpmInfo(&info);
+    }
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&image);
+
+    return (ErrorStatus);
+}
+
+int
+XpmCreateXpmImageFromBuffer(
+    char       *buffer,
+    XpmImage   *image,
+    XpmInfo    *info)
+{
+    xpmData mdata;
+    int ErrorStatus;
+
+    /* init returned values */
+    xpmInitXpmImage(image);
+    xpmInitXpmInfo(info);
+
+    /* open buffer to read */
+    OpenBuffer(buffer, &mdata);
+
+    /* create the XpmImage from the XpmData */
+    ErrorStatus = xpmParseData(&mdata, image, info);
+
+    return (ErrorStatus);
+}
+
+/*
+ * open the given buffer to be read or written as an xpmData which is returned
+ */
+static void
+OpenBuffer(
+    char       *buffer,
+    xpmData    *mdata)
+{
+    mdata->type = XPMBUFFER;
+    mdata->cptr = buffer;
+    mdata->CommentLength = 0;
+}
diff --git a/src/CrIFrDat.c b/src/CrIFrDat.c
new file mode 100644 (file)
index 0000000..9ef1557
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrIFrData.c:                                                               *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm array and create the image and possibly its mask              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(OpenArray, void, (char **data, xpmData *mdata));
+
+int
+XpmCreateImageFromData(
+    Display             *display,
+    char               **data,
+    XImage             **image_return,
+    XImage             **shapeimage_return,
+    XpmAttributes       *attributes)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+    xpmData mdata;
+
+    xpmInitXpmImage(&image);
+    xpmInitXpmInfo(&info);
+
+    /* open data */
+    OpenArray(data, &mdata);
+
+    /* create an XpmImage from the file */
+    if (attributes) {
+       xpmInitAttributes(attributes);
+       xpmSetInfoMask(&info, attributes);
+       ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+                                           image_return, shapeimage_return,
+                                           &image, &info, attributes);
+    } else
+       ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+                                           image_return, shapeimage_return,
+                                           &image, NULL, attributes);
+    if (attributes) {
+       if (ErrorStatus >= 0)           /* no fatal error */
+           xpmSetAttributes(attributes, &image, &info);
+       XpmFreeXpmInfo(&info);
+    }
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&image);
+
+    return (ErrorStatus);
+}
+
+int
+XpmCreateXpmImageFromData(
+    char       **data,
+    XpmImage    *image,
+    XpmInfo     *info)
+{
+    xpmData mdata;
+    int ErrorStatus;
+
+    /* init returned values */
+    xpmInitXpmImage(image);
+    xpmInitXpmInfo(info);
+
+    /* open data */
+    OpenArray(data, &mdata);
+
+    /* create the XpmImage from the XpmData */
+    ErrorStatus = xpmParseData(&mdata, image, info);
+
+    return (ErrorStatus);
+}
+
+/*
+ * open the given array to be read or written as an xpmData which is returned
+ */
+static void
+OpenArray(
+    char       **data,
+    xpmData     *mdata)
+{
+    mdata->type = XPMARRAY;
+    mdata->stream.data = data;
+    mdata->cptr = *data;
+    mdata->line = 0;
+    mdata->CommentLength = 0;
+    mdata->Bcmt = mdata->Ecmt = NULL;
+    mdata->Bos = mdata->Eos = '\0';
+    mdata->format = 0;                 /* this can only be Xpm 2 or 3 */
+}
diff --git a/src/CrIFrP.c b/src/CrIFrP.c
new file mode 100644 (file)
index 0000000..79c4c49
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrIFrP.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Create the XImage related to the given Pixmap.                             *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+void
+xpmCreateImageFromPixmap(
+    Display             *display,
+    Pixmap               pixmap,
+    XImage             **ximage_return,
+    unsigned int        *width,
+    unsigned int        *height)
+{
+    unsigned int dum;
+    int dummy;
+    Window win;
+
+    if (*width == 0 && *height == 0)
+       XGetGeometry(display, pixmap, &win, &dummy, &dummy,
+                    width, height, &dum, &dum);
+
+    *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height,
+                              AllPlanes, ZPixmap);
+}
diff --git a/src/CrPFrBuf.c b/src/CrPFrBuf.c
new file mode 100644 (file)
index 0000000..2c28a41
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrPFrBuf.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm buffer and create the pixmap and possibly its mask            *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreatePixmapFromBuffer(
+    Display            *display,
+    Drawable            d,
+    char               *buffer,
+    Pixmap             *pixmap_return,
+    Pixmap             *shapemask_return,
+    XpmAttributes      *attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+       *pixmap_return = 0;
+    if (shapemask_return)
+       *shapemask_return = 0;
+
+    /* create the images */
+    ErrorStatus = XpmCreateImageFromBuffer(display, buffer,
+                                          (pixmap_return ? &ximage : NULL),
+                                          (shapemask_return ?
+                                           &shapeimage : NULL),
+                                          attributes);
+
+    if (ErrorStatus < 0)               /* fatal error */
+       return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+       xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+       XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+       xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+       XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
diff --git a/src/CrPFrDat.c b/src/CrPFrDat.c
new file mode 100644 (file)
index 0000000..b65771d
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrPFrData.c:                                                               *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm array and create the pixmap and possibly its mask             *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmCreatePixmapFromData(
+    Display             *display,
+    Drawable             d,
+    char               **data,
+    Pixmap              *pixmap_return,
+    Pixmap              *shapemask_return,
+    XpmAttributes       *attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+       *pixmap_return = 0;
+    if (shapemask_return)
+       *shapemask_return = 0;
+
+    /* create the images */
+    ErrorStatus = XpmCreateImageFromData(display, data,
+                                        (pixmap_return ? &ximage : NULL),
+                                        (shapemask_return ?
+                                         &shapeimage : NULL),
+                                        attributes);
+
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    if (ErrorStatus < 0)               /* fatal error */
+       return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+       xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+       XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+       xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+       XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
diff --git a/src/CrPFrI.c b/src/CrPFrI.c
new file mode 100644 (file)
index 0000000..8f6f4aa
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  CrPFrI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Create the Pixmap related to the given XImage.                             *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+void
+xpmCreatePixmapFromImage(
+    Display    *display,
+    Drawable    d,
+    XImage     *ximage,
+    Pixmap     *pixmap_return)
+{
+    GC gc;
+    XGCValues values;
+
+    *pixmap_return = XCreatePixmap(display, d, ximage->width,
+                                  ximage->height, ximage->depth);
+    /* set fg and bg in case we have an XYBitmap */
+    values.foreground = 1;
+    values.background = 0;
+    gc = XCreateGC(display, *pixmap_return,
+                  GCForeground | GCBackground, &values);
+
+    XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0,
+             ximage->width, ximage->height);
+
+    XFreeGC(display, gc);
+}
diff --git a/src/Image.c b/src/Image.c
new file mode 100644 (file)
index 0000000..e0223cc
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  Image.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Functions to init and free the XpmImage structure.                         *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitXpmImage(XpmImage *image)
+{
+    image->ncolors = 0;
+    image->colorTable = NULL;
+    image->data = NULL;
+}
+
+/*
+ * Free the XpmImage data which have been allocated
+ */
+void
+XpmFreeXpmImage(XpmImage *image)
+{
+    if (image->colorTable)
+       xpmFreeColorTable(image->colorTable, image->ncolors);
+    if (image->data)
+       XpmFree(image->data);
+    image->data = NULL;
+}
diff --git a/src/Info.c b/src/Info.c
new file mode 100644 (file)
index 0000000..e975a6d
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  Info.c:                                                                    *
+*                                                                             *
+*  XPM library                                                                *
+*  Functions related to the XpmInfo structure.                                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitXpmInfo(XpmInfo *info)
+{
+    if (info) {
+       info->hints_cmt = NULL;
+       info->colors_cmt = NULL;
+       info->pixels_cmt = NULL;
+       info->extensions = NULL;
+       info->nextensions = 0;
+    }
+}
+
+/*
+ * Free the XpmInfo data which have been allocated
+ */
+void
+XpmFreeXpmInfo(XpmInfo *info)
+{
+    if (info) {
+       if (info->valuemask & XpmComments) {
+           if (info->hints_cmt) {
+               XpmFree(info->hints_cmt);
+               info->hints_cmt = NULL;
+           }
+           if (info->colors_cmt) {
+               XpmFree(info->colors_cmt);
+               info->colors_cmt = NULL;
+           }
+           if (info->pixels_cmt) {
+               XpmFree(info->pixels_cmt);
+               info->pixels_cmt = NULL;
+           }
+       }
+       if (info->valuemask & XpmReturnExtensions && info->nextensions) {
+           XpmFreeExtensions(info->extensions, info->nextensions);
+           info->extensions = NULL;
+           info->nextensions = 0;
+       }
+       info->valuemask = 0;
+    }
+}
+
+/*
+ * Set the XpmInfo valuemask to retrieve required info
+ */
+void
+xpmSetInfoMask(
+    XpmInfo            *info,
+    XpmAttributes      *attributes)
+{
+    info->valuemask = 0;
+    if (attributes->valuemask & XpmReturnInfos)
+       info->valuemask |= XpmReturnComments;
+    if (attributes->valuemask & XpmReturnExtensions)
+       info->valuemask |= XpmReturnExtensions;
+}
+
+/*
+ * Fill in the XpmInfo with the XpmAttributes
+ */
+void
+xpmSetInfo(
+    XpmInfo            *info,
+    XpmAttributes      *attributes)
+{
+    info->valuemask = 0;
+    if (attributes->valuemask & XpmInfos) {
+       info->valuemask |= XpmComments | XpmColorTable;
+       info->hints_cmt = attributes->hints_cmt;
+       info->colors_cmt = attributes->colors_cmt;
+       info->pixels_cmt = attributes->pixels_cmt;
+    }
+    if (attributes->valuemask & XpmExtensions) {
+       info->valuemask |= XpmExtensions;
+       info->extensions = attributes->extensions;
+       info->nextensions = attributes->nextensions;
+    }
+    if (attributes->valuemask & XpmHotspot) {
+       info->valuemask |= XpmHotspot;
+       info->x_hotspot = attributes->x_hotspot;
+       info->y_hotspot = attributes->y_hotspot;
+    }
+}
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755 (executable)
index 0000000..297d310
--- /dev/null
@@ -0,0 +1,43 @@
+# Daniel Stone disowns all copyright on this file.
+
+lib_LTLIBRARIES=libXpm.la
+
+AM_CPPFLAGS = -I$(top_srcdir)/include/X11/
+AM_CFLAGS = $(CWARNFLAGS) $(XPM_CFLAGS)
+
+libXpm_la_LDFLAGS = -version-number 4:11:0 -no-undefined
+libXpm_la_LIBADD =  $(XPM_LIBS)
+
+libXpm_la_SOURCES =                                    \
+       Attrib.c                                        \
+       CrBufFrI.c                                      \
+       CrBufFrP.c                                      \
+       CrDatFrI.c                                      \
+       CrDatFrP.c                                      \
+       CrIFrBuf.c                                      \
+       CrIFrDat.c                                      \
+       CrIFrP.c                                        \
+       CrPFrBuf.c                                      \
+       CrPFrDat.c                                      \
+       CrPFrI.c                                        \
+       Image.c                                         \
+       Info.c                                          \
+       RdFToBuf.c                                      \
+       RdFToDat.c                                      \
+       RdFToI.c                                        \
+       RdFToP.c                                        \
+       WrFFrBuf.c                                      \
+       WrFFrDat.c                                      \
+       WrFFrI.c                                        \
+       WrFFrP.c                                        \
+       XpmI.h                                          \
+       create.c                                        \
+       data.c                                          \
+       hashtab.c                                       \
+       misc.c                                          \
+       parse.c                                         \
+       rgb.c                                           \
+       rgbtab.h                                        \
+       scan.c
+
+EXTRA_DIST = amigax.c amigax.h simx.c simx.h
diff --git a/src/RdFToBuf.c b/src/RdFToBuf.c
new file mode 100644 (file)
index 0000000..b719960
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* RdFToBuf.c:                                                                 *
+*                                                                             *
+*  XPM library                                                                *
+*  Copy a file to a malloc'ed buffer, provided as a convenience.              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <sys/stat.h>
+#if !defined(FOR_MSW) && !defined(WIN32)
+#include <unistd.h>
+#endif
+#ifndef VAX11C
+#include <fcntl.h>
+#endif
+#if defined(FOR_MSW) || defined(WIN32)
+#include <io.h>
+#define stat _stat
+#define fstat _fstat
+#define fdopen _fdopen
+#define O_RDONLY _O_RDONLY
+#endif
+
+int
+XpmReadFileToBuffer(
+    char        *filename,
+    char       **buffer_return)
+{
+    int fd, fcheck;
+    off_t len;
+    char *ptr;
+    struct stat stats;
+    FILE *fp;
+
+    *buffer_return = NULL;
+
+#ifndef VAX11C
+    fd = open(filename, O_RDONLY);
+#else
+    fd = open(filename, O_RDONLY, NULL);
+#endif
+    if (fd < 0)
+       return XpmOpenFailed;
+
+    if (fstat(fd, &stats)) {
+       close(fd);
+       return XpmOpenFailed;
+    }
+    fp = fdopen(fd, "r");
+    if (!fp) {
+       close(fd);
+       return XpmOpenFailed;
+    }
+    len = stats.st_size;
+    ptr = (char *) XpmMalloc(len + 1);
+    if (!ptr) {
+       fclose(fp);
+       return XpmNoMemory;
+    }
+    fcheck = fread(ptr, 1, len, fp);
+    fclose(fp);
+#ifdef VMS
+    /* VMS often stores text files in a variable-length record format,
+       where there are two bytes of size followed by the record.  fread        
+       converts this so it looks like a record followed by a newline.  
+       Unfortunately, the size reported by fstat() (and fseek/ftell)   
+       counts the two bytes for the record terminator, while fread()   
+       counts only one.  So, fread() sees fewer bytes in the file (size        
+       minus # of records) and thus when asked to read the amount      
+       returned by stat(), it fails.
+       The best solution, suggested by DEC, seems to consider the length
+       returned from fstat() as an upper bound and call fread() with
+       a record length of 1. Then don't check the return value.
+       We'll check for 0 for gross error that's all.
+    */
+    len = fcheck;
+    if (fcheck == 0) {
+#else
+    if (fcheck != len) {
+#endif
+       XpmFree(ptr);
+       return XpmOpenFailed;
+    }
+    ptr[len] = '\0';
+    *buffer_return = ptr;
+    return XpmSuccess;
+}
diff --git a/src/RdFToDat.c b/src/RdFToDat.c
new file mode 100644 (file)
index 0000000..87f7f1e
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  RdFToDat.c:                                                                *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file and create an array of strings corresponding to it.      *
+*                                                                             *
+*  Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com              *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmReadFileToData(
+    char         *filename,
+    char       ***data_return)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+
+    info.valuemask = XpmReturnComments | XpmReturnExtensions;
+
+    /*
+     * initialize return value
+     */
+    if (data_return)
+       *data_return = NULL;
+
+    ErrorStatus = XpmReadFileToXpmImage(filename, &image, &info);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    ErrorStatus =
+       XpmCreateDataFromXpmImage(data_return, &image, &info);
+
+    XpmFreeXpmImage(&image);
+    XpmFreeXpmInfo(&info);
+
+    return (ErrorStatus);
+}
diff --git a/src/RdFToI.c b/src/RdFToI.c
new file mode 100755 (executable)
index 0000000..e56e3f8
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  RdFToI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file and create the image and possibly its mask               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#ifndef NO_ZPIPE
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#else
+#ifdef FOR_MSW
+#include <fcntl.h>
+#endif
+#endif
+
+LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
+LFUNC(xpmDataClose, void, (xpmData *mdata));
+
+FUNC(xpmPipeThrough, FILE*, (int fd,
+                            const char *cmd,
+                            const char *arg1,
+                            const char *mode));
+
+#ifndef CXPMPROG
+int
+XpmReadFileToImage(
+    Display             *display,
+    char                *filename,
+    XImage             **image_return,
+    XImage             **shapeimage_return,
+    XpmAttributes       *attributes)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+    xpmData mdata;
+
+    xpmInitXpmImage(&image);
+    xpmInitXpmInfo(&info);
+
+    /* open file to read */
+    if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
+       return (ErrorStatus);
+
+    /* create the XImage from the XpmData */
+    if (attributes) {
+       xpmInitAttributes(attributes);
+       xpmSetInfoMask(&info, attributes);
+       ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+                                           image_return, shapeimage_return,
+                                           &image, &info, attributes);
+    } else
+       ErrorStatus = xpmParseDataAndCreate(display, &mdata,
+                                           image_return, shapeimage_return,
+                                           &image, NULL, attributes);
+    if (attributes) {
+       if (ErrorStatus >= 0)           /* no fatal error */
+           xpmSetAttributes(attributes, &image, &info);
+       XpmFreeXpmInfo(&info);
+    }
+
+    xpmDataClose(&mdata);
+    /* free the XpmImage */
+    XpmFreeXpmImage(&image);
+
+    return (ErrorStatus);
+}
+
+int
+XpmReadFileToXpmImage(
+    char       *filename,
+    XpmImage   *image,
+    XpmInfo    *info)
+{
+    xpmData mdata;
+    int ErrorStatus;
+
+    /* init returned values */
+    xpmInitXpmImage(image);
+    xpmInitXpmInfo(info);
+
+    /* open file to read */
+    if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess)
+       return (ErrorStatus);
+
+    /* create the XpmImage from the XpmData */
+    ErrorStatus = xpmParseData(&mdata, image, info);
+
+    xpmDataClose(&mdata);
+
+    return (ErrorStatus);
+}
+#endif /* CXPMPROG */
+
+#ifndef NO_ZPIPE
+/* Do not depend on errno after read_through */
+FILE*
+xpmPipeThrough(
+    int                 fd,
+    const char *cmd,
+    const char *arg1,
+    const char *mode)
+{
+    FILE* fp;
+    int status, fds[2], in = 0, out = 1;
+    pid_t pid;
+    if ( 'w' == *mode )
+       out = 0, in = 1;
+    if ( pipe(fds) < 0 )
+       return NULL;
+    pid = fork();
+    if ( pid < 0 )
+       goto fail1;
+    if ( 0 == pid )
+    {
+       close(fds[in]);
+       if ( dup2(fds[out], out) < 0 )
+           goto err;
+       close(fds[out]);
+       if ( dup2(fd, in) < 0 )
+           goto err;
+       close(fd);
+       pid = fork();
+       if ( pid < 0 )
+           goto err;
+       if ( 0 == pid )
+       {
+           execlp(cmd, cmd, arg1, (char *)NULL);
+           perror(cmd);
+           goto err;
+       }
+       _exit(0);
+    err:
+       _exit(1);
+    }
+    close(fds[out]);
+    /* calling process: wait for first child */
+    while ( waitpid(pid, &status, 0) < 0 && EINTR == errno )
+       ;
+    if ( WIFSIGNALED(status) ||
+        (WIFEXITED(status) && WEXITSTATUS(status) != 0) )
+       goto fail2;
+    fp = fdopen(fds[in], mode);
+    if ( !fp )
+       goto fail2;
+    close(fd); /* still open in 2nd child */
+    return fp;
+fail1:
+    close(fds[out]);
+fail2:
+    close(fds[in]);
+    return NULL;
+}
+#endif
+
+/*
+ * open the given file to be read as an xpmData which is returned.
+ */
+static int
+OpenReadFile(
+    char       *filename,
+    xpmData    *mdata)
+{
+    if (!filename) {
+       mdata->stream.file = (stdin);
+       mdata->type = XPMFILE;
+    } else {
+       int fd = open(filename, O_RDONLY);
+#if defined(NO_ZPIPE)
+       if ( fd < 0 )
+           return XpmOpenFailed;
+#else
+       const char* ext = NULL;
+       if ( fd >= 0 )
+           ext = strrchr(filename, '.');
+#ifdef STAT_ZFILE /* searching for z-files if the given name not found */
+       else
+       {
+           size_t len = strlen(filename);
+           char *compressfile = (char *) XpmMalloc(len + 4);
+           if ( !compressfile )
+               return (XpmNoMemory);
+           strcpy(compressfile, filename);
+           strcpy(compressfile + len, ext = ".Z");
+           fd = open(compressfile, O_RDONLY);
+           if ( fd < 0 )
+           {
+               strcpy(compressfile + len, ext = ".gz");
+               fd = open(compressfile, O_RDONLY);
+               if ( fd < 0 )
+               {
+                   XpmFree(compressfile);
+                   return XpmOpenFailed;
+               }
+           }
+           XpmFree(compressfile);
+       }
+#endif
+       if ( ext && !strcmp(ext, ".Z") )
+       {
+           mdata->type = XPMPIPE;
+           mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r");
+       }
+       else if ( ext && !strcmp(ext, ".gz") )
+       {
+           mdata->type = XPMPIPE;
+           mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r");
+       }
+       else
+#endif /* z-files */
+       {
+           mdata->type = XPMFILE;
+           mdata->stream.file = fdopen(fd, "r");
+       }
+       if (!mdata->stream.file)
+       {
+           close(fd);
+           return (XpmOpenFailed);
+       }
+    }
+    mdata->CommentLength = 0;
+#ifdef CXPMPROG
+    mdata->lineNum = 0;
+    mdata->charNum = 0;
+#endif
+    return (XpmSuccess);
+}
+
+/*
+ * close the file related to the xpmData if any
+ */
+static void
+xpmDataClose(xpmData *mdata)
+{
+    if (mdata->stream.file != (stdin))
+       fclose(mdata->stream.file);
+}
diff --git a/src/RdFToP.c b/src/RdFToP.c
new file mode 100644 (file)
index 0000000..bacedda
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  RdFToP.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file and create the pixmap and possibly its mask              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmReadFileToPixmap(
+    Display            *display,
+    Drawable            d,
+    char               *filename,
+    Pixmap             *pixmap_return,
+    Pixmap             *shapemask_return,
+    XpmAttributes      *attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+       *pixmap_return = 0;
+    if (shapemask_return)
+       *shapemask_return = 0;
+
+    /* create the images */
+    ErrorStatus = XpmReadFileToImage(display, filename,
+                                    (pixmap_return ? &ximage : NULL),
+                                    (shapemask_return ? &shapeimage : NULL),
+                                    attributes);
+
+    if (ErrorStatus < 0)               /* fatal error */
+       return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+       xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+       XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+       xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+       XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
diff --git a/src/WrFFrBuf.c b/src/WrFFrBuf.c
new file mode 100644 (file)
index 0000000..bd1c45b
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* WrFFrBuf.c:                                                                 *
+*                                                                             *
+*  XPM library                                                                *
+*  Write a memory buffer to a file, provided as a convenience.                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmWriteFileFromBuffer(
+    char       *filename,
+    char       *buffer)
+{
+    int fcheck, len;
+    FILE *fp = fopen(filename, "w");
+
+    if (!fp)
+       return XpmOpenFailed;
+
+    len = strlen(buffer);
+    fcheck = fwrite(buffer, len, 1, fp);
+    fclose(fp);
+    if (fcheck != 1)
+       return XpmOpenFailed; /* maybe use a better return value */
+
+    return XpmSuccess;
+}
diff --git a/src/WrFFrDat.c b/src/WrFFrDat.c
new file mode 100644 (file)
index 0000000..dc738b9
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrData.c:                                                               *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an Xpm array and write a file that corresponds to it.                *
+*                                                                             *
+*  Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com              *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmWriteFileFromData(
+    char        *filename,
+    char       **data)
+{
+    XpmImage image;
+    XpmInfo info;
+    int ErrorStatus;
+
+    info.valuemask = XpmReturnComments | XpmReturnExtensions;
+
+    ErrorStatus = XpmCreateXpmImageFromData(data, &image, &info);
+
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    ErrorStatus = XpmWriteFileFromXpmImage(filename, &image, &info);
+
+    XpmFreeXpmImage(&image);
+    XpmFreeXpmInfo(&info);
+
+    return (ErrorStatus);
+}
diff --git a/src/WrFFrI.c b/src/WrFFrI.c
new file mode 100755 (executable)
index 0000000..f2726f9
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Write an image and possibly its mask to an XPM file                        *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+#ifndef NO_ZPIPE
+#include "sys/wait.h"
+#include "sys/types.h"
+#include "fcntl.h"
+#include "unistd.h"
+#include "errno.h"
+#endif
+
+/* MS Windows define a function called WriteFile @#%#&!!! */
+LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, char *name,
+                         XpmInfo *info));
+
+LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors));
+
+LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height,
+                        unsigned int cpp, unsigned int *pixels,
+                        XpmColor *colors));
+
+LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext,
+                             unsigned int num));
+
+LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata));
+LFUNC(xpmDataClose, void, (xpmData *mdata));
+
+int
+XpmWriteFileFromImage(
+    Display            *display,
+    char               *filename,
+    XImage             *image,
+    XImage             *shapeimage,
+    XpmAttributes      *attributes)
+{
+    XpmImage xpmimage;
+    XpmInfo info;
+    int ErrorStatus;
+
+    /* create an XpmImage from the image */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage,
+                                            &xpmimage, attributes);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /* write the file from the XpmImage */
+    if (attributes) {
+       xpmSetInfo(&info, attributes);
+       ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info);
+    } else
+       ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL);
+
+    /* free the XpmImage */
+    XpmFreeXpmImage(&xpmimage);
+
+    return (ErrorStatus);
+}
+
+int
+XpmWriteFileFromXpmImage(
+    char       *filename,
+    XpmImage   *image,
+    XpmInfo    *info)
+{
+    xpmData mdata;
+    char *name, *dot, *s, new_name[BUFSIZ] = {0};
+    int ErrorStatus;
+
+    /* open file to write */
+    if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess)
+       return (ErrorStatus);
+
+    /* figure out a name */
+    if (filename) {
+#ifdef VMS
+       name = filename;
+#else
+       if (!(name = strrchr(filename, '/'))
+#ifdef AMIGA
+           && !(name = strrchr(filename, ':'))
+#endif
+     )
+           name = filename;
+       else
+           name++;
+#endif
+       /* let's try to make a valid C syntax name */
+       if (strchr(name, '.')) {
+           strncpy(new_name, name, sizeof(new_name));
+           new_name[sizeof(new_name)-1] = '\0';
+           /* change '.' to '_' */
+           name = s = new_name;
+           while ((dot = strchr(s, '.'))) {
+               *dot = '_';
+               s = dot;
+           }
+       }
+       if (strchr(name, '-')) {
+           if (name != new_name) {
+               strncpy(new_name, name, sizeof(new_name));
+               new_name[sizeof(new_name)-1] = '\0';
+               name = new_name;
+           }
+           /* change '-' to '_' */
+           s = name;
+           while ((dot = strchr(s, '-'))) {
+               *dot = '_';
+               s = dot;
+           }
+       }
+    } else
+       name = "image_name";
+
+    /* write the XpmData from the XpmImage */
+    if (ErrorStatus == XpmSuccess)
+       ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info);
+
+    xpmDataClose(&mdata);
+
+    return (ErrorStatus);
+}
+
+static int
+xpmWriteFile(
+    FILE       *file,
+    XpmImage   *image,
+    char       *name,
+    XpmInfo    *info)
+{
+    /* calculation variables */
+    unsigned int cmts, extensions;
+    int ErrorStatus;
+
+    cmts = info && (info->valuemask & XpmComments);
+    extensions = info && (info->valuemask & XpmExtensions)
+       && info->nextensions;
+
+    /* print the header line */
+    fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name);
+
+    /* print the hints line */
+    if (cmts && info->hints_cmt)
+       fprintf(file, "/*%s*/\n", info->hints_cmt);
+
+    fprintf(file, "\"%d %d %d %d", image->width, image->height,
+           image->ncolors, image->cpp);
+
+    if (info && (info->valuemask & XpmHotspot))
+       fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot);
+
+    if (extensions)
+       fprintf(file, " XPMEXT");
+
+    fprintf(file, "\",\n");
+
+    /* print colors */
+    if (cmts && info->colors_cmt)
+       fprintf(file, "/*%s*/\n", info->colors_cmt);
+
+    WriteColors(file, image->colorTable, image->ncolors);
+
+    /* print pixels */
+    if (cmts && info->pixels_cmt)
+       fprintf(file, "/*%s*/\n", info->pixels_cmt);
+
+    ErrorStatus = WritePixels(file, image->width, image->height, image->cpp,
+                             image->data, image->colorTable);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /* print extensions */
+    if (extensions)
+       WriteExtensions(file, info->extensions, info->nextensions);
+
+    /* close the array */
+    fprintf(file, "};\n");
+
+    return (XpmSuccess);
+}
+
+static void
+WriteColors(
+    FILE               *file,
+    XpmColor           *colors,
+    unsigned int        ncolors)
+{
+    unsigned int a, key;
+    char *s;
+    char **defaults;
+
+    for (a = 0; a < ncolors; a++, colors++) {
+
+       defaults = (char **) colors;
+       fprintf(file, "\"%s", *defaults++);
+
+       for (key = 1; key <= NKEYS; key++, defaults++) {
+           if ((s = *defaults))
+               fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s);
+       }
+       fprintf(file, "\",\n");
+    }
+}
+
+
+static int
+WritePixels(
+    FILE               *file,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int        cpp,
+    unsigned int       *pixels,
+    XpmColor           *colors)
+{
+    char *s, *p, *buf;
+    unsigned int x, y, h;
+
+    h = height - 1;
+    if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) 
+       return XpmNoMemory;    
+    p = buf = (char *) XpmMalloc(width * cpp + 3);
+    if (!buf)
+       return (XpmNoMemory);
+    *buf = '"';
+    p++;
+    for (y = 0; y < h; y++) {
+       s = p;
+       for (x = 0; x < width; x++, pixels++) {
+           strncpy(s, colors[*pixels].string, cpp);
+           s += cpp;
+       }
+       *s++ = '"';
+       *s = '\0';
+       fprintf(file, "%s,\n", buf);
+    }
+    /* duplicate some code to avoid a test in the loop */
+    s = p;
+    for (x = 0; x < width; x++, pixels++) {
+       strncpy(s, colors[*pixels].string, cpp);
+       s += cpp;
+    }
+    *s++ = '"';
+    *s = '\0';
+    fprintf(file, "%s", buf);
+
+    XpmFree(buf);
+    return (XpmSuccess);
+}
+
+static void
+WriteExtensions(
+    FILE               *file,
+    XpmExtension       *ext,
+    unsigned int        num)
+{
+    unsigned int x, y, n;
+    char **line;
+
+    for (x = 0; x < num; x++, ext++) {
+       fprintf(file, ",\n\"XPMEXT %s\"", ext->name);
+       n = ext->nlines;
+       for (y = 0, line = ext->lines; y < n; y++, line++)
+           fprintf(file, ",\n\"%s\"", *line);
+    }
+    fprintf(file, ",\n\"XPMENDEXT\"");
+}
+
+
+#ifndef NO_ZPIPE
+FUNC(xpmPipeThrough, FILE*, (int fd,
+                            const char* cmd,
+                            const char* arg1,
+                            const char* mode));
+#endif
+
+/*
+ * open the given file to be written as an xpmData which is returned
+ */
+static int
+OpenWriteFile(
+    char       *filename,
+    xpmData    *mdata)
+{
+    if (!filename) {
+       mdata->stream.file = (stdout);
+       mdata->type = XPMFILE;
+    } else {
+#ifndef NO_ZPIPE
+       size_t len;
+#endif
+       int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
+       if ( fd < 0 )
+           return(XpmOpenFailed);
+#ifndef NO_ZPIPE
+       len = strlen(filename);
+       if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
+           mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w");
+           mdata->type = XPMPIPE;
+       } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
+           mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w");
+           mdata->type = XPMPIPE;
+       } else
+#endif
+       {
+           mdata->stream.file = fdopen(fd, "w");
+           mdata->type = XPMFILE;
+       }
+       if (!mdata->stream.file)
+           return (XpmOpenFailed);
+    }
+    return (XpmSuccess);
+}
+
+/*
+ * close the file related to the xpmData if any
+ */
+static void
+xpmDataClose(xpmData *mdata)
+{
+    if (mdata->stream.file != (stdout))
+       fclose(mdata->stream.file);
+}
+
diff --git a/src/WrFFrP.c b/src/WrFFrP.c
new file mode 100644 (file)
index 0000000..497ba56
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrP.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Write a pixmap and possibly its mask to an XPM file                        *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+int
+XpmWriteFileFromPixmap(
+    Display            *display,
+    char               *filename,
+    Pixmap              pixmap,
+    Pixmap              shapemask,
+    XpmAttributes      *attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+       width = attributes->width;
+       height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+       xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+       xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+                                &width, &height);
+
+    /* write to the file */
+    ErrorStatus = XpmWriteFileFromImage(display, filename, ximage, shapeimage,
+                                       attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+       XDestroyImage(ximage);
+    if (shapeimage)
+       XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
diff --git a/src/XpmI.h b/src/XpmI.h
new file mode 100755 (executable)
index 0000000..9d4b1ae
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* XpmI.h:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Internal Include file                                                      *
+*                                                                             *
+*  ** Everything defined here is subject to changes any time. **              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+#ifndef XPMI_h
+#define XPMI_h
+
+#include "xpm.h"
+
+/*
+ * lets try to solve include files
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+/* stdio.h doesn't declare popen on a Sequent DYNIX OS */
+#ifdef sequent
+extern FILE *popen();
+#endif
+
+#ifdef FOR_MSW
+#include "simx.h"
+#else
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xmd.h>
+#endif
+
+#ifdef VMS
+#include <unixio.h>
+#include <file.h>
+#endif
+
+/* The following should help people wanting to use their own memory allocation
+ * functions. To avoid the overhead of a function call when the standard
+ * functions are used these are all macros, even the XpmFree function which
+ * needs to be a real function for the outside world though.
+ * So if change these be sure to change the XpmFree function in misc.c
+ * accordingly.
+ */
+#define XpmFree(ptr) free(ptr)
+
+#ifndef FOR_MSW
+#define XpmMalloc(size) malloc((size))
+#define XpmRealloc(ptr, size) realloc((ptr), (size))
+#define XpmCalloc(nelem, elsize) calloc((nelem), (elsize))
+#else
+/* checks for mallocs bigger than 64K */
+#define XpmMalloc(size) boundCheckingMalloc((long)(size))/* in simx.[ch] */
+#define XpmRealloc(ptr, size) boundCheckingRealloc((ptr),(long)(size))
+#define XpmCalloc(nelem, elsize) \
+               boundCheckingCalloc((long)(nelem),(long) (elsize))
+#endif
+
+#if defined(SCO) || defined(__USLC__)
+#include <stdint.h>    /* For SIZE_MAX */
+#endif
+#include <limits.h>
+#ifndef SIZE_MAX
+# ifdef ULONG_MAX
+#  define SIZE_MAX ULONG_MAX
+# else 
+#  define SIZE_MAX UINT_MAX
+# endif
+#endif
+
+#define XPMMAXCMTLEN BUFSIZ
+typedef struct {
+    unsigned int type;
+    union {
+       FILE *file;
+       char **data;
+    }     stream;
+    char *cptr;
+    unsigned int line;
+    int CommentLength;
+    char Comment[XPMMAXCMTLEN];
+    char *Bcmt, *Ecmt, Bos, Eos;
+    int format;                        /* 1 if XPM1, 0 otherwise */
+#ifdef CXPMPROG
+    int lineNum;
+    int charNum;
+#endif
+}      xpmData;
+
+#define XPMARRAY 0
+#define XPMFILE  1
+#define XPMPIPE  2
+#define XPMBUFFER 3
+
+#define EOL '\n'
+#define TAB '\t'
+#define SPC ' '
+
+typedef struct {
+    char *type;                        /* key word */
+    char *Bcmt;                        /* string beginning comments */
+    char *Ecmt;                        /* string ending comments */
+    char Bos;                  /* character beginning strings */
+    char Eos;                  /* character ending strings */
+    char *Strs;                        /* strings separator */
+    char *Dec;                 /* data declaration string */
+    char *Boa;                 /* string beginning assignment */
+    char *Eoa;                 /* string ending assignment */
+}      xpmDataType;
+
+extern xpmDataType xpmDataTypes[];
+
+/*
+ * rgb values and ascii names (from rgb text file) rgb values,
+ * range of 0 -> 65535 color mnemonic of rgb value
+ */
+typedef struct {
+    int r, g, b;
+    char *name;
+}      xpmRgbName;
+
+/* Maximum number of rgb mnemonics allowed in rgb text file. */
+#define MAX_RGBNAMES 1024
+
+extern char *xpmColorKeys[];
+
+#define TRANSPARENT_COLOR "None"       /* this must be a string! */
+
+/* number of xpmColorKeys */
+#define NKEYS 5
+
+/* XPM internal routines */
+
+FUNC(xpmParseData, int, (xpmData *data, XpmImage *image, XpmInfo *info));
+FUNC(xpmParseDataAndCreate, int, (Display *display, xpmData *data,
+                                 XImage **image_return,
+                                 XImage **shapeimage_return,
+                                 XpmImage *image, XpmInfo *info,
+                                 XpmAttributes *attributes));
+
+FUNC(xpmFreeColorTable, void, (XpmColor *colorTable, int ncolors));
+
+FUNC(xpmInitAttributes, void, (XpmAttributes *attributes));
+
+FUNC(xpmInitXpmImage, void, (XpmImage *image));
+
+FUNC(xpmInitXpmInfo, void, (XpmInfo *info));
+
+FUNC(xpmSetInfoMask, void, (XpmInfo *info, XpmAttributes *attributes));
+FUNC(xpmSetInfo, void, (XpmInfo *info, XpmAttributes *attributes));
+FUNC(xpmSetAttributes, void, (XpmAttributes *attributes, XpmImage *image,
+                             XpmInfo *info));
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+FUNC(xpmCreatePixmapFromImage, void, (Display *display, Drawable d,
+                                     XImage *ximage, Pixmap *pixmap_return));
+
+FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap,
+                                     XImage **ximage_return,
+                                     unsigned int *width,
+                                     unsigned int *height));
+#endif
+
+/* structures and functions related to hastable code */
+
+typedef struct _xpmHashAtom {
+    char *name;
+    void *data;
+}      *xpmHashAtom;
+
+typedef struct {
+    unsigned int size;
+    unsigned int limit;
+    unsigned int used;
+    xpmHashAtom *atomTable;
+}      xpmHashTable;
+
+FUNC(xpmHashTableInit, int, (xpmHashTable *table));
+FUNC(xpmHashTableFree, void, (xpmHashTable *table));
+FUNC(xpmHashSlot, xpmHashAtom *, (xpmHashTable *table, char *s));
+FUNC(xpmHashIntern, int, (xpmHashTable *table, char *tag, void *data));
+
+#define HashAtomData(i) ((void *)(long)i)
+#define HashColorIndex(slot) ((unsigned long)((*slot)->data))
+#define USE_HASHTABLE (cpp > 2 && ncolors > 4)
+
+/* I/O utility */
+
+FUNC(xpmNextString, int, (xpmData *mdata));
+FUNC(xpmNextUI, int, (xpmData *mdata, unsigned int *ui_return));
+FUNC(xpmGetString, int, (xpmData *mdata, char **sptr, unsigned int *l));
+
+#define xpmGetC(mdata) \
+       ((!mdata->type || mdata->type == XPMBUFFER) ? \
+        (*mdata->cptr++) : (getc(mdata->stream.file)))
+
+FUNC(xpmNextWord, unsigned int,
+     (xpmData *mdata, char *buf, unsigned int buflen));
+FUNC(xpmGetCmt, int, (xpmData *mdata, char **cmt));
+FUNC(xpmParseHeader, int, (xpmData *mdata));
+FUNC(xpmParseValues, int, (xpmData *data, unsigned int *width,
+                          unsigned int *height, unsigned int *ncolors,
+                          unsigned int *cpp, unsigned int *x_hotspot,
+                          unsigned int *y_hotspot, unsigned int *hotspot,
+                          unsigned int *extensions));
+
+FUNC(xpmParseColors, int, (xpmData *data, unsigned int ncolors,
+                          unsigned int cpp, XpmColor **colorTablePtr,
+                          xpmHashTable *hashtable));
+
+FUNC(xpmParseExtensions, int, (xpmData *data, XpmExtension **extensions,
+                              unsigned int *nextensions));
+
+/* RGB utility */
+
+FUNC(xpmReadRgbNames, int, (char *rgb_fname, xpmRgbName *rgbn));
+FUNC(xpmGetRgbName, char *, (xpmRgbName *rgbn, int rgbn_max,
+                            int red, int green, int blue));
+FUNC(xpmFreeRgbNames, void, (xpmRgbName *rgbn, int rgbn_max));
+#ifdef FOR_MSW
+FUNC(xpmGetRGBfromName,int, (char *name, int *r, int *g, int *b));
+#endif
+
+#ifndef AMIGA
+FUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp,
+                                     register XImage *img));
+FUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp,
+                                    register XImage *img));
+
+/*
+ * Macros
+ *
+ * The XYNORMALIZE macro determines whether XY format data requires
+ * normalization and calls a routine to do so if needed. The logic in
+ * this module is designed for LSBFirst byte and bit order, so
+ * normalization is done as required to present the data in this order.
+ *
+ * The ZNORMALIZE macro performs byte and nibble order normalization if
+ * required for Z format data.
+ *
+ * The XYINDEX macro computes the index to the starting byte (char) boundary
+ * for a bitmap_unit containing a pixel with coordinates x and y for image
+ * data in XY format.
+ *
+ * The ZINDEX* macros compute the index to the starting byte (char) boundary
+ * for a pixel with coordinates x and y for image data in ZPixmap format.
+ *
+ */
+
+#define XYNORMALIZE(bp, img) \
+    if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \
+       xpm_xynormalizeimagebits((unsigned char *)(bp), img)
+
+#define ZNORMALIZE(bp, img) \
+    if (img->byte_order == MSBFirst) \
+       xpm_znormalizeimagebits((unsigned char *)(bp), img)
+
+#define XYINDEX(x, y, img) \
+    ((y) * img->bytes_per_line) + \
+    (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3)
+
+#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \
+    (((x) * img->bits_per_pixel) >> 3)
+
+#define ZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2)
+
+#define ZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1)
+
+#define ZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x)
+
+#define ZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3)
+#endif /* not AMIGA */
+
+#ifdef __STDC__
+#define Const const
+#else
+#define Const /**/
+#endif
+
+#ifdef NEED_STRDUP
+FUNC(xpmstrdup, char *, (char *s1));
+#else
+#undef xpmstrdup
+#define xpmstrdup strdup
+#endif
+
+#ifdef NEED_STRCASECMP                   
+FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
+#else
+#undef xpmstrcasecmp
+#define xpmstrcasecmp strcasecmp
+#endif
+
+FUNC(xpmatoui, unsigned int,
+     (char *p, unsigned int l, unsigned int *ui_return));
+
+#endif
diff --git a/src/amigax.c b/src/amigax.c
new file mode 100644 (file)
index 0000000..eb3bc3a
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 19896 Lorens Younes
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Lorens Younes shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Lorens Younes.
+ */
+
+/*****************************************************************************\
+* amigax.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Emulates some Xlib functionality for Amiga.                                *
+*                                                                             *
+*  Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95                      *
+*  Revised 4/96                                                               *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include "amigax.h"
+
+#include <graphics/gfxbase.h>
+#include <intuition/screens.h>
+
+#include <proto/exec.h>
+
+
+static struct RastPort *
+AllocRastPort (unsigned int, unsigned int, unsigned int);
+static void
+FreeRastPort (struct RastPort *, unsigned int,unsigned int);
+
+
+static struct RastPort *
+AllocRastPort (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth)
+{
+    struct RastPort  *rp;
+    
+    rp = XpmMalloc (sizeof (*rp));
+    if (rp != NULL)
+    {
+       InitRastPort (rp);
+       if (GfxBase->LibNode.lib_Version >= 39)
+       {
+           rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL);
+           if (rp->BitMap == NULL)
+           {
+               FreeRastPort (rp, width, height);
+               return NULL;
+           }
+       }
+       else
+       {
+           unsigned int   i;
+           
+           rp->BitMap = XpmMalloc (sizeof (*rp->BitMap));
+           if (rp->BitMap == NULL)
+           {
+               FreeRastPort (rp, width, height);
+               return NULL;
+           }
+           
+           InitBitMap (rp->BitMap, depth, width, height);
+           for (i = 0; i < depth; ++i)
+               rp->BitMap->Planes[i] = NULL;
+           for (i = 0; i < depth; ++i)
+           {
+               rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height);
+               if (rp->BitMap->Planes[i] == NULL)
+               {
+                   FreeRastPort (rp, width, height);
+                   return NULL;
+               }
+           }
+       }
+    }
+    
+    return rp;
+}
+
+
+static void
+FreeRastPort (
+    struct RastPort  *rp,
+    unsigned int      width,
+    unsigned int      height)
+{
+    if (rp != NULL)
+    {
+       if (rp->BitMap != NULL)
+       {
+           WaitBlit ();
+           if (GfxBase->LibNode.lib_Version >= 39)
+               FreeBitMap (rp->BitMap);
+           else
+           {
+               unsigned int   i;
+               
+               for (i = 0; i < rp->BitMap->Depth; ++i)
+               {
+                   if (rp->BitMap->Planes[i] != NULL)
+                       FreeRaster (rp->BitMap->Planes[i], width, height);
+               }
+               XpmFree (rp->BitMap);
+           }
+       }
+       XpmFree (rp);
+    }
+}
+
+
+XImage *
+AllocXImage (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth)
+{
+    XImage  *img;
+    
+    img = XpmMalloc (sizeof (*img));
+    if (img != NULL)
+    {
+       img->width = width;
+       img->height = height;
+       img->rp = AllocRastPort (img->width, img->height, depth);
+       if (img->rp == NULL)
+       {
+           FreeXImage (img);
+           return NULL;
+       }
+    }
+    
+    return img;
+}
+
+
+int
+FreeXImage (
+    XImage  *ximage)
+{
+    if (ximage != NULL)
+    {
+       FreeRastPort (ximage->rp, ximage->width, ximage->height);
+       XpmFree (ximage);
+    }
+    
+    return Success;
+}
+
+
+int
+XPutPixel (
+    XImage         *ximage,
+    int             x,
+    int             y,
+    unsigned long   pixel)
+{
+    SetAPen (ximage->rp, pixel);
+    WritePixel (ximage->rp, x, y);
+    
+    return Success;
+}
+
+
+Status
+AllocBestPen (
+    Colormap        colormap,
+    XColor         *screen_in_out,
+    unsigned long   precision,
+    Bool            fail_if_bad)
+{
+    if (GfxBase->LibNode.lib_Version >= 39)
+    {
+       unsigned long   r, g, b;
+       
+       r = screen_in_out->red * 0x00010001;
+       g = screen_in_out->green * 0x00010001;
+       b = screen_in_out->blue * 0x00010001;
+       screen_in_out->pixel = ObtainBestPen (colormap, r, g, b,
+                                             OBP_Precision, precision,
+                                             OBP_FailIfBad, fail_if_bad,
+                                             TAG_DONE);
+       if (screen_in_out->pixel == -1)
+           return False;
+       
+       QueryColor (colormap, screen_in_out);
+    }
+    else
+    {
+       XColor   nearest, trial;
+       long     nearest_delta, trial_delta;
+       int      num_cells, i;
+       
+       num_cells = colormap->Count;
+       nearest.pixel = 0;
+       QueryColor (colormap, &nearest);
+       nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8))
+                         * ((screen_in_out->red >> 8) - (nearest.red >> 8)))
+                        +
+                        (((screen_in_out->green >> 8) - (nearest.green >> 8))
+                         * ((screen_in_out->green >> 8) - (nearest.green >> 8)))
+                        +
+                        (((screen_in_out->blue >> 8) - (nearest.blue >> 8))
+                         * ((screen_in_out->blue >> 8) - (nearest.blue >> 8))));
+       for (i = 1; i < num_cells; i++)
+       {
+       /* precision and fail_if_bad is ignored under pre V39 */
+           trial.pixel = i;
+           QueryColor (colormap, &trial);
+           trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8))
+                           * ((screen_in_out->red >> 8) - (trial.red >> 8)))
+                          +
+                          (((screen_in_out->green >> 8) - (trial.green >> 8))
+                           * ((screen_in_out->green >> 8) - (trial.green >> 8)))
+                          +
+                          (((screen_in_out->blue >> 8) - (trial.blue >> 8))
+                           * ((screen_in_out->blue >> 8) - (trial.blue >> 8))));
+           if (trial_delta < nearest_delta)
+           {
+               nearest = trial;
+               nearest_delta = trial_delta;
+           }
+       }
+       screen_in_out->pixel = nearest.pixel;
+       screen_in_out->red = nearest.red;
+       screen_in_out->green = nearest.green;
+       screen_in_out->blue = nearest.blue;
+    }
+    
+    return True;
+}
+
+
+int
+FreePens (
+    Colormap        colormap,
+    unsigned long  *pixels,
+    int             npixels)
+{
+    if (GfxBase->LibNode.lib_Version >= 39)
+    {
+       int   i;
+       
+       for (i = 0; i < npixels; i++)
+           ReleasePen (colormap, pixels[i]);
+    }
+    
+    return Success;
+}
+
+
+Status
+ParseColor (
+    char    *spec,
+    XColor  *exact_def_return)
+{
+    int spec_length;
+    
+    if (spec == 0)
+       return False;
+    
+    spec_length = strlen(spec);
+    if (spec[0] == '#')
+    {
+       int hexlen;
+       char hexstr[10];
+       
+       hexlen = (spec_length - 1) / 3;
+       if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1)
+           return False;
+       
+       hexstr[hexlen] = '\0';
+       strncpy (hexstr, spec + 1, hexlen);
+       exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+       strncpy (hexstr, spec + 1 + hexlen, hexlen);
+       exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+       strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen);
+       exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen);
+       
+       return True;
+    }
+    else
+    {
+       FILE  *rgbf;
+       int    items, red, green, blue;
+       char   line[512], name[512];
+       Bool   success = False;
+       
+       rgbf = fopen ("LIBS:rgb.txt", "r");
+       if (rgbf == NULL)
+           return False;
+       
+       while (fgets(line, sizeof (line), rgbf) && !success)
+       {
+           items = sscanf (line, "%d %d %d %[^\n]\n",
+                           &red, &green, &blue, name);
+           if (items != 4)
+               continue;
+           
+           if (red < 0 || red > 0xFF
+               || green < 0 || green > 0xFF
+               || blue < 0 || blue > 0xFF)
+           {
+               continue;
+           }
+           
+           if (0 == xpmstrcasecmp (spec, name))
+           {
+               exact_def_return->red = red * 0x0101;
+               exact_def_return->green = green * 0x0101;
+               exact_def_return->blue = blue * 0x0101;
+               success = True;
+           }
+       }
+       fclose (rgbf);
+       
+       return success;
+    }
+}
+
+
+int
+QueryColor (
+    Colormap   colormap,
+    XColor    *def_in_out)
+{
+    if (GfxBase->LibNode.lib_Version >= 39)
+    {
+       unsigned long   rgb[3];
+       
+       GetRGB32 (colormap, def_in_out->pixel, 1, rgb);
+       def_in_out->red = rgb[0] >> 16;
+       def_in_out->green = rgb[1] >> 16;
+       def_in_out->blue = rgb[2] >> 16;
+    }
+    else
+    {
+       unsigned short   rgb;
+       
+       rgb = GetRGB4 (colormap, def_in_out->pixel);
+       def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111;
+       def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111;
+       def_in_out->blue = (rgb & 0xF) * 0x1111;
+    }
+    
+    return Success;
+}
+
+
+int
+QueryColors (
+    Colormap   colormap,
+    XColor    *defs_in_out,
+    int        ncolors)
+{
+    int   i;
+    
+    for (i = 0; i < ncolors; i++)
+       QueryColor (colormap, &defs_in_out[i]);
+    
+    return Success;
+}
diff --git a/src/amigax.h b/src/amigax.h
new file mode 100644 (file)
index 0000000..213ed76
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 1996 Lorens Younes
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Lorens Younes shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Lorens Younes.
+ */
+
+/*****************************************************************************\
+* amigax.h:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Emulates some Xlib functionality for Amiga.                                *
+*                                                                             *
+*  Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95                      *
+*  Revised 4/96                                                               *
+\*****************************************************************************/
+
+#ifndef AMIGA_X
+#define AMIGA_X
+
+
+#include <intuition/screens.h>
+
+#include <proto/exec.h>
+#include <proto/graphics.h>
+
+
+#define Success   0
+
+/* really never used */
+#define ZPixmap   2
+
+#define Bool     int
+#define Status   int
+#define True     1
+#define False    0
+
+typedef struct ColorMap  *Colormap;
+
+typedef void  *Visual;
+
+typedef struct {
+    int               width, height;
+    struct RastPort  *rp;
+}   XImage;
+
+typedef struct {
+    unsigned long    pixel;
+    unsigned short   red, green, blue;
+}   XColor;
+
+typedef struct Screen   Display;
+
+
+#define XGrabServer(dpy)     (Forbid ())
+#define XUngrabServer(dpy)   (Permit ())
+
+#define XDefaultScreen(dpy)          (0)
+#define XDefaultVisual(dpy, scr)     (NULL)
+#define XDefaultColormap(dpy, scr)   (dpy->ViewPort.ColorMap)
+#define XDefaultDepth(dpy, scr)      (dpy->RastPort.BitMap->Depth)
+
+#define XCreateImage(dpy, vi, depth, format, offset, data, width, height, pad, bpl) \
+       (AllocXImage (width, height, depth))
+#define XDestroyImage(img)   (FreeXImage (img))
+
+#define XAllocColor(dpy, cm, xc) \
+       (AllocBestPen (cm, xc, PRECISION_EXACT, True))
+#define XFreeColors(dpy, cm, pixels, npixels, planes) \
+       (FreePens (cm, pixels, npixels))
+#define XParseColor(dpy, cm, spec, exact_def_return) \
+       (ParseColor (spec, exact_def_return))
+#define XQueryColor(dpy, cm, def_in_out) \
+       (QueryColor(cm, def_in_out))
+#define XQueryColors(dpy, cm, defs_in_out, ncolors) \
+       (QueryColors(cm, defs_in_out, ncolors))
+
+
+XImage *
+AllocXImage (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth);
+
+
+int
+FreeXImage (
+    XImage  *ximage);
+
+
+int
+XPutPixel (
+    XImage         *ximage,
+    int             x,
+    int             y,
+    unsigned long   pixel);
+
+
+Status
+AllocBestPen (
+    Colormap        colormap,
+    XColor         *screen_in_out,
+    unsigned long   precision,
+    Bool            fail_if_bad);
+
+
+int
+FreePens (
+    Colormap        colormap,
+    unsigned long  *pixels,
+    int             npixels);
+
+
+Status
+ParseColor (
+    char      *spec,
+    XColor    *exact_def_return);
+
+
+int
+QueryColor (
+    Colormap   colormap,
+    XColor    *def_in_out);
+
+
+int
+QueryColors (
+    Colormap   colormap,
+    XColor    *defs_in_out,
+    int        ncolors);
+
+
+#endif /* AMIGA_X */
diff --git a/src/create.c b/src/create.c
new file mode 100755 (executable)
index 0000000..7c75a42
--- /dev/null
@@ -0,0 +1,2517 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* create.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Create an X image and possibly its related shape mask                      *
+*  from the given XpmImage.                                                   *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <ctype.h>
+
+LFUNC(xpmVisualType, int, (Visual *visual));
+
+LFUNC(AllocColor, int, (Display *display, Colormap colormap,
+                       char *colorname, XColor *xcolor, void *closure));
+LFUNC(FreeColors, int, (Display *display, Colormap colormap,
+                       Pixel *pixels, int n, void *closure));
+
+#ifndef FOR_MSW
+LFUNC(SetCloseColor, int, (Display *display, Colormap colormap,
+                          Visual *visual, XColor *col,
+                          Pixel *image_pixel, Pixel *mask_pixel,
+                          Pixel *alloc_pixels, unsigned int *nalloc_pixels,
+                          XpmAttributes *attributes, XColor *cols, int ncols,
+                          XpmAllocColorFunc allocColor, void *closure));
+#else
+/* let the window system take care of close colors */
+#endif
+
+LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual,
+                     char *colorname, unsigned int color_index,
+                     Pixel *image_pixel, Pixel *mask_pixel,
+                     unsigned int *mask_pixel_index,
+                     Pixel *alloc_pixels, unsigned int *nalloc_pixels,
+                     Pixel *used_pixels, unsigned int *nused_pixels,
+                     XpmAttributes *attributes, XColor *cols, int ncols,
+                     XpmAllocColorFunc allocColor, void *closure));
+
+LFUNC(CreateXImage, int, (Display *display, Visual *visual,
+                         unsigned int depth, int format, unsigned int width,
+                          unsigned int height, XImage **image_return));
+
+LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes,
+                          XpmColor *colors, unsigned int ncolors,
+                          Pixel *image_pixels, Pixel *mask_pixels,
+                          unsigned int *mask_pixel_index,
+                          Pixel *alloc_pixels, unsigned int *nalloc_pixels,
+                          Pixel *used_pixels, unsigned int *nused_pixels));
+
+#ifndef FOR_MSW
+LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width,
+                              unsigned int height, unsigned int ncolors,
+                              unsigned int cpp, XpmColor *colorTable,
+                              xpmHashTable *hashtable,
+                              XImage *image, Pixel *image_pixels,
+                              XImage *mask, Pixel *mask_pixels));
+#else  /* FOR_MSW */
+LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width,
+                              unsigned int height, unsigned int ncolors,
+                              unsigned int cpp, XpmColor *colorTable,
+                              xpmHashTable *hashtable,
+                              XImage *image, Pixel *image_pixels,
+                              XImage *mask, Pixel *mask_pixels));
+#endif
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+/* XImage pixel routines */
+LFUNC(PutImagePixels, void, (XImage *image, unsigned int width,
+                            unsigned int height, unsigned int *pixelindex,
+                            Pixel *pixels));
+
+LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width,
+                              unsigned int height, unsigned int *pixelindex,
+                              Pixel *pixels));
+
+LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width,
+                              unsigned int height, unsigned int *pixelindex,
+                              Pixel *pixels));
+
+LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width,
+                             unsigned int height, unsigned int *pixelindex,
+                             Pixel *pixels));
+
+LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width,
+                             unsigned int height, unsigned int *pixelindex,
+                             Pixel *pixels));
+
+LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel));
+#if !defined(WORD64) && !defined(LONG64)
+LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel));
+#endif
+LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel));
+
+# else /* AMIGA */
+LFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width,
+                             unsigned int height, unsigned int *pixelindex,
+                             Pixel *pixels));
+# endif/* AMIGA */
+#else  /* FOR_MSW */
+/* FOR_MSW pixel routine */
+LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image,
+                               unsigned int width, unsigned int height,
+                               unsigned int *pixelindex, Pixel *pixels));
+#endif /* FOR_MSW */
+
+#ifdef NEED_STRCASECMP
+FUNC(xpmstrcasecmp, int, (char *s1, char *s2));
+
+/*
+ * in case strcasecmp is not provided by the system here is one
+ * which does the trick
+ */
+int
+xpmstrcasecmp(
+    register char      *s1,
+    register char      *s2)
+{
+    register int c1, c2;
+
+    while (*s1 && *s2) {
+       c1 = tolower(*s1);
+       c2 = tolower(*s2);
+       if (c1 != c2)
+           return (c1 - c2);
+       s1++;
+       s2++;
+    }
+    return (int) (*s1 - *s2);
+}
+
+#endif
+
+/*
+ * return the default color key related to the given visual
+ */
+static int
+xpmVisualType(Visual *visual)
+{
+#ifndef FOR_MSW
+# ifndef AMIGA
+    switch (visual->class) {
+    case StaticGray:
+    case GrayScale:
+       switch (visual->map_entries) {
+       case 2:
+           return (XPM_MONO);
+       case 4:
+           return (XPM_GRAY4);
+       default:
+           return (XPM_GRAY);
+       }
+    default:
+       return (XPM_COLOR);
+    }
+# else
+    /* set the key explicitly in the XpmAttributes to override this */
+    return (XPM_COLOR);
+# endif
+#else
+    /* there should be a similar switch for MSW */
+    return (XPM_COLOR);
+#endif
+}
+
+
+typedef struct {
+    int cols_index;
+    long closeness;
+}      CloseColor;
+
+static int
+closeness_cmp(Const void *a, Const void *b)
+{
+    CloseColor *x = (CloseColor *) a, *y = (CloseColor *) b;
+
+    /* cast to int as qsort requires */
+    return (int) (x->closeness - y->closeness);
+}
+
+
+/* default AllocColor function:
+ *   call XParseColor if colorname is given, return negative value if failure
+ *   call XAllocColor and return 0 if failure, positive otherwise
+ */
+static int
+AllocColor(
+    Display    *display,
+    Colormap    colormap,
+    char       *colorname,
+    XColor     *xcolor,
+    void       *closure)               /* not used */
+{
+    int status;
+    if (colorname)
+       if (!XParseColor(display, colormap, colorname, xcolor))
+           return -1;
+    status = XAllocColor(display, colormap, xcolor);
+    return status != 0 ? 1 : 0;
+}
+
+
+#ifndef FOR_MSW
+/*
+ * set a close color in case the exact one can't be set
+ * return 0 if success, 1 otherwise.
+ */
+
+static int
+SetCloseColor(
+    Display            *display,
+    Colormap            colormap,
+    Visual             *visual,
+    XColor             *col,
+    Pixel              *image_pixel,
+    Pixel              *mask_pixel,
+    Pixel              *alloc_pixels,
+    unsigned int       *nalloc_pixels,
+    XpmAttributes      *attributes,
+    XColor             *cols,
+    int                         ncols,
+    XpmAllocColorFunc   allocColor,
+    void               *closure)
+{
+
+    /*
+     * Allocation failed, so try close colors. To get here the visual must
+     * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor?
+     * What about sharing systems like QDSS?). Beware: we have to treat
+     * DirectColor differently.
+     */
+
+
+    long int red_closeness, green_closeness, blue_closeness;
+    int n;
+    Bool alloc_color;
+
+    if (attributes && (attributes->valuemask & XpmCloseness))
+       red_closeness = green_closeness = blue_closeness =
+           attributes->closeness;
+    else {
+       red_closeness = attributes->red_closeness;
+       green_closeness = attributes->green_closeness;
+       blue_closeness = attributes->blue_closeness;
+    }
+    if (attributes && (attributes->valuemask & XpmAllocCloseColors))
+       alloc_color = attributes->alloc_close_colors;
+    else
+       alloc_color = True;
+
+    /*
+     * We sort the colormap by closeness and try to allocate the color
+     * closest to the target. If the allocation of this close color fails,
+     * which almost never happens, then one of two scenarios is possible.
+     * Either the colormap must have changed (since the last close color
+     * allocation or possibly while we were sorting the colormap), or the
+     * color is allocated as Read/Write by some other client. (Note: X
+     * _should_ allow clients to check if a particular color is Read/Write,
+     * but it doesn't! :-( ). We cannot determine which of these scenarios
+     * occurred, so we try the next closest color, and so on, until no more
+     * colors are within closeness of the target. If we knew that the
+     * colormap had changed, we could skip this sequence.
+     * 
+     * If _none_ of the colors within closeness of the target can be allocated,
+     * then we can finally be pretty sure that the colormap has actually
+     * changed. In this case we try to allocate the original color (again),
+     * then try the closecolor stuff (again)...
+     * 
+     * In theory it would be possible for an infinite loop to occur if another
+     * process kept changing the colormap every time we sorted it, so we set
+     * a maximum on the number of iterations. After this many tries, we use
+     * XGrabServer() to ensure that the colormap remains unchanged.
+     * 
+     * This approach gives particularly bad worst case performance - as many as
+     * <MaximumIterations> colormap reads and sorts may be needed, and as
+     * many as <MaximumIterations> * <ColormapSize> attempted allocations
+     * may fail. On an 8-bit system, this means as many as 3 colormap reads,
+     * 3 sorts and 768 failed allocations per execution of this code!
+     * Luckily, my experiments show that in general use in a typical 8-bit
+     * color environment only about 1 in every 10000 allocations fails to
+     * succeed in the fastest possible time. So virtually every time what
+     * actually happens is a single sort followed by a successful allocate.
+     * The very first allocation also costs a colormap read, but no further
+     * reads are usually necessary.
+     */
+
+#define ITERATIONS 2                   /* more than one is almost never
+                                        * necessary */
+
+    for (n = 0; n <= ITERATIONS; ++n) {
+       CloseColor *closenesses =
+           (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor));
+       int i, c;
+
+       for (i = 0; i < ncols; ++i) {   /* build & sort closenesses table */
+#define COLOR_FACTOR       3
+#define BRIGHTNESS_FACTOR  1
+
+           closenesses[i].cols_index = i;
+           closenesses[i].closeness =
+               COLOR_FACTOR * (abs((long) col->red - (long) cols[i].red)
+                               + abs((long) col->green - (long) cols[i].green)
+                               + abs((long) col->blue - (long) cols[i].blue))
+               + BRIGHTNESS_FACTOR * abs(((long) col->red +
+                                          (long) col->green +
+                                          (long) col->blue)
+                                          - ((long) cols[i].red +
+                                             (long) cols[i].green +
+                                             (long) cols[i].blue));
+       }
+       qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp);
+
+       i = 0;
+       c = closenesses[i].cols_index;
+       while ((long) cols[c].red >= (long) col->red - red_closeness &&
+              (long) cols[c].red <= (long) col->red + red_closeness &&
+              (long) cols[c].green >= (long) col->green - green_closeness &&
+              (long) cols[c].green <= (long) col->green + green_closeness &&
+              (long) cols[c].blue >= (long) col->blue - blue_closeness &&
+              (long) cols[c].blue <= (long) col->blue + blue_closeness) {
+           if (alloc_color) {
+               if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){
+                   if (n == ITERATIONS)
+                       XUngrabServer(display);
+                   XpmFree(closenesses);
+                   *image_pixel = cols[c].pixel;
+                   *mask_pixel = 1;
+                   alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel;
+                   return (0);
+               } else {
+                   ++i;
+                   if (i == ncols)
+                       break;
+                   c = closenesses[i].cols_index;
+               }
+           } else {
+               if (n == ITERATIONS)
+                   XUngrabServer(display);
+               XpmFree(closenesses);
+               *image_pixel = cols[c].pixel;
+               *mask_pixel = 1;
+               return (0);
+           }
+       }
+
+       /* Couldn't allocate _any_ of the close colors! */
+
+       if (n == ITERATIONS)
+           XUngrabServer(display);
+       XpmFree(closenesses);
+
+       if (i == 0 || i == ncols)       /* no color close enough or cannot */
+           return (1);                 /* alloc any color (full of r/w's) */
+
+       if ((*allocColor)(display, colormap, NULL, col, closure)) {
+           *image_pixel = col->pixel;
+           *mask_pixel = 1;
+           alloc_pixels[(*nalloc_pixels)++] = col->pixel;
+           return (0);
+       } else {                        /* colormap has probably changed, so
+                                        * re-read... */
+           if (n == ITERATIONS - 1)
+               XGrabServer(display);
+
+#if 0
+           if (visual->class == DirectColor) {
+               /* TODO */
+           } else
+#endif
+               XQueryColors(display, colormap, cols, ncols);
+       }
+    }
+    return (1);
+}
+
+#define USE_CLOSECOLOR attributes && \
+(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \
+ || ((attributes->valuemask & XpmRGBCloseness) && \
+     (attributes->red_closeness != 0 \
+      || attributes->green_closeness != 0 \
+      || attributes->blue_closeness != 0)))
+
+#else
+    /* FOR_MSW part */
+    /* nothing to do here, the window system does it */
+#endif
+
+/*
+ * set the color pixel related to the given colorname,
+ * return 0 if success, 1 otherwise.
+ */
+
+static int
+SetColor(
+    Display            *display,
+    Colormap            colormap,
+    Visual             *visual,
+    char               *colorname,
+    unsigned int        color_index,
+    Pixel              *image_pixel,
+    Pixel              *mask_pixel,
+    unsigned int       *mask_pixel_index,
+    Pixel              *alloc_pixels,
+    unsigned int       *nalloc_pixels,
+    Pixel              *used_pixels,
+    unsigned int       *nused_pixels,
+    XpmAttributes      *attributes,
+    XColor             *cols,
+    int                         ncols,
+    XpmAllocColorFunc   allocColor,
+    void               *closure)
+{
+    XColor xcolor;
+    int status;
+
+    if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) {
+       status = (*allocColor)(display, colormap, colorname, &xcolor, closure);
+       if (status < 0)         /* parse color failed */
+           return (1);
+
+       if (status == 0) {
+#ifndef FOR_MSW
+           if (USE_CLOSECOLOR)
+               return (SetCloseColor(display, colormap, visual, &xcolor,
+                                     image_pixel, mask_pixel,
+                                     alloc_pixels, nalloc_pixels,
+                                     attributes, cols, ncols,
+                                     allocColor, closure));
+           else
+#endif /* ndef FOR_MSW */
+               return (1);
+       } else
+           alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
+       *image_pixel = xcolor.pixel;
+#ifndef FOR_MSW
+       *mask_pixel = 1;
+#else
+       *mask_pixel = RGB(0,0,0);
+#endif
+       used_pixels[(*nused_pixels)++] = xcolor.pixel;
+    } else {
+       *image_pixel = 0;
+#ifndef FOR_MSW
+       *mask_pixel = 0;
+#else
+       *mask_pixel = RGB(255,255,255);
+#endif
+       /* store the color table index */
+       *mask_pixel_index = color_index;
+    }
+    return (0);
+}
+
+
+static int
+CreateColors(
+    Display            *display,
+    XpmAttributes      *attributes,
+    XpmColor           *colors,
+    unsigned int        ncolors,
+    Pixel              *image_pixels,
+    Pixel              *mask_pixels,
+    unsigned int       *mask_pixel_index,
+    Pixel              *alloc_pixels,
+    unsigned int       *nalloc_pixels,
+    Pixel              *used_pixels,
+    unsigned int       *nused_pixels)
+{
+    /* variables stored in the XpmAttributes structure */
+    Visual *visual;
+    Colormap colormap;
+    XpmColorSymbol *colorsymbols = NULL;
+    unsigned int numsymbols;
+    XpmAllocColorFunc allocColor;
+    void *closure;
+
+    char *colorname;
+    unsigned int color, key;
+    Bool pixel_defined;
+    XpmColorSymbol *symbol = NULL;
+    char **defaults;
+    int ErrorStatus = XpmSuccess;
+    char *s;
+    int default_index;
+
+    XColor *cols = NULL;
+    unsigned int ncols = 0;
+
+    /*
+     * retrieve information from the XpmAttributes
+     */
+    if (attributes && attributes->valuemask & XpmColorSymbols) {
+       colorsymbols = attributes->colorsymbols;
+       numsymbols = attributes->numsymbols;
+    } else
+       numsymbols = 0;
+
+    if (attributes && attributes->valuemask & XpmVisual)
+       visual = attributes->visual;
+    else
+       visual = XDefaultVisual(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColormap))
+       colormap = attributes->colormap;
+    else
+       colormap = XDefaultColormap(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColorKey))
+       key = attributes->color_key;
+    else
+       key = xpmVisualType(visual);
+
+    if (attributes && (attributes->valuemask & XpmAllocColor))
+       allocColor = attributes->alloc_color;
+    else
+       allocColor = AllocColor;
+    if (attributes && (attributes->valuemask & XpmColorClosure))
+       closure = attributes->color_closure;
+    else
+       closure = NULL;
+
+#ifndef FOR_MSW
+    if (USE_CLOSECOLOR) {
+       /* originally from SetCloseColor */
+#if 0
+       if (visual->class == DirectColor) {
+
+           /*
+            * TODO: Implement close colors for DirectColor visuals. This is
+            * difficult situation. Chances are that we will never get here,
+            * because any machine that supports DirectColor will probably
+            * also support TrueColor (and probably PseudoColor). Also,
+            * DirectColor colormaps can be very large, so looking for close
+            * colors may be too slow.
+            */
+       } else {
+#endif
+           unsigned int i;
+
+#ifndef AMIGA
+           ncols = visual->map_entries;
+#else
+           ncols = colormap->Count;
+#endif
+           cols = (XColor *) XpmCalloc(ncols, sizeof(XColor));
+           for (i = 0; i < ncols; ++i)
+               cols[i].pixel = i;
+           XQueryColors(display, colormap, cols, ncols);
+#if 0
+       }
+#endif
+    }
+#endif /* ndef FOR_MSW */
+
+    switch (key) {
+    case XPM_MONO:
+       default_index = 2;
+       break;
+    case XPM_GRAY4:
+       default_index = 3;
+       break;
+    case XPM_GRAY:
+       default_index = 4;
+       break;
+    case XPM_COLOR:
+    default:
+       default_index = 5;
+       break;
+    }
+
+    for (color = 0; color < ncolors; color++, colors++,
+                                        image_pixels++, mask_pixels++) {
+       colorname = NULL;
+       pixel_defined = False;
+       defaults = (char **) colors;
+
+       /*
+        * look for a defined symbol
+        */
+       if (numsymbols) {
+
+           unsigned int n;
+
+           s = defaults[1];
+           for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) {
+               if (symbol->name && s && !strcmp(symbol->name, s))
+                   /* override name */
+                   break;
+               if (!symbol->name && symbol->value) {   /* override value */
+                   int def_index = default_index;
+
+                   while (defaults[def_index] == NULL) /* find defined
+                                                        * colorname */
+                       --def_index;
+                   if (def_index < 2) {/* nothing towards mono, so try
+                                        * towards color */
+                       def_index = default_index + 1;
+                       while (def_index <= 5 && defaults[def_index] == NULL)
+                           ++def_index;
+                   }
+                   if (def_index >= 2 && defaults[def_index] != NULL &&
+                       !xpmstrcasecmp(symbol->value, defaults[def_index]))
+                       break;
+               }
+           }
+           if (n != numsymbols) {
+               if (symbol->name && symbol->value)
+                   colorname = symbol->value;
+               else
+                   pixel_defined = True;
+           }
+       }
+       if (!pixel_defined) {           /* pixel not given as symbol value */
+
+           unsigned int k;
+
+           if (colorname) {            /* colorname given as symbol value */
+               if (!SetColor(display, colormap, visual, colorname, color,
+                             image_pixels, mask_pixels, mask_pixel_index,
+                             alloc_pixels, nalloc_pixels, used_pixels,
+                             nused_pixels, attributes, cols, ncols,
+                             allocColor, closure))
+                   pixel_defined = True;
+               else
+                   ErrorStatus = XpmColorError;
+           }
+           k = key;
+           while (!pixel_defined && k > 1) {
+               if (defaults[k]) {
+                   if (!SetColor(display, colormap, visual, defaults[k],
+                                 color, image_pixels, mask_pixels,
+                                 mask_pixel_index, alloc_pixels,
+                                 nalloc_pixels, used_pixels, nused_pixels,
+                                 attributes, cols, ncols,
+                                 allocColor, closure)) {
+                       pixel_defined = True;
+                       break;
+                   } else
+                       ErrorStatus = XpmColorError;
+               }
+               k--;
+           }
+           k = key + 1;
+           while (!pixel_defined && k < NKEYS + 1) {
+               if (defaults[k]) {
+                   if (!SetColor(display, colormap, visual, defaults[k],
+                                 color, image_pixels, mask_pixels,
+                                 mask_pixel_index, alloc_pixels,
+                                 nalloc_pixels, used_pixels, nused_pixels,
+                                 attributes, cols, ncols,
+                                 allocColor, closure)) {
+                       pixel_defined = True;
+                       break;
+                   } else
+                       ErrorStatus = XpmColorError;
+               }
+               k++;
+           }
+           if (!pixel_defined) {
+               if (cols)
+                   XpmFree(cols);
+               return (XpmColorFailed);
+           }
+       } else {
+           /* simply use the given pixel */
+           *image_pixels = symbol->pixel;
+           /* the following makes the mask to be built even if none
+              is given a particular pixel */
+           if (symbol->value
+               && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) {
+               *mask_pixels = 0;
+               *mask_pixel_index = color;
+           } else
+               *mask_pixels = 1;
+           used_pixels[(*nused_pixels)++] = *image_pixels;
+       }
+    }
+    if (cols)
+       XpmFree(cols);
+    return (ErrorStatus);
+}
+
+
+/* default FreeColors function, simply call XFreeColors */
+static int
+FreeColors(
+    Display    *display,
+    Colormap    colormap,
+    Pixel      *pixels,
+    int                 n,
+    void       *closure)               /* not used */
+{
+    return XFreeColors(display, colormap, pixels, n, 0);
+}
+
+
+/* function call in case of error */
+
+#undef RETURN
+#define RETURN(status) \
+do \
+{ \
+      ErrorStatus = status; \
+      goto error; \
+} while(0)
+
+int
+XpmCreateImageFromXpmImage(
+    Display             *display,
+    XpmImage            *image,
+    XImage             **image_return,
+    XImage             **shapeimage_return,
+    XpmAttributes       *attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    Visual *visual;
+    Colormap colormap;
+    unsigned int depth;
+    int bitmap_format;
+    XpmFreeColorsFunc freeColors;
+
+    /* variables to return */
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int mask_pixel_index = XpmUndefPixel;
+    int ErrorStatus;
+
+    /* calculation variables */
+    Pixel *image_pixels = NULL;
+    Pixel *mask_pixels = NULL;
+    Pixel *alloc_pixels = NULL;
+    Pixel *used_pixels = NULL;
+    unsigned int nalloc_pixels = 0;
+    unsigned int nused_pixels = 0;
+
+    /* initialize return values */
+    if (image_return)
+       *image_return = NULL;
+    if (shapeimage_return)
+       *shapeimage_return = NULL;
+
+    /* retrieve information from the XpmAttributes */
+    if (attributes && (attributes->valuemask & XpmVisual))
+       visual = attributes->visual;
+    else
+       visual = XDefaultVisual(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColormap))
+       colormap = attributes->colormap;
+    else
+       colormap = XDefaultColormap(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmDepth))
+       depth = attributes->depth;
+    else
+       depth = XDefaultDepth(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmBitmapFormat))
+       bitmap_format = attributes->bitmap_format;
+    else
+       bitmap_format = ZPixmap;
+
+    if (attributes && (attributes->valuemask & XpmFreeColors))
+       freeColors = attributes->free_colors;
+    else
+       freeColors = FreeColors;
+
+    ErrorStatus = XpmSuccess;
+
+    if (image->ncolors >= UINT_MAX / sizeof(Pixel)) 
+       return (XpmNoMemory);
+
+    /* malloc pixels index tables */
+    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!image_pixels)
+       return (XpmNoMemory);
+
+    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!mask_pixels)
+       RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!alloc_pixels)
+       RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors);
+    if (!used_pixels)
+       RETURN(XpmNoMemory);
+
+    /* get pixel colors, store them in index tables */
+    ErrorStatus = CreateColors(display, attributes, image->colorTable,
+                              image->ncolors, image_pixels, mask_pixels,
+                              &mask_pixel_index, alloc_pixels, &nalloc_pixels,
+                              used_pixels, &nused_pixels);
+
+    if (ErrorStatus != XpmSuccess
+       && (ErrorStatus < 0 || (attributes
+                               && (attributes->valuemask & XpmExactColors)
+                               && attributes->exactColors)))
+       RETURN(ErrorStatus);
+
+    /* create the ximage */
+    if (image_return) {
+       ErrorStatus = CreateXImage(display, visual, depth,
+                                  (depth == 1 ? bitmap_format : ZPixmap),
+                                  image->width, image->height, &ximage);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+
+       /*
+        * set the ximage data using optimized functions for ZPixmap
+        */
+
+       if (ximage->bits_per_pixel == 8)
+           PutImagePixels8(ximage, image->width, image->height,
+                           image->data, image_pixels);
+       else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
+                (ximage->byte_order == ximage->bitmap_bit_order))
+           PutImagePixels1(ximage, image->width, image->height,
+                           image->data, image_pixels);
+       else if (ximage->bits_per_pixel == 16)
+           PutImagePixels16(ximage, image->width, image->height,
+                            image->data, image_pixels);
+       else if (ximage->bits_per_pixel == 32)
+           PutImagePixels32(ximage, image->width, image->height,
+                            image->data, image_pixels);
+       else
+           PutImagePixels(ximage, image->width, image->height,
+                          image->data, image_pixels);
+# else /* AMIGA */
+       APutImagePixels(ximage, image->width, image->height,
+                       image->data, image_pixels);
+# endif
+#else  /* FOR_MSW */
+       MSWPutImagePixels(display, ximage, image->width, image->height,
+                         image->data, image_pixels);
+#endif
+    }
+    /* create the shape mask image */
+    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
+       ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
+                                  image->width, image->height, &shapeimage);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+       PutImagePixels1(shapeimage, image->width, image->height,
+                       image->data, mask_pixels);
+# else /* AMIGA */
+       APutImagePixels(shapeimage, image->width, image->height,
+                       image->data, mask_pixels);
+# endif
+#else  /* FOR_MSW */
+       MSWPutImagePixels(display, shapeimage, image->width, image->height,
+                         image->data, mask_pixels);
+#endif
+
+    }
+    XpmFree(image_pixels);
+    XpmFree(mask_pixels);
+
+    /* if requested return used pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnPixels ||
+/* 3.2 backward compatibility code */
+       attributes->valuemask & XpmReturnInfos)) {
+/* end 3.2 bc */
+       attributes->pixels = used_pixels;
+       attributes->npixels = nused_pixels;
+       attributes->mask_pixel = mask_pixel_index;
+    } else
+       XpmFree(used_pixels);
+
+    /* if requested return alloc'ed pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
+       attributes->alloc_pixels = alloc_pixels;
+       attributes->nalloc_pixels = nalloc_pixels;
+    } else
+       XpmFree(alloc_pixels);
+
+    /* return created images */
+    if (image_return)
+       *image_return = ximage;
+    if (shapeimage_return)
+       *shapeimage_return = shapeimage;
+
+    return (ErrorStatus);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (ximage)
+       XDestroyImage(ximage);
+    if (shapeimage)
+       XDestroyImage(shapeimage);
+    if (image_pixels)
+       XpmFree(image_pixels);
+    if (mask_pixels)
+       XpmFree(mask_pixels);
+    if (nalloc_pixels)
+       (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
+    if (alloc_pixels)
+       XpmFree(alloc_pixels);
+    if (used_pixels)
+       XpmFree(used_pixels);
+
+    return (ErrorStatus);
+}
+
+
+/*
+ * Create an XImage with its data
+ */
+static int
+CreateXImage(
+    Display     *display,
+    Visual      *visual,
+    unsigned int  depth,
+    int                  format,
+    unsigned int  width,
+    unsigned int  height,
+    XImage     **image_return)
+{
+    int bitmap_pad;
+
+    /* first get bitmap_pad */
+    if (depth > 16)
+       bitmap_pad = 32;
+    else if (depth > 8)
+       bitmap_pad = 16;
+    else
+       bitmap_pad = 8;
+
+    /* then create the XImage with data = NULL and bytes_per_line = 0 */
+    *image_return = XCreateImage(display, visual, depth, format, 0, 0,
+                                width, height, bitmap_pad, 0);
+    if (!*image_return)
+       return (XpmNoMemory);
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+    if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) {
+       XDestroyImage(*image_return);
+       return XpmNoMemory;
+    }
+    /* now that bytes_per_line must have been set properly alloc data */
+    if((*image_return)->bytes_per_line == 0 ||  height == 0)
+       return XpmNoMemory;
+    (*image_return)->data =
+       (char *) XpmMalloc((*image_return)->bytes_per_line * height);
+
+    if (!(*image_return)->data) {
+       XDestroyImage(*image_return);
+       *image_return = NULL;
+       return (XpmNoMemory);
+    }
+#else
+    /* under FOR_MSW and AMIGA XCreateImage has done it all */
+#endif
+    return (XpmSuccess);
+}
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+/*
+ * The functions below are written from X11R5 MIT's code (XImUtil.c)
+ *
+ * The idea is to have faster functions than the standard XPutPixel function
+ * to build the image data. Indeed we can speed up things by suppressing tests
+ * performed for each pixel. We do the same tests but at the image level.
+ * We also assume that we use only ZPixmap images with null offsets.
+ */
+
+LFUNC(_putbits, void, (register char *src, int dstoffset,
+                      register int numbits, register char *dst));
+
+LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb));
+
+static unsigned char Const _reverse_byte[0x100] = {
+    0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+    0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+    0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+    0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+    0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+    0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+    0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+    0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+    0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+    0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+    0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+    0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+    0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+    0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+    0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+    0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+    0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+    0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+    0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+    0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+    0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+    0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+    0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+    0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+    0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+    0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+    0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+    0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+    0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+    0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+    0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+    0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
+};
+
+static int
+_XReverse_Bytes(
+    register unsigned char     *bpt,
+    register unsigned int       nb)
+{
+    do {
+       *bpt = _reverse_byte[*bpt];
+       bpt++;
+    } while (--nb > 0); /* is nb user-controled? */
+    return 0;
+}
+
+
+void
+xpm_xynormalizeimagebits(
+    register unsigned char     *bp,
+    register XImage            *img)
+{
+    register unsigned char c;
+
+    if (img->byte_order != img->bitmap_bit_order) {
+       switch (img->bitmap_unit) {
+
+       case 16:
+           c = *bp;
+           *bp = *(bp + 1);
+           *(bp + 1) = c;
+           break;
+
+       case 32:
+           c = *(bp + 3);
+           *(bp + 3) = *bp;
+           *bp = c;
+           c = *(bp + 2);
+           *(bp + 2) = *(bp + 1);
+           *(bp + 1) = c;
+           break;
+       }
+    }
+    if (img->bitmap_bit_order == MSBFirst)
+       _XReverse_Bytes(bp, img->bitmap_unit >> 3);
+}
+
+void
+xpm_znormalizeimagebits(
+    register unsigned char     *bp,
+    register XImage            *img)
+{
+    register unsigned char c;
+
+    switch (img->bits_per_pixel) {
+
+    case 2:
+       _XReverse_Bytes(bp, 1);
+       break;
+
+    case 4:
+       *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF);
+       break;
+
+    case 16:
+       c = *bp;
+       *bp = *(bp + 1);
+       *(bp + 1) = c;
+       break;
+
+    case 24:
+       c = *(bp + 2);
+       *(bp + 2) = *bp;
+       *bp = c;
+       break;
+
+    case 32:
+       c = *(bp + 3);
+       *(bp + 3) = *bp;
+       *bp = c;
+       c = *(bp + 2);
+       *(bp + 2) = *(bp + 1);
+       *(bp + 1) = c;
+       break;
+    }
+}
+
+static unsigned char Const _lomask[0x09] = {
+0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
+static unsigned char Const _himask[0x09] = {
+0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
+
+static void
+_putbits(
+    register char      *src,           /* address of source bit string */
+    int                         dstoffset,     /* bit offset into destination;
+                                        * range is 0-31 */
+    register int        numbits,       /* number of bits to copy to
+                                        * destination */
+    register char      *dst)           /* address of destination bit string */
+{
+    register unsigned char chlo, chhi;
+    int hibits;
+
+    dst = dst + (dstoffset >> 3);
+    dstoffset = dstoffset & 7;
+    hibits = 8 - dstoffset;
+    chlo = *dst & _lomask[dstoffset];
+    for (;;) {
+       chhi = (*src << dstoffset) & _himask[dstoffset];
+       if (numbits <= hibits) {
+           chhi = chhi & _lomask[dstoffset + numbits];
+           *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi;
+           break;
+       }
+       *dst = chhi | chlo;
+       dst++;
+       numbits = numbits - hibits;
+       chlo = (unsigned char) (*src & _himask[hibits]) >> hibits;
+       src++;
+       if (numbits <= dstoffset) {
+           chlo = chlo & _lomask[numbits];
+           *dst = (*dst & _himask[numbits]) | chlo;
+           break;
+       }
+       numbits = numbits - dstoffset;
+    }
+}
+
+/*
+ * Default method to write pixels into a Z image data structure.
+ * The algorithm used is:
+ *
+ *     copy the destination bitmap_unit or Zpixel to temp
+ *     normalize temp if needed
+ *     copy the pixel bits into the temp
+ *     renormalize temp if needed
+ *     copy the temp back into the destination image data
+ */
+
+static void
+PutImagePixels(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int       *pixelindex,
+    Pixel              *pixels)
+{
+    register char *src;
+    register char *dst;
+    register unsigned int *iptr;
+    register unsigned int x, y;
+    register char *data;
+    Pixel pixel, px;
+    int nbytes, depth, ibu, ibpp, i;
+
+    data = image->data;
+    iptr = pixelindex;
+    depth = image->depth;
+    if (depth == 1) {
+       ibu = image->bitmap_unit;
+       for (y = 0; y < height; y++) /* how can we trust height */
+           for (x = 0; x < width; x++, iptr++) { /* how can we trust width */
+               pixel = pixels[*iptr];
+               for (i = 0, px = pixel; i < sizeof(unsigned long);
+                    i++, px >>= 8)
+                   ((unsigned char *) &pixel)[i] = px;
+               src = &data[XYINDEX(x, y, image)];
+               dst = (char *) &px;
+               px = 0;
+               nbytes = ibu >> 3;
+               for (i = nbytes; --i >= 0;)
+                   *dst++ = *src++;
+               XYNORMALIZE(&px, image);
+               _putbits((char *) &pixel, (x % ibu), 1, (char *) &px);
+               XYNORMALIZE(&px, image);
+               src = (char *) &px;
+               dst = &data[XYINDEX(x, y, image)];
+               for (i = nbytes; --i >= 0;)
+                   *dst++ = *src++;
+           }
+    } else {
+       ibpp = image->bits_per_pixel;
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               pixel = pixels[*iptr];
+               if (depth == 4)
+                   pixel &= 0xf;
+               for (i = 0, px = pixel; i < sizeof(unsigned long); i++,
+                    px >>= 8)
+                   ((unsigned char *) &pixel)[i] = px;
+               src = &data[ZINDEX(x, y, image)];
+               dst = (char *) &px;
+               px = 0;
+               nbytes = (ibpp + 7) >> 3;
+               for (i = nbytes; --i >= 0;)
+                   *dst++ = *src++;
+               ZNORMALIZE(&px, image);
+               _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
+               ZNORMALIZE(&px, image);
+               src = (char *) &px;
+               dst = &data[ZINDEX(x, y, image)];
+               for (i = nbytes; --i >= 0;)
+                   *dst++ = *src++;
+           }
+    }
+}
+
+/*
+ * write pixels into a 32-bits Z image data structure
+ */
+
+#if !defined(WORD64) && !defined(LONG64)
+/* this item is static but deterministic so let it slide; doesn't
+ * hurt re-entrancy of this library. Note if it is actually const then would
+ * be OK under rules of ANSI-C but probably not C++ which may not
+ * want to allocate space for it.
+ */
+static unsigned long byteorderpixel = MSBFirst << 24;
+
+#endif
+
+/*
+   WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original
+   3.2e code - by default you get the speeded-up version.
+*/
+
+static void
+PutImagePixels32(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int       *pixelindex,
+    Pixel              *pixels)
+{
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int y;
+    Pixel pixel;
+
+#ifdef WITHOUT_SPEEDUPS
+
+    unsigned int x;
+    unsigned char *addr;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+#if !defined(WORD64) && !defined(LONG64)
+    if (*((char *) &byteorderpixel) == image->byte_order) {
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX32(x, y, image)];
+               *((unsigned long *) addr) = pixels[*iptr];
+           }
+    } else
+#endif
+    if (image->byte_order == MSBFirst)
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX32(x, y, image)];
+               pixel = pixels[*iptr];
+               addr[0] = pixel >> 24;
+               addr[1] = pixel >> 16;
+               addr[2] = pixel >> 8;
+               addr[3] = pixel;
+           }
+    else
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX32(x, y, image)];
+               pixel = pixels[*iptr];
+               addr[0] = pixel;
+               addr[1] = pixel >> 8;
+               addr[2] = pixel >> 16;
+               addr[3] = pixel >> 24;
+           }
+
+#else  /* WITHOUT_SPEEDUPS */
+
+    unsigned int bpl = image->bytes_per_line;
+    unsigned char *data_ptr, *max_data;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+#if !defined(WORD64) && !defined(LONG64)
+    if (*((char *) &byteorderpixel) == image->byte_order) {
+       for (y = 0; y < height; y++) {
+           data_ptr = data;
+           max_data = data_ptr + (width << 2);
+
+           while (data_ptr < max_data) {
+               *((unsigned long *) data_ptr) = pixels[*(iptr++)];
+               data_ptr += (1 << 2);
+           }
+           data += bpl;
+       }
+    } else
+#endif
+    if (image->byte_order == MSBFirst)
+       for (y = 0; y < height; y++) {
+           data_ptr = data;
+           max_data = data_ptr + (width << 2);
+
+           while (data_ptr < max_data) {
+               pixel = pixels[*(iptr++)];
+
+               *data_ptr++ = pixel >> 24;
+               *data_ptr++ = pixel >> 16;
+               *data_ptr++ = pixel >> 8;
+               *data_ptr++ = pixel;
+
+           }
+           data += bpl;
+       }
+    else
+       for (y = 0; y < height; y++) {
+           data_ptr = data;
+           max_data = data_ptr + (width << 2);
+
+           while (data_ptr < max_data) {
+               pixel = pixels[*(iptr++)];
+
+               *data_ptr++ = pixel;
+               *data_ptr++ = pixel >> 8;
+               *data_ptr++ = pixel >> 16;
+               *data_ptr++ = pixel >> 24;
+           }
+           data += bpl;
+       }
+
+#endif /* WITHOUT_SPEEDUPS */
+}
+
+/*
+ * write pixels into a 16-bits Z image data structure
+ */
+
+static void
+PutImagePixels16(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int       *pixelindex,
+    Pixel              *pixels)
+{
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int y;
+
+#ifdef WITHOUT_SPEEDUPS
+
+    unsigned int x;
+    unsigned char *addr;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+    if (image->byte_order == MSBFirst)
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX16(x, y, image)];
+               addr[0] = pixels[*iptr] >> 8;
+               addr[1] = pixels[*iptr];
+           }
+    else
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX16(x, y, image)];
+               addr[0] = pixels[*iptr];
+               addr[1] = pixels[*iptr] >> 8;
+           }
+
+#else  /* WITHOUT_SPEEDUPS */
+
+    Pixel pixel;
+
+    unsigned int bpl = image->bytes_per_line;
+    unsigned char *data_ptr, *max_data;
+
+    data = (unsigned char *) image->data;
+    iptr = pixelindex;
+    if (image->byte_order == MSBFirst)
+       for (y = 0; y < height; y++) {
+           data_ptr = data;
+           max_data = data_ptr + (width << 1);
+
+           while (data_ptr < max_data) {
+               pixel = pixels[*(iptr++)];
+
+               data_ptr[0] = pixel >> 8;
+               data_ptr[1] = pixel;
+
+               data_ptr += (1 << 1);
+           }
+           data += bpl;
+       }
+    else
+       for (y = 0; y < height; y++) {
+           data_ptr = data;
+           max_data = data_ptr + (width << 1);
+
+           while (data_ptr < max_data) {
+               pixel = pixels[*(iptr++)];
+
+               data_ptr[0] = pixel;
+               data_ptr[1] = pixel >> 8;
+
+               data_ptr += (1 << 1);
+           }
+           data += bpl;
+       }
+
+#endif /* WITHOUT_SPEEDUPS */
+}
+
+/*
+ * write pixels into a 8-bits Z image data structure
+ */
+
+static void
+PutImagePixels8(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int       *pixelindex,
+    Pixel              *pixels)
+{
+    char *data;
+    unsigned int *iptr;
+    unsigned int y;
+
+#ifdef WITHOUT_SPEEDUPS
+
+    unsigned int x;
+
+    data = image->data;
+    iptr = pixelindex;
+    for (y = 0; y < height; y++)
+       for (x = 0; x < width; x++, iptr++)
+           data[ZINDEX8(x, y, image)] = pixels[*iptr];
+
+#else  /* WITHOUT_SPEEDUPS */
+
+    unsigned int bpl = image->bytes_per_line;
+    char *data_ptr, *max_data;
+
+    data = image->data;
+    iptr = pixelindex;
+
+    for (y = 0; y < height; y++) {
+       data_ptr = data;
+       max_data = data_ptr + width;
+
+       while (data_ptr < max_data)
+           *(data_ptr++) = pixels[*(iptr++)];
+
+       data += bpl;
+    }
+
+#endif /* WITHOUT_SPEEDUPS */
+}
+
+/*
+ * write pixels into a 1-bit depth image data structure and **offset null**
+ */
+
+static void
+PutImagePixels1(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int       *pixelindex,
+    Pixel              *pixels)
+{
+    if (image->byte_order != image->bitmap_bit_order)
+       PutImagePixels(image, width, height, pixelindex, pixels);
+    else {
+       unsigned int *iptr;
+       unsigned int y;
+       char *data;
+
+#ifdef WITHOUT_SPEEDUPS
+
+       unsigned int x;
+
+       data = image->data;
+       iptr = pixelindex;
+       if (image->bitmap_bit_order == MSBFirst)
+           for (y = 0; y < height; y++)
+               for (x = 0; x < width; x++, iptr++) {
+                   if (pixels[*iptr] & 1)
+                       data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7);
+                   else
+                       data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7));
+               }
+       else
+           for (y = 0; y < height; y++)
+               for (x = 0; x < width; x++, iptr++) {
+                   if (pixels[*iptr] & 1)
+                       data[ZINDEX1(x, y, image)] |= 1 << (x & 7);
+                   else
+                       data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7));
+               }
+
+#else  /* WITHOUT_SPEEDUPS */
+
+       char value;
+       char *data_ptr, *max_data;
+       int bpl = image->bytes_per_line;
+       int diff, count;
+
+       data = image->data;
+       iptr = pixelindex;
+
+       diff = width & 7;
+       width >>= 3;
+
+       if (image->bitmap_bit_order == MSBFirst)
+           for (y = 0; y < height; y++) {
+               data_ptr = data;
+               max_data = data_ptr + width;
+               while (data_ptr < max_data) {
+                   value = 0;
+
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+                   value = (value << 1) | (pixels[*(iptr++)] & 1);
+
+                   *(data_ptr++) = value;
+               }
+               if (diff) {
+                   value = 0;
+                   for (count = 0; count < diff; count++) {
+                       if (pixels[*(iptr++)] & 1)
+                           value |= (0x80 >> count);
+                   }
+                   *(data_ptr) = value;
+               }
+               data += bpl;
+           }
+       else
+           for (y = 0; y < height; y++) {
+               data_ptr = data;
+               max_data = data_ptr + width;
+               while (data_ptr < max_data) {
+                   value = 0;
+                   iptr += 8;
+
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+                   value = (value << 1) | (pixels[*(--iptr)] & 1);
+
+                   iptr += 8;
+                   *(data_ptr++) = value;
+               }
+               if (diff) {
+                   value = 0;
+                   for (count = 0; count < diff; count++) {
+                       if (pixels[*(iptr++)] & 1)
+                           value |= (1 << count);
+                   }
+                   *(data_ptr) = value;
+               }
+               data += bpl;
+           }
+
+#endif /* WITHOUT_SPEEDUPS */
+    }
+}
+
+int
+XpmCreatePixmapFromXpmImage(
+    Display            *display,
+    Drawable            d,
+    XpmImage           *image,
+    Pixmap             *pixmap_return,
+    Pixmap             *shapemask_return,
+    XpmAttributes      *attributes)
+{
+    XImage *ximage, *shapeimage;
+    int ErrorStatus;
+
+    /* initialize return values */
+    if (pixmap_return)
+       *pixmap_return = 0;
+    if (shapemask_return)
+       *shapemask_return = 0;
+
+    /* create the ximages */
+    ErrorStatus = XpmCreateImageFromXpmImage(display, image,
+                                            (pixmap_return ? &ximage : NULL),
+                                            (shapemask_return ?
+                                             &shapeimage : NULL),
+                                            attributes);
+    if (ErrorStatus < 0)
+       return (ErrorStatus);
+
+    /* create the pixmaps and destroy images */
+    if (pixmap_return && ximage) {
+       xpmCreatePixmapFromImage(display, d, ximage, pixmap_return);
+       XDestroyImage(ximage);
+    }
+    if (shapemask_return && shapeimage) {
+       xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return);
+       XDestroyImage(shapeimage);
+    }
+    return (ErrorStatus);
+}
+
+# else /* AMIGA */
+
+static void
+APutImagePixels (
+    XImage        *image,
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int  *pixelindex,
+    Pixel         *pixels)
+{
+    unsigned int   *data = pixelindex;
+    unsigned int    x, y;
+    unsigned char  *array;
+    XImage         *tmp_img;
+    BOOL            success = FALSE;
+    
+    array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array));
+    if (array != NULL)
+    {
+       tmp_img = AllocXImage ((((width+15)>>4)<<4), 1,
+                              image->rp->BitMap->Depth);
+       if (tmp_img != NULL)
+       {
+           for (y = 0; y < height; ++y)
+           {
+               for (x = 0; x < width; ++x)
+                   array[x] = pixels[*(data++)];
+               WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp);
+           }
+           FreeXImage (tmp_img);
+           success = TRUE;
+       }
+       XpmFree (array);
+    }
+    
+    if (!success)
+    {
+       for (y = 0; y < height; ++y)
+           for (x = 0; x < width; ++x)
+               XPutPixel (image, x, y, pixels[*(data++)]);
+    }
+}
+
+# endif/* AMIGA */
+#else  /* FOR_MSW part follows */
+static void
+MSWPutImagePixels(
+    Display            *dc,
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int       *pixelindex,
+    Pixel              *pixels)
+{
+    unsigned int *data = pixelindex;
+    unsigned int x, y;
+    HBITMAP obm;
+
+    obm = SelectObject(*dc, image->bitmap);
+    for (y = 0; y < height; y++) {
+       for (x = 0; x < width; x++) {
+           SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */
+       }
+    }
+    SelectObject(*dc, obm);
+}
+
+#endif /* FOR_MSW */
+
+
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+
+static int
+PutPixel1(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    register char *src;
+    register char *dst;
+    register int i;
+    Pixel px;
+    int nbytes;
+
+    if(x < 0 || y < 0)
+       return 0;
+
+    for (i=0, px=pixel; i<sizeof(unsigned long); i++, px>>=8)
+       ((unsigned char *)&pixel)[i] = px;
+    src = &ximage->data[XYINDEX(x, y, ximage)];
+    dst = (char *)&px;
+    px = 0;
+    nbytes = ximage->bitmap_unit >> 3;
+    for (i = nbytes; --i >= 0; ) *dst++ = *src++;
+    XYNORMALIZE(&px, ximage);
+    i = ((x + ximage->xoffset) % ximage->bitmap_unit);
+    _putbits ((char *)&pixel, i, 1, (char *)&px);
+    XYNORMALIZE(&px, ximage);
+    src = (char *) &px;
+    dst = &ximage->data[XYINDEX(x, y, ximage)];
+    for (i = nbytes; --i >= 0; )
+       *dst++ = *src++;
+
+    return 1;
+}
+
+static int
+PutPixel(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    register char *src;
+    register char *dst;
+    register int i;
+    Pixel px;
+    unsigned int nbytes, ibpp;
+
+    if(x < 0 || y < 0)
+       return 0;
+
+    ibpp = ximage->bits_per_pixel;
+    if (ximage->depth == 4)
+       pixel &= 0xf;
+    for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8)
+       ((unsigned char *) &pixel)[i] = px;
+    src = &ximage->data[ZINDEX(x, y, ximage)];
+    dst = (char *) &px;
+    px = 0;
+    nbytes = (ibpp + 7) >> 3;
+    for (i = nbytes; --i >= 0;)
+       *dst++ = *src++;
+    ZNORMALIZE(&px, ximage);
+    _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px);
+    ZNORMALIZE(&px, ximage);
+    src = (char *) &px;
+    dst = &ximage->data[ZINDEX(x, y, ximage)];
+    for (i = nbytes; --i >= 0;)
+       *dst++ = *src++;
+
+    return 1;
+}
+
+#if !defined(WORD64) && !defined(LONG64)
+static int
+PutPixel32(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    unsigned char *addr;
+
+    if(x < 0 || y < 0)
+       return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+    *((unsigned long *)addr) = pixel;
+    return 1;
+}
+#endif
+
+static int
+PutPixel32MSB(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    unsigned char *addr;
+
+    if(x < 0 || y < 0)
+       return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+    addr[0] = pixel >> 24;
+    addr[1] = pixel >> 16;
+    addr[2] = pixel >> 8;
+    addr[3] = pixel;
+    return 1;
+}
+
+static int
+PutPixel32LSB(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    unsigned char *addr;
+
+    if(x < 0 || y < 0)
+       return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+    addr[3] = pixel >> 24;
+    addr[2] = pixel >> 16;
+    addr[1] = pixel >> 8;
+    addr[0] = pixel;
+    return 1;
+}
+
+static int
+PutPixel16MSB(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    unsigned char *addr;
+    
+    if(x < 0 || y < 0)
+       return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
+    addr[0] = pixel >> 8;
+    addr[1] = pixel;
+    return 1;
+}
+
+static int
+PutPixel16LSB(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    unsigned char *addr;
+    
+    if(x < 0 || y < 0)
+       return 0;
+
+    addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
+    addr[1] = pixel >> 8;
+    addr[0] = pixel;
+    return 1;
+}
+
+static int
+PutPixel8(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    if(x < 0 || y < 0)
+       return 0;
+
+    ximage->data[ZINDEX8(x, y, ximage)] = pixel;
+    return 1;
+}
+
+static int
+PutPixel1MSB(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    if(x < 0 || y < 0)
+       return 0;
+
+    if (pixel & 1)
+       ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7);
+    else
+       ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7));
+    return 1;
+}
+
+static int
+PutPixel1LSB(
+    register XImage    *ximage,
+    int                         x,
+    int                         y,
+    unsigned long       pixel)
+{
+    if(x < 0 || y < 0)
+       return 0;
+
+    if (pixel & 1)
+       ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7);
+    else
+       ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7));
+    return 1;
+}
+
+#endif /* not FOR_MSW && not AMIGA */
+
+/*
+ * This function parses an Xpm file or data and directly create an XImage
+ */
+int
+xpmParseDataAndCreate(
+    Display             *display,
+    xpmData             *data,
+    XImage             **image_return,
+    XImage             **shapeimage_return,
+    XpmImage            *image,
+    XpmInfo             *info,
+    XpmAttributes       *attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    Visual *visual;
+    Colormap colormap;
+    unsigned int depth;
+    int bitmap_format;
+    XpmFreeColorsFunc freeColors;
+
+    /* variables to return */
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int mask_pixel_index = XpmUndefPixel;
+
+    /* calculation variables */
+    Pixel *image_pixels = NULL;
+    Pixel *mask_pixels = NULL;
+    Pixel *alloc_pixels = NULL;
+    Pixel *used_pixels = NULL;
+    unsigned int nalloc_pixels = 0;
+    unsigned int nused_pixels = 0;
+    unsigned int width, height, ncolors, cpp;
+    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
+    XpmColor *colorTable = NULL;
+    char *hints_cmt = NULL;
+    char *colors_cmt = NULL;
+    char *pixels_cmt = NULL;
+
+    unsigned int cmts;
+    int ErrorStatus;
+    xpmHashTable hashtable;
+
+
+    /* initialize return values */
+    if (image_return)
+       *image_return = NULL;
+    if (shapeimage_return)
+       *shapeimage_return = NULL;
+
+
+    /* retrieve information from the XpmAttributes */
+    if (attributes && (attributes->valuemask & XpmVisual))
+       visual = attributes->visual;
+    else
+       visual = XDefaultVisual(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmColormap))
+       colormap = attributes->colormap;
+    else
+       colormap = XDefaultColormap(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmDepth))
+       depth = attributes->depth;
+    else
+       depth = XDefaultDepth(display, XDefaultScreen(display));
+
+    if (attributes && (attributes->valuemask & XpmBitmapFormat))
+       bitmap_format = attributes->bitmap_format;
+    else
+       bitmap_format = ZPixmap;
+
+    if (attributes && (attributes->valuemask & XpmFreeColors))
+       freeColors = attributes->free_colors;
+    else
+       freeColors = FreeColors;
+
+    cmts = info && (info->valuemask & XpmReturnComments);
+
+    /*
+     * parse the header
+     */
+    ErrorStatus = xpmParseHeader(data);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /*
+     * read values
+     */
+    ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
+                                &x_hotspot, &y_hotspot, &hotspot,
+                                &extensions);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /*
+     * store the hints comment line
+     */
+    if (cmts)
+       xpmGetCmt(data, &hints_cmt);
+
+    /*
+     * init the hashtable
+     */
+    if (USE_HASHTABLE) {
+       ErrorStatus = xpmHashTableInit(&hashtable);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+    }
+
+    /*
+     * read colors
+     */
+    ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
+    if (ErrorStatus != XpmSuccess)
+       RETURN(ErrorStatus);
+
+    /*
+     * store the colors comment line
+     */
+    if (cmts)
+       xpmGetCmt(data, &colors_cmt);
+
+    /* malloc pixels index tables */
+    if (ncolors >= UINT_MAX / sizeof(Pixel)) 
+       RETURN(XpmNoMemory);
+
+    image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!image_pixels)
+       RETURN(XpmNoMemory);
+
+    mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!mask_pixels)
+       RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!alloc_pixels)
+       RETURN(XpmNoMemory);
+
+    /* maximum of allocated pixels will be the number of colors */
+    used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors);
+    if (!used_pixels)
+       RETURN(XpmNoMemory);
+
+    /* get pixel colors, store them in index tables */
+    ErrorStatus = CreateColors(display, attributes, colorTable, ncolors,
+                              image_pixels, mask_pixels, &mask_pixel_index,
+                              alloc_pixels, &nalloc_pixels, used_pixels,
+                              &nused_pixels);
+
+    if (ErrorStatus != XpmSuccess
+       && (ErrorStatus < 0 || (attributes
+                               && (attributes->valuemask & XpmExactColors)
+                               && attributes->exactColors)))
+       RETURN(ErrorStatus);
+
+    /* now create the ximage */
+    if (image_return) {
+       ErrorStatus = CreateXImage(display, visual, depth,
+                                  (depth == 1 ? bitmap_format : ZPixmap),
+                                  width, height, &ximage);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+
+       /*
+        * set the XImage pointer function, to be used with XPutPixel,
+        * to an internal optimized function
+        */
+
+       if (ximage->bits_per_pixel == 8)
+           ximage->f.put_pixel = PutPixel8;
+       else if (((ximage->bits_per_pixel | ximage->depth) == 1) &&
+                (ximage->byte_order == ximage->bitmap_bit_order))
+           if (ximage->bitmap_bit_order == MSBFirst)
+               ximage->f.put_pixel = PutPixel1MSB;
+           else
+               ximage->f.put_pixel = PutPixel1LSB;
+       else if (ximage->bits_per_pixel == 16)
+           if (ximage->bitmap_bit_order == MSBFirst)
+               ximage->f.put_pixel = PutPixel16MSB;
+           else
+               ximage->f.put_pixel = PutPixel16LSB;
+       else if (ximage->bits_per_pixel == 32)
+#if !defined(WORD64) && !defined(LONG64)
+           if (*((char *)&byteorderpixel) == ximage->byte_order)
+               ximage->f.put_pixel = PutPixel32;
+           else
+#endif
+               if (ximage->bitmap_bit_order == MSBFirst)
+                   ximage->f.put_pixel = PutPixel32MSB;
+               else
+                   ximage->f.put_pixel = PutPixel32LSB;
+       else if ((ximage->bits_per_pixel | ximage->depth) == 1)
+           ximage->f.put_pixel = PutPixel1;
+       else
+           ximage->f.put_pixel = PutPixel;
+#endif /* not FOR_MSW && not AMIGA */
+    }
+
+    /* create the shape mask image */
+    if (mask_pixel_index != XpmUndefPixel && shapeimage_return) {
+       ErrorStatus = CreateXImage(display, visual, 1, bitmap_format,
+                                  width, height, &shapeimage);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+
+#if !defined(FOR_MSW) && !defined(AMIGA)
+       if (shapeimage->bitmap_bit_order == MSBFirst)
+           shapeimage->f.put_pixel = PutPixel1MSB;
+       else
+           shapeimage->f.put_pixel = PutPixel1LSB;
+#endif
+    }
+
+    /*
+     * read pixels and put them in the XImage
+     */
+    ErrorStatus = ParseAndPutPixels(
+#ifdef FOR_MSW
+                                   display,
+#endif
+                                   data, width, height, ncolors, cpp,
+                                   colorTable, &hashtable,
+                                   ximage, image_pixels,
+                                   shapeimage, mask_pixels);
+    XpmFree(image_pixels);
+    image_pixels = NULL;
+    XpmFree(mask_pixels);
+    mask_pixels = NULL;
+
+    /*
+     * free the hastable
+     */
+    if (ErrorStatus != XpmSuccess)
+       RETURN(ErrorStatus);
+    else if (USE_HASHTABLE)
+       xpmHashTableFree(&hashtable);
+
+    /*
+     * store the pixels comment line
+     */
+    if (cmts)
+       xpmGetCmt(data, &pixels_cmt);
+
+    /*
+     * parse extensions
+     */
+    if (info && (info->valuemask & XpmReturnExtensions)) {
+       if (extensions) {
+           ErrorStatus = xpmParseExtensions(data, &info->extensions,
+                                            &info->nextensions);
+           if (ErrorStatus != XpmSuccess)
+               RETURN(ErrorStatus);
+       } else {
+           info->extensions = NULL;
+           info->nextensions = 0;
+       }
+    }
+    /*
+     * store found informations in the XpmImage structure
+     */
+    image->width = width;
+    image->height = height;
+    image->cpp = cpp;
+    image->ncolors = ncolors;
+    image->colorTable = colorTable;
+    image->data = NULL;
+
+    if (info) {
+       if (cmts) {
+           info->hints_cmt = hints_cmt;
+           info->colors_cmt = colors_cmt;
+           info->pixels_cmt = pixels_cmt;
+       }
+       if (hotspot) {
+           info->x_hotspot = x_hotspot;
+           info->y_hotspot = y_hotspot;
+           info->valuemask |= XpmHotspot;
+       }
+    }
+    /* if requested return used pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnPixels ||
+/* 3.2 backward compatibility code */
+       attributes->valuemask & XpmReturnInfos)) {
+/* end 3.2 bc */
+       attributes->pixels = used_pixels;
+       attributes->npixels = nused_pixels;
+       attributes->mask_pixel = mask_pixel_index;
+    } else
+       XpmFree(used_pixels);
+
+    /* if requested return alloc'ed pixels in the XpmAttributes structure */
+    if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) {
+       attributes->alloc_pixels = alloc_pixels;
+       attributes->nalloc_pixels = nalloc_pixels;
+    } else
+       XpmFree(alloc_pixels);
+
+    /* return created images */
+    if (image_return)
+       *image_return = ximage;
+    if (shapeimage_return)
+       *shapeimage_return = shapeimage;
+
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (USE_HASHTABLE)
+       xpmHashTableFree(&hashtable);
+    if (colorTable)
+       xpmFreeColorTable(colorTable, ncolors);
+    if (hints_cmt)
+       XpmFree(hints_cmt);
+    if (colors_cmt)
+       XpmFree(colors_cmt);
+    if (pixels_cmt)
+       XpmFree(pixels_cmt);
+    if (ximage)
+       XDestroyImage(ximage);
+    if (shapeimage)
+       XDestroyImage(shapeimage);
+    if (image_pixels)
+       XpmFree(image_pixels);
+    if (mask_pixels)
+       XpmFree(mask_pixels);
+    if (nalloc_pixels)
+       (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL);
+    if (alloc_pixels)
+       XpmFree(alloc_pixels);
+    if (used_pixels)
+       XpmFree(used_pixels);
+
+    return (ErrorStatus);
+}
+
+static int
+ParseAndPutPixels(
+#ifdef FOR_MSW
+    Display            *dc,
+#endif
+    xpmData            *data,
+    unsigned int        width,
+    unsigned int        height,
+    unsigned int        ncolors,
+    unsigned int        cpp,
+    XpmColor           *colorTable,
+    xpmHashTable       *hashtable,
+    XImage             *image,
+    Pixel              *image_pixels,
+    XImage             *shapeimage,
+    Pixel              *shape_pixels)
+{
+    unsigned int a, x, y;
+
+    switch (cpp) {
+
+    case (1):                          /* Optimize for single character
+                                        * colors */
+       {
+           unsigned short colidx[256];
+#ifdef FOR_MSW
+           HDC shapedc;
+           HBITMAP obm, sobm;
+
+           if ( shapeimage ) {
+               shapedc = CreateCompatibleDC(*dc);
+               sobm = SelectObject(shapedc, shapeimage->bitmap);
+           } else {
+               shapedc = NULL;
+           }
+           obm = SelectObject(*dc, image->bitmap);
+#endif
+           if (ncolors > 256)
+               return (XpmFileInvalid);
+
+           bzero((char *)colidx, 256 * sizeof(short));
+           for (a = 0; a < ncolors; a++)
+               colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
+
+           for (y = 0; y < height; y++) {
+               xpmNextString(data);
+               for (x = 0; x < width; x++) {
+                   int c = xpmGetC(data);
+
+                   if (c > 0 && c < 256 && colidx[c] != 0) {
+#ifndef FOR_MSW
+                       XPutPixel(image, x, y, image_pixels[colidx[c] - 1]);
+                       if (shapeimage)
+                           XPutPixel(shapeimage, x, y,
+                                     shape_pixels[colidx[c] - 1]);
+#else
+                       SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
+                       if (shapedc) {
+                           SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
+                       }
+#endif
+                   } else
+                       return (XpmFileInvalid);
+               }
+           }
+#ifdef FOR_MSW
+           if ( shapedc ) {
+               SelectObject(shapedc, sobm);
+               DeleteDC(shapedc);
+           }
+           SelectObject(*dc, obm);
+#endif
+       }
+       break;
+
+    case (2):                          /* Optimize for double character
+                                        * colors */
+       {
+
+/* free all allocated pointers at all exits */
+#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \
+if (cidx[f]) XpmFree(cidx[f]);}
+
+           /* array of pointers malloced by need */
+           unsigned short *cidx[256];
+           unsigned int char1;
+
+           bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
+           for (a = 0; a < ncolors; a++) {
+               char1 = (unsigned char) colorTable[a].string[0];
+               if (cidx[char1] == NULL) { /* get new memory */
+                   cidx[char1] = (unsigned short *)
+                       XpmCalloc(256, sizeof(unsigned short));
+                   if (cidx[char1] == NULL) { /* new block failed */
+                       FREE_CIDX;
+                       return (XpmNoMemory);
+                   }
+               }
+               cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
+           }
+
+           for (y = 0; y < height; y++) {
+               xpmNextString(data);
+               for (x = 0; x < width; x++) {
+                   int cc1 = xpmGetC(data);
+                   if (cc1 > 0 && cc1 < 256) {
+                       int cc2 = xpmGetC(data);
+                       if (cc2 > 0 && cc2 < 256 &&
+                           cidx[cc1] && cidx[cc1][cc2] != 0) {
+#ifndef FOR_MSW
+                           XPutPixel(image, x, y,
+                                     image_pixels[cidx[cc1][cc2] - 1]);
+                           if (shapeimage)
+                               XPutPixel(shapeimage, x, y,
+                                         shape_pixels[cidx[cc1][cc2] - 1]);
+#else
+                       SelectObject(*dc, image->bitmap);
+                       SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]);
+                       if (shapeimage) {
+                           SelectObject(*dc, shapeimage->bitmap);
+                           SetPixel(*dc, x, y,
+                                    shape_pixels[cidx[cc1][cc2] - 1]);
+                       }
+#endif
+                       } else {
+                           FREE_CIDX;
+                           return (XpmFileInvalid);
+                       }
+                   } else {
+                       FREE_CIDX;
+                       return (XpmFileInvalid);
+                   }
+               }
+           }
+           FREE_CIDX;
+       }
+       break;
+
+    default:                           /* Non-optimized case of long color
+                                        * names */
+       {
+           char *s;
+           char buf[BUFSIZ];
+
+           if (cpp >= sizeof(buf))
+               return (XpmFileInvalid);
+
+           buf[cpp] = '\0';
+           if (USE_HASHTABLE) {
+               xpmHashAtom *slot;
+
+               for (y = 0; y < height; y++) {
+                   xpmNextString(data);
+                   for (x = 0; x < width; x++) {
+                       for (a = 0, s = buf; a < cpp; a++, s++)
+                           *s = xpmGetC(data);
+                       slot = xpmHashSlot(hashtable, buf);
+                       if (!*slot)     /* no color matches */
+                           return (XpmFileInvalid);
+#ifndef FOR_MSW
+                       XPutPixel(image, x, y,
+                                 image_pixels[HashColorIndex(slot)]);
+                       if (shapeimage)
+                           XPutPixel(shapeimage, x, y,
+                                     shape_pixels[HashColorIndex(slot)]);
+#else
+                       SelectObject(*dc, image->bitmap);
+                       SetPixel(*dc, x, y,
+                                image_pixels[HashColorIndex(slot)]);
+                       if (shapeimage) {
+                           SelectObject(*dc, shapeimage->bitmap);
+                           SetPixel(*dc, x, y,
+                                    shape_pixels[HashColorIndex(slot)]);
+                       }
+#endif
+                   }
+               }
+           } else {
+               for (y = 0; y < height; y++) {
+                   xpmNextString(data);
+                   for (x = 0; x < width; x++) {
+                       for (a = 0, s = buf; a < cpp; a++, s++)
+                           *s = xpmGetC(data);
+                       for (a = 0; a < ncolors; a++)
+                           if (!strcmp(colorTable[a].string, buf))
+                               break;
+                       if (a == ncolors)       /* no color matches */
+                           return (XpmFileInvalid);
+#ifndef FOR_MSW
+                       XPutPixel(image, x, y, image_pixels[a]);
+                       if (shapeimage)
+                           XPutPixel(shapeimage, x, y, shape_pixels[a]);
+#else
+                       SelectObject(*dc, image->bitmap);
+                       SetPixel(*dc, x, y, image_pixels[a]);
+                       if (shapeimage) {
+                           SelectObject(*dc, shapeimage->bitmap);
+                           SetPixel(*dc, x, y, shape_pixels[a]);
+                       }
+#endif
+                   }
+               }
+           }
+       }
+       break;
+    }
+    return (XpmSuccess);
+}
diff --git a/src/data.c b/src/data.c
new file mode 100755 (executable)
index 0000000..347aa46
--- /dev/null
@@ -0,0 +1,479 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* data.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  IO utilities                                                               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifndef CXPMPROG
+#if 0
+/* Official version number */
+static char *RCS_Version = "$XpmVersion: 3.4k $";
+
+/* Internal version number */
+static char *RCS_Id = "Id: xpm.shar,v 3.71 1998/03/19 19:47:14 lehors Exp $";
+#endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#endif
+#include <ctype.h>
+
+#ifndef CXPMPROG
+#define Getc(data, file) getc(file)
+#define Ungetc(data, c, file) ungetc(c, file)
+#endif
+
+static int
+ParseComment(xpmData *data)
+{
+    if (data->type == XPMBUFFER) {
+       register char c;
+       register unsigned int n = 0;
+       unsigned int notend;
+       char *s, *s2;
+
+       s = data->Comment;
+       *s = data->Bcmt[0];
+
+       /* skip the string beginning comment */
+       s2 = data->Bcmt;
+       do {
+           c = *data->cptr++;
+           *++s = c;
+           n++;
+           s2++;
+       } while (c == *s2 && *s2 != '\0' && c);
+
+       if (*s2 != '\0') {
+           /* this wasn't the beginning of a comment */
+           data->cptr -= n;
+           return 0;
+       }
+       /* store comment */
+       data->Comment[0] = *s;
+       s = data->Comment;
+       notend = 1;
+       n = 0;
+       while (notend) {
+           s2 = data->Ecmt;
+           while (*s != *s2 && c) {
+               c = *data->cptr++;
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
+               *++s = c;
+               n++;
+           }
+           data->CommentLength = n;
+           do {
+               c = *data->cptr++;
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
+               *++s = c;
+               n++;
+               s2++;
+           } while (c == *s2 && *s2 != '\0' && c);
+           if (*s2 == '\0') {
+               /* this is the end of the comment */
+               notend = 0;
+               data->cptr--;
+           }
+       }
+       return 0;
+    } else {
+       FILE *file = data->stream.file;
+       register int c;
+       register unsigned int n = 0, a;
+       unsigned int notend;
+       char *s, *s2;
+
+       s = data->Comment;
+       *s = data->Bcmt[0];
+
+       /* skip the string beginning comment */
+       s2 = data->Bcmt;
+       do {
+           c = Getc(data, file);
+           *++s = c;
+           n++;
+           s2++;
+       } while (c == *s2 && *s2 != '\0' && c != EOF);
+
+       if (*s2 != '\0') {
+           /* this wasn't the beginning of a comment */
+           /* put characters back in the order that we got them */
+           for (a = n; a > 0; a--, s--)
+               Ungetc(data, *s, file);
+           return 0;
+       }
+       /* store comment */
+       data->Comment[0] = *s;
+       s = data->Comment;
+       notend = 1;
+       n = 0;
+       while (notend) {
+           s2 = data->Ecmt;
+           while (*s != *s2 && c != EOF) {
+               c = Getc(data, file);
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
+               *++s = c;
+               n++;
+           }
+           data->CommentLength = n;
+           do {
+               c = Getc(data, file);
+               if (n == XPMMAXCMTLEN - 1)  { /* forget it */
+                   s = data->Comment;
+                   n = 0;
+               }
+               *++s = c;
+               n++;
+               s2++;
+           } while (c == *s2 && *s2 != '\0' && c != EOF);
+           if (*s2 == '\0') {
+               /* this is the end of the comment */
+               notend = 0;
+               Ungetc(data, *s, file);
+           }
+       }
+       return 0;
+    }
+}
+
+/*
+ * skip to the end of the current string and the beginning of the next one
+ */
+int
+xpmNextString(xpmData *data)
+{
+    if (!data->type)
+       data->cptr = (data->stream.data)[++data->line];
+    else if (data->type == XPMBUFFER) {
+       register char c;
+
+       /* get to the end of the current string */
+       if (data->Eos)
+           while ((c = *data->cptr++) && c != data->Eos);
+
+       /*
+        * then get to the beginning of the next string looking for possible
+        * comment
+        */
+       if (data->Bos) {
+           while ((c = *data->cptr++) && c != data->Bos)
+               if (data->Bcmt && c == data->Bcmt[0])
+                   ParseComment(data);
+       } else if (data->Bcmt) {        /* XPM2 natural */
+           while ((c = *data->cptr++) == data->Bcmt[0])
+               ParseComment(data);
+           data->cptr--;
+       }
+    } else {
+       register int c;
+       FILE *file = data->stream.file;
+
+       /* get to the end of the current string */
+       if (data->Eos)
+           while ((c = Getc(data, file)) != data->Eos && c != EOF);
+
+       /*
+        * then get to the beginning of the next string looking for possible
+        * comment
+        */
+       if (data->Bos) {
+           while ((c = Getc(data, file)) != data->Bos && c != EOF)
+               if (data->Bcmt && c == data->Bcmt[0])
+                   ParseComment(data);
+
+       } else if (data->Bcmt) {        /* XPM2 natural */
+           while ((c = Getc(data, file)) == data->Bcmt[0])
+               ParseComment(data);
+           Ungetc(data, c, file);
+       }
+    }
+    return 0;
+}
+
+
+/*
+ * skip whitespace and return the following word
+ */
+unsigned int
+xpmNextWord(
+    xpmData            *data,
+    char               *buf,
+    unsigned int        buflen)
+{
+    register unsigned int n = 0;
+    int c;
+
+    if (!data->type || data->type == XPMBUFFER) {
+       while (isspace(c = *data->cptr) && c != data->Eos)
+           data->cptr++;
+       do {
+           c = *data->cptr++;
+           *buf++ = c;
+           n++;
+       } while (!isspace(c) && c != data->Eos && n < buflen);
+       n--;
+       data->cptr--;
+    } else {
+       FILE *file = data->stream.file;
+
+       while ((c = Getc(data, file)) != EOF && isspace(c) && c != data->Eos);
+       while (!isspace(c) && c != data->Eos && c != EOF && n < buflen) {
+           *buf++ = c;
+           n++;
+           c = Getc(data, file);
+       }
+       Ungetc(data, c, file);
+    }
+    return (n); /* this returns bytes read + 1 */
+}
+
+/*
+ * skip whitespace and compute the following unsigned int,
+ * returns 1 if one is found and 0 if not
+ */
+int
+xpmNextUI(
+    xpmData            *data,
+    unsigned int       *ui_return)
+{
+    char buf[BUFSIZ];
+    int l;
+
+    l = xpmNextWord(data, buf, BUFSIZ);
+    return xpmatoui(buf, l, ui_return);
+}
+
+/*
+ * return end of string - WARNING: malloc!
+ */
+int
+xpmGetString(
+    xpmData             *data,
+    char               **sptr,
+    unsigned int        *l)
+{
+    unsigned int i, n = 0;
+    int c;
+    char *p = NULL, *q, buf[BUFSIZ];
+
+    if (!data->type || data->type == XPMBUFFER) {
+       if (data->cptr) {
+           char *start = data->cptr;
+           while ((c = *data->cptr) && c != data->Eos)
+               data->cptr++;
+           n = data->cptr - start + 1;
+           p = (char *) XpmMalloc(n);
+           if (!p)
+               return (XpmNoMemory);
+           strncpy(p, start, n);
+           if (data->type)             /* XPMBUFFER */
+               p[n - 1] = '\0';
+       }
+    } else {
+       FILE *file = data->stream.file;
+
+       if ((c = Getc(data, file)) == EOF)
+           return (XpmFileInvalid);
+
+       i = 0;
+       q = buf;
+       p = (char *) XpmMalloc(1);
+       while (c != data->Eos && c != EOF) {
+           if (i == BUFSIZ) {
+               /* get to the end of the buffer */
+               /* malloc needed memory */
+               q = (char *) XpmRealloc(p, n + i);
+               if (!q) {
+                   XpmFree(p);
+                   return (XpmNoMemory);
+               }
+               p = q;
+               q += n;
+               /* and copy what we already have */
+               strncpy(q, buf, i);
+               n += i;
+               i = 0;
+               q = buf;
+           }
+           *q++ = c;
+           i++;
+           c = Getc(data, file);
+       }
+       if (c == EOF) {
+           XpmFree(p);
+           return (XpmFileInvalid);
+       }
+       if (n + i != 0) {
+           /* malloc needed memory */
+           q = (char *) XpmRealloc(p, n + i + 1);
+           if (!q) {
+               XpmFree(p);
+               return (XpmNoMemory);
+           }
+           p = q;
+           q += n;
+           /* and copy the buffer */
+           strncpy(q, buf, i);
+           n += i;
+           p[n++] = '\0';
+       } else {
+           *p = '\0';
+           n = 1;
+       }
+       Ungetc(data, c, file);
+    }
+    *sptr = p;
+    *l = n;
+    return (XpmSuccess);
+}
+
+/*
+ * get the current comment line
+ */
+int
+xpmGetCmt(
+    xpmData     *data,
+    char       **cmt)
+{
+    if (!data->type)
+       *cmt = NULL;
+    else if (data->CommentLength != 0 && data->CommentLength < UINT_MAX - 1) {
+       if( (*cmt = (char *) XpmMalloc(data->CommentLength + 1)) == NULL)
+               return XpmNoMemory;
+       strncpy(*cmt, data->Comment, data->CommentLength);
+       (*cmt)[data->CommentLength] = '\0';
+       data->CommentLength = 0;
+    } else
+       *cmt = NULL;
+    return 0;
+}
+
+xpmDataType xpmDataTypes[] =
+{
+    {"", "!", "\n", '\0', '\n', "", "", "", ""},       /* Natural type */
+    {"C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n"},
+    {"Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n"},
+    {NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL}
+};
+
+/*
+ * parse xpm header
+ */
+int
+xpmParseHeader(xpmData *data)
+{
+    char buf[BUFSIZ+1] = {0};
+    int l, n = 0;
+
+    if (data->type) {
+       data->Bos = '\0';
+       data->Eos = '\n';
+       data->Bcmt = data->Ecmt = NULL;
+       l = xpmNextWord(data, buf, BUFSIZ);
+       if (l == 7 && !strncmp("#define", buf, 7)) {
+           /* this maybe an XPM 1 file */
+           char *ptr;
+
+           l = xpmNextWord(data, buf, BUFSIZ);
+           if (!l)
+               return (XpmFileInvalid);
+           buf[l] = '\0';
+           ptr = strrchr(buf, '_');
+           if (!ptr || strncmp("_format", ptr, l - (ptr - buf)))
+               return XpmFileInvalid;
+           /* this is definitely an XPM 1 file */
+           data->format = 1;
+           n = 1;                      /* handle XPM1 as mainly XPM2 C */
+       } else {
+
+           /*
+            * skip the first word, get the second one, and see if this is
+            * XPM 2 or 3
+            */
+           l = xpmNextWord(data, buf, BUFSIZ);
+           if ((l == 3 && !strncmp("XPM", buf, 3)) ||
+               (l == 4 && !strncmp("XPM2", buf, 4))) {
+               if (l == 3)
+                   n = 1;              /* handle XPM as XPM2 C */
+               else {
+                   /* get the type key word */
+                   l = xpmNextWord(data, buf, BUFSIZ);
+
+                   /*
+                    * get infos about this type
+                    */
+                   while (xpmDataTypes[n].type
+                          && strncmp(xpmDataTypes[n].type, buf, l))
+                       n++;
+               }
+               data->format = 0;
+           } else
+               /* nope this is not an XPM file */
+               return XpmFileInvalid;
+       }
+       if (xpmDataTypes[n].type) {
+           if (n == 0) {               /* natural type */
+               data->Bcmt = xpmDataTypes[n].Bcmt;
+               data->Ecmt = xpmDataTypes[n].Ecmt;
+               xpmNextString(data);    /* skip the end of the headerline */
+               data->Bos = xpmDataTypes[n].Bos;
+               data->Eos = xpmDataTypes[n].Eos;
+           } else {
+               data->Bcmt = xpmDataTypes[n].Bcmt;
+               data->Ecmt = xpmDataTypes[n].Ecmt;
+               if (!data->format) {    /* XPM 2 or 3 */
+                   data->Bos = xpmDataTypes[n].Bos;
+                   data->Eos = '\0';
+                   /* get to the beginning of the first string */
+                   xpmNextString(data);
+                   data->Eos = xpmDataTypes[n].Eos;
+               } else                  /* XPM 1 skip end of line */
+                   xpmNextString(data);
+           }
+       } else
+           /* we don't know about that type of XPM file... */
+           return XpmFileInvalid;
+    }
+    return XpmSuccess;
+}
diff --git a/src/hashtab.c b/src/hashtab.c
new file mode 100644 (file)
index 0000000..49e6e48
--- /dev/null
@@ -0,0 +1,239 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* hashtab.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+*  this originaly comes from Colas Nahaboo as a part of Wool                  *
+*                                                                             *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+LFUNC(AtomMake, xpmHashAtom, (char *name, void *data));
+LFUNC(HashTableGrows, int, (xpmHashTable * table));
+
+static xpmHashAtom
+AtomMake(                              /* makes an atom */
+    char       *name,                  /* WARNING: is just pointed to */
+    void       *data)
+{
+    xpmHashAtom object = (xpmHashAtom) XpmMalloc(sizeof(struct _xpmHashAtom));
+
+    if (object) {
+       object->name = name;
+       object->data = data;
+    }
+    return object;
+}
+
+/************************\
+*                       *
+*  hash table routines          *
+*                       *
+\************************/
+
+/*
+ * Hash function definition:
+ * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char,
+ *                              hash2 = temporary for hashcode.
+ * INITIAL_TABLE_SIZE in slots
+ * HASH_TABLE_GROWS how hash table grows.
+ */
+
+/* Mock lisp function */
+#define HASH_FUNCTION    hash = (hash << 5) - hash + *hp++;
+/* #define INITIAL_HASH_SIZE 2017 */
+#define INITIAL_HASH_SIZE 256          /* should be enough for colors */
+#define HASH_TABLE_GROWS  size = size * 2;
+
+/* aho-sethi-ullman's HPJ (sizes should be primes)*/
+#ifdef notdef
+#define HASH_FUNCTION  hash <<= 4; hash += *hp++; \
+    if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2;
+#define INITIAL_HASH_SIZE 4095         /* should be 2^n - 1 */
+#define HASH_TABLE_GROWS  size = size << 1 + 1;
+#endif
+
+/* GNU emacs function */
+/*
+#define HASH_FUNCTION    hash = (hash << 3) + (hash >> 28) + *hp++;
+#define INITIAL_HASH_SIZE 2017
+#define HASH_TABLE_GROWS  size = size * 2;
+*/
+
+/* end of hash functions */
+
+/*
+ * The hash table is used to store atoms via their NAME:
+ *
+ * NAME --hash--> ATOM |--name--> "foo"
+ *                    |--data--> any value which has to be stored
+ *
+ */
+
+/*
+ * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name
+ * (slot points to NULL if it is not defined)
+ *
+ */
+
+xpmHashAtom *
+xpmHashSlot(
+    xpmHashTable       *table,
+    char               *s)
+{
+    xpmHashAtom *atomTable = table->atomTable;
+    unsigned int hash;
+    xpmHashAtom *p;
+    char *hp = s;
+    char *ns;
+
+    hash = 0;
+    while (*hp) {                      /* computes hash function */
+       HASH_FUNCTION
+    }
+    p = atomTable + hash % table->size;
+    while (*p) {
+       ns = (*p)->name;
+       if (ns[0] == s[0] && strcmp(ns, s) == 0)
+           break;
+       p--;
+       if (p < atomTable)
+           p = atomTable + table->size - 1;
+    }
+    return p;
+}
+
+static int
+HashTableGrows(xpmHashTable *table)
+{
+    xpmHashAtom *atomTable = table->atomTable;
+    unsigned int size = table->size;
+    xpmHashAtom *t, *p;
+    int i;
+    unsigned int oldSize = size;
+
+    t = atomTable;
+    HASH_TABLE_GROWS
+       table->size = size;
+    table->limit = size / 3;
+    if (size >= UINT_MAX / sizeof(*atomTable)) 
+       return (XpmNoMemory);
+    atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable));
+    if (!atomTable)
+       return (XpmNoMemory);
+    table->atomTable = atomTable;
+    for (p = atomTable + size; p > atomTable;)
+       *--p = NULL;
+    for (i = 0, p = t; i < oldSize; i++, p++)
+       if (*p) {
+           xpmHashAtom *ps = xpmHashSlot(table, (*p)->name);
+
+           *ps = *p;
+       }
+    XpmFree(t);
+    return (XpmSuccess);
+}
+
+/*
+ * xpmHashIntern(table, name, data)
+ * an xpmHashAtom is created if name doesn't exist, with the given data.
+ */
+
+int
+xpmHashIntern(
+    xpmHashTable       *table,
+    char               *tag,
+    void               *data)
+{
+    xpmHashAtom *slot;
+
+    if (!*(slot = xpmHashSlot(table, tag))) {
+       /* undefined, make a new atom with the given data */
+       if (!(*slot = AtomMake(tag, data)))
+           return (XpmNoMemory);
+       if (table->used >= table->limit) {
+           int ErrorStatus;
+
+           if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess)
+               return (ErrorStatus);
+           table->used++;
+           return (XpmSuccess);
+       }
+       table->used++;
+    }
+    return (XpmSuccess);
+}
+
+/*
+ *  must be called before allocating any atom
+ */
+
+int
+xpmHashTableInit(xpmHashTable *table)
+{
+    xpmHashAtom *p;
+    xpmHashAtom *atomTable;
+
+    table->size = INITIAL_HASH_SIZE;
+    table->limit = table->size / 3;
+    table->used = 0;
+    table->atomTable = NULL;
+    if (table->size >= UINT_MAX / sizeof(*atomTable))
+       return (XpmNoMemory);
+    atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable));
+    if (!atomTable)
+       return (XpmNoMemory);
+    for (p = atomTable + table->size; p > atomTable;)
+       *--p = NULL;
+    table->atomTable = atomTable;
+    return (XpmSuccess);
+}
+
+/*
+ *   frees a hashtable and all the stored atoms
+ */
+
+void
+xpmHashTableFree(xpmHashTable *table)
+{
+    xpmHashAtom *p;
+    xpmHashAtom *atomTable = table->atomTable;
+
+    if (!atomTable)
+       return;
+    for (p = atomTable + table->size; p > atomTable;)
+       if (*--p)
+           XpmFree(*p);
+    XpmFree(atomTable);
+    table->atomTable = NULL;
+}
diff --git a/src/misc.c b/src/misc.c
new file mode 100644 (file)
index 0000000..e5bc0f6
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* misc.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Miscellaneous utilities                                                    *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+#ifdef NEED_STRDUP
+/*
+ * in case strdup is not provided by the system here is one
+ * which does the trick
+ */
+char *
+xpmstrdup(char *s1)
+{
+    char *s2;
+    size_t l = strlen(s1) + 1;
+
+    if (s2 = (char *) XpmMalloc(l))
+       strcpy(s2, s1);
+    return s2;
+}
+
+#endif
+
+unsigned int
+xpmatoui(
+    register char      *p,
+    unsigned int        l,
+    unsigned int       *ui_return)
+{
+    register unsigned int n, i;
+
+    n = 0;
+    for (i = 0; i < l; i++)
+       if (*p >= '0' && *p <= '9')
+           n = n * 10 + *p++ - '0';
+       else
+           break;
+
+    if (i != 0 && i == l) {
+       *ui_return = n;
+       return 1;
+    } else
+       return 0;
+}
+
+/*
+ * Function returning a character string related to an error code.
+ */
+char *
+XpmGetErrorString(int errcode)
+{
+    switch (errcode) {
+    case XpmColorError:
+       return ("XpmColorError");
+    case XpmSuccess:
+       return ("XpmSuccess");
+    case XpmOpenFailed:
+       return ("XpmOpenFailed");
+    case XpmFileInvalid:
+       return ("XpmFileInvalid");
+    case XpmNoMemory:
+       return ("XpmNoMemory");
+    case XpmColorFailed:
+       return ("XpmColorFailed");
+    default:
+       return ("Invalid XpmError");
+    }
+}
+
+/*
+ * The following function provides a way to figure out if the linked library is
+ * newer or older than the one with which a program has been first compiled.
+ */
+int
+XpmLibraryVersion(void)
+{
+    return XpmIncludeVersion;
+}
+
+
+/* The following should help people wanting to use their own functions */
+#ifdef XpmFree
+#undef XpmFree
+#endif
+
+void
+XpmFree(void *ptr)
+{
+    free(ptr);
+}
diff --git a/src/parse.c b/src/parse.c
new file mode 100755 (executable)
index 0000000..5c7915f
--- /dev/null
@@ -0,0 +1,804 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* parse.c:                                                                    *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file or array and store the found informations                *
+*  in the given XpmImage structure.                                           *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <ctype.h>
+#include <string.h>
+
+#if defined(HAS_STRLCAT) || defined(HAVE_STRLCAT)
+# define STRLCAT(dst, src, dstsize) do { \
+       if (strlcat(dst, src, dstsize) >= (dstsize)) \
+           return (XpmFileInvalid); } while(0)
+# define STRLCPY(dst, src, dstsize) do { \
+       if (strlcpy(dst, src, dstsize) >= (dstsize)) \
+           return (XpmFileInvalid); } while(0)
+#else
+# define STRLCAT(dst, src, dstsize) do { \
+       if ((strlen(dst) + strlen(src)) < (dstsize)) \
+           strcat(dst, src); \
+       else return (XpmFileInvalid); } while(0)
+# define STRLCPY(dst, src, dstsize) do { \
+       if (strlen(src) < (dstsize)) \
+           strcpy(dst, src); \
+       else return (XpmFileInvalid); } while(0)
+#endif
+
+LFUNC(ParsePixels, int, (xpmData *data, unsigned int width,
+                        unsigned int height, unsigned int ncolors,
+                        unsigned int cpp, XpmColor *colorTable,
+                        xpmHashTable *hashtable, unsigned int **pixels));
+
+char *xpmColorKeys[] = {
+    "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 */
+};
+
+int
+xpmParseValues(
+    xpmData            *data,
+    unsigned int       *width,
+    unsigned int       *height,
+    unsigned int       *ncolors,
+    unsigned int       *cpp,
+    unsigned int       *x_hotspot,
+    unsigned int       *y_hotspot,
+    unsigned int       *hotspot,
+    unsigned int       *extensions)
+{
+    unsigned int l;
+    char buf[BUFSIZ + 1];
+
+    if (!data->format) {               /* XPM 2 or 3 */
+
+       /*
+        * read values: width, height, ncolors, chars_per_pixel
+        */
+       if (!(xpmNextUI(data, width) && xpmNextUI(data, height)
+             && xpmNextUI(data, ncolors) && xpmNextUI(data, cpp)))
+           return (XpmFileInvalid);
+
+       /*
+        * read optional information (hotspot and/or XPMEXT) if any
+        */
+       l = xpmNextWord(data, buf, BUFSIZ);
+       if (l) {
+           *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
+           if (*extensions)
+               *hotspot = (xpmNextUI(data, x_hotspot)
+                           && xpmNextUI(data, y_hotspot));
+           else {
+               *hotspot = (xpmatoui(buf, l, x_hotspot)
+                           && xpmNextUI(data, y_hotspot));
+               l = xpmNextWord(data, buf, BUFSIZ);
+               *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6));
+           }
+       }
+    } else {
+
+       /*
+        * XPM 1 file read values: width, height, ncolors, chars_per_pixel
+        */
+       int i;
+       char *ptr;
+       Bool got_one, saw_width = False, saw_height = False;
+       Bool saw_ncolors = False, saw_chars_per_pixel = False;
+
+       for (i = 0; i < 4; i++) {
+           l = xpmNextWord(data, buf, BUFSIZ);
+           if (l != 7 || strncmp("#define", buf, 7))
+               return (XpmFileInvalid);
+           l = xpmNextWord(data, buf, BUFSIZ);
+           if (!l)
+               return (XpmFileInvalid);
+           buf[l] = '\0';
+           ptr = buf;
+           got_one = False;
+           while (!got_one) {
+               ptr = strchr(ptr, '_');
+               if (!ptr)
+                   return (XpmFileInvalid);
+               switch (l - (ptr - buf)) {
+               case 6:
+                   if (saw_width || strncmp("_width", ptr, 6)
+                       || !xpmNextUI(data, width))
+                       return (XpmFileInvalid);
+                   else
+                       saw_width = True;
+                   got_one = True;
+                   break;
+               case 7:
+                   if (saw_height || strncmp("_height", ptr, 7)
+                       || !xpmNextUI(data, height))
+                       return (XpmFileInvalid);
+                   else
+                       saw_height = True;
+                   got_one = True;
+                   break;
+               case 8:
+                   if (saw_ncolors || strncmp("_ncolors", ptr, 8)
+                       || !xpmNextUI(data, ncolors))
+                       return (XpmFileInvalid);
+                   else
+                       saw_ncolors = True;
+                   got_one = True;
+                   break;
+               case 16:
+                   if (saw_chars_per_pixel
+                       || strncmp("_chars_per_pixel", ptr, 16)
+                       || !xpmNextUI(data, cpp))
+                       return (XpmFileInvalid);
+                   else
+                       saw_chars_per_pixel = True;
+                   got_one = True;
+                   break;
+               default:
+                   ptr++;
+               }
+           }
+           /* skip the end of line */
+           xpmNextString(data);
+       }
+       if (!saw_width || !saw_height || !saw_ncolors || !saw_chars_per_pixel)
+         return (XpmFileInvalid);
+
+       *hotspot = 0;
+       *extensions = 0;
+    }
+    return (XpmSuccess);
+}
+
+int
+xpmParseColors(
+    xpmData             *data,
+    unsigned int         ncolors,
+    unsigned int         cpp,
+    XpmColor           **colorTablePtr,
+    xpmHashTable        *hashtable)
+{
+    unsigned int key = 0, l, a, b, len;
+    unsigned int curkey;               /* current color key */
+    unsigned int lastwaskey;           /* key read */
+    char buf[BUFSIZ+1];
+    char curbuf[BUFSIZ];               /* current buffer */
+    char **sptr, *s;
+    XpmColor *color;
+    XpmColor *colorTable;
+    char **defaults;
+    int ErrorStatus;
+
+    if (ncolors >= UINT_MAX / sizeof(XpmColor))
+       return (XpmNoMemory);
+    colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor));
+    if (!colorTable)
+       return (XpmNoMemory);
+
+    if (!data->format) {               /* XPM 2 or 3 */
+       for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+           xpmNextString(data);        /* skip the line */
+
+           /*
+            * read pixel value
+            */
+           if (cpp >= UINT_MAX - 1) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
+           color->string = (char *) XpmMalloc(cpp + 1);
+           if (!color->string) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
+           for (b = 0, s = color->string; b < cpp; b++, s++)
+               *s = xpmGetC(data);
+           *s = '\0';
+
+           /*
+            * store the string in the hashtable with its color index number
+            */
+           if (USE_HASHTABLE) {
+               ErrorStatus =
+                   xpmHashIntern(hashtable, color->string, HashAtomData(a));
+               if (ErrorStatus != XpmSuccess) {
+                   xpmFreeColorTable(colorTable, ncolors);
+                   return (ErrorStatus);
+               }
+           }
+
+           /*
+            * read color keys and values
+            */
+           defaults = (char **) color;
+           curkey = 0;
+           lastwaskey = 0;
+           *curbuf = '\0';             /* init curbuf */
+           while ((l = xpmNextWord(data, buf, BUFSIZ))) {
+               if (!lastwaskey) {
+                   for (key = 0, sptr = xpmColorKeys; key < NKEYS; key++,
+                        sptr++)
+                       if ((strlen(*sptr) == l) && (!strncmp(*sptr, buf, l)))
+                           break;
+               }
+               if (!lastwaskey && key < NKEYS) {       /* open new key */
+                   if (curkey) {       /* flush string */
+                       len = strlen(curbuf) + 1;
+                       s = (char *) XpmMalloc(len);
+                       if (!s) {
+                           xpmFreeColorTable(colorTable, ncolors);
+                           return (XpmNoMemory);
+                       }
+                       defaults[curkey] = s;
+                       memcpy(s, curbuf, len);
+                   }
+                   curkey = key + 1;   /* set new key  */
+                   *curbuf = '\0';     /* reset curbuf */
+                   lastwaskey = 1;
+               } else {
+                   if (!curkey) {      /* key without value */
+                       xpmFreeColorTable(colorTable, ncolors);
+                       return (XpmFileInvalid);
+                   }
+                   if (!lastwaskey)
+                       STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */
+                   buf[l] = '\0';
+                   STRLCAT(curbuf, buf, sizeof(curbuf)); /* append buf */
+                   lastwaskey = 0;
+               }
+           }
+           if (!curkey) {              /* key without value */
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmFileInvalid);
+           }
+           len = strlen(curbuf) + 1; /* integer overflow just theoretically possible */
+           s = defaults[curkey] = (char *) XpmMalloc(len);
+           if (!s) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
+           memcpy(s, curbuf, len);
+       }
+    } else {                           /* XPM 1 */
+       /* get to the beginning of the first string */
+       data->Bos = '"';
+       data->Eos = '\0';
+       xpmNextString(data);
+       data->Eos = '"';
+       for (a = 0, color = colorTable; a < ncolors; a++, color++) {
+
+           /*
+            * read pixel value
+            */
+           if (cpp >= UINT_MAX - 1) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
+           color->string = (char *) XpmMalloc(cpp + 1);
+           if (!color->string) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
+           for (b = 0, s = color->string; b < cpp; b++, s++)
+               *s = xpmGetC(data);
+           *s = '\0';
+
+           /*
+            * store the string in the hashtable with its color index number
+            */
+           if (USE_HASHTABLE) {
+               ErrorStatus =
+                   xpmHashIntern(hashtable, color->string, HashAtomData(a));
+               if (ErrorStatus != XpmSuccess) {
+                   xpmFreeColorTable(colorTable, ncolors);
+                   return (ErrorStatus);
+               }
+           }
+
+           /*
+            * read color values
+            */
+           xpmNextString(data);        /* get to the next string */
+           *curbuf = '\0';             /* init curbuf */
+           while ((l = xpmNextWord(data, buf, BUFSIZ))) {
+               if (*curbuf != '\0')
+                   STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */
+               buf[l] = '\0';
+               STRLCAT(curbuf, buf, sizeof(curbuf));   /* append buf */
+           }
+           len = strlen(curbuf) + 1;
+           s = (char *) XpmMalloc(len);
+           if (!s) {
+               xpmFreeColorTable(colorTable, ncolors);
+               return (XpmNoMemory);
+           }
+           memcpy(s, curbuf, len);
+           color->c_color = s;
+           *curbuf = '\0';             /* reset curbuf */
+           if (a < ncolors - 1)        /* can we trust ncolors -> leave data's bounds */
+               xpmNextString(data);    /* get to the next string */
+       }
+    }
+    *colorTablePtr = colorTable;
+    return (XpmSuccess);
+}
+
+static int
+ParsePixels(
+    xpmData             *data,
+    unsigned int         width,
+    unsigned int         height,
+    unsigned int         ncolors,
+    unsigned int         cpp,
+    XpmColor            *colorTable,
+    xpmHashTable        *hashtable,
+    unsigned int       **pixels)
+{
+    unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */
+    unsigned int a, x, y;
+
+    if ((height > 0 && width >= UINT_MAX / height) ||
+       width * height >= UINT_MAX / sizeof(unsigned int)) 
+       return XpmNoMemory;
+#ifndef FOR_MSW
+    iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height);
+#else
+
+    /*
+     * special treatment to trick DOS malloc(size_t) where size_t is 16 bit!!
+     * XpmMalloc is defined to longMalloc(long) and checks the 16 bit boundary
+     */
+    iptr2 = (unsigned int *)
+       XpmMalloc((long) sizeof(unsigned int) * (long) width * (long) height);
+#endif
+    if (!iptr2)
+       return (XpmNoMemory);
+
+    iptr = iptr2;
+
+    switch (cpp) {
+
+    case (1):                          /* Optimize for single character
+                                        * colors */
+       {
+           unsigned short colidx[256];
+
+           if (ncolors > 256) {
+               XpmFree(iptr2); /* found by Egbert Eich */
+               return (XpmFileInvalid);
+           }
+
+           bzero((char *)colidx, 256 * sizeof(short));
+           for (a = 0; a < ncolors; a++)
+               colidx[(unsigned char)colorTable[a].string[0]] = a + 1;
+
+           for (y = 0; y < height; y++) {
+               xpmNextString(data);
+               for (x = 0; x < width; x++, iptr++) {
+                   int c = xpmGetC(data);
+
+                   if (c > 0 && c < 256 && colidx[c] != 0)
+                       *iptr = colidx[c] - 1;
+                   else {
+                       XpmFree(iptr2);
+                       return (XpmFileInvalid);
+                   }
+               }
+           }
+       }
+       break;
+
+    case (2):                          /* Optimize for double character
+                                        * colors */
+       {
+
+/* free all allocated pointers at all exits */
+#define FREE_CIDX \
+do \
+{ \
+       int f; for (f = 0; f < 256; f++) \
+       if (cidx[f]) XpmFree(cidx[f]); \
+} while(0)
+
+           /* array of pointers malloced by need */
+           unsigned short *cidx[256];
+           unsigned int char1;
+
+           bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
+           for (a = 0; a < ncolors; a++) {
+               char1 = (unsigned char) colorTable[a].string[0];
+               if (cidx[char1] == NULL) { /* get new memory */
+                   cidx[char1] = (unsigned short *)
+                       XpmCalloc(256, sizeof(unsigned short));
+                   if (cidx[char1] == NULL) { /* new block failed */
+                       FREE_CIDX;
+                       XpmFree(iptr2);
+                       return (XpmNoMemory);
+                   }
+               }
+               cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1;
+           }
+
+           for (y = 0; y < height; y++) {
+               xpmNextString(data);
+               for (x = 0; x < width; x++, iptr++) {
+                   int cc1 = xpmGetC(data);
+                   if (cc1 > 0 && cc1 < 256) {
+                       int cc2 = xpmGetC(data);
+                       if (cc2 > 0 && cc2 < 256 &&
+                           cidx[cc1] && cidx[cc1][cc2] != 0)
+                           *iptr = cidx[cc1][cc2] - 1;
+                       else {
+                           FREE_CIDX;
+                           XpmFree(iptr2);
+                           return (XpmFileInvalid);
+                       }
+                   } else {
+                       FREE_CIDX;
+                       XpmFree(iptr2);
+                       return (XpmFileInvalid);
+                   }
+               }
+           }
+           FREE_CIDX;
+       }
+       break;
+
+    default:                           /* Non-optimized case of long color
+                                        * names */
+       {
+           char *s;
+           char buf[BUFSIZ];
+
+           if (cpp >= sizeof(buf)) {
+               XpmFree(iptr2); /* found by Egbert Eich */
+               return (XpmFileInvalid);
+           }
+
+           buf[cpp] = '\0';
+           if (USE_HASHTABLE) {
+               xpmHashAtom *slot;
+
+               for (y = 0; y < height; y++) {
+                   xpmNextString(data);
+                   for (x = 0; x < width; x++, iptr++) {
+                       for (a = 0, s = buf; a < cpp; a++, s++)
+                           *s = xpmGetC(data); /* int assigned to char, not a problem here */
+                       slot = xpmHashSlot(hashtable, buf);
+                       if (!*slot) {   /* no color matches */
+                           XpmFree(iptr2);
+                           return (XpmFileInvalid);
+                       }
+                       *iptr = HashColorIndex(slot);
+                   }
+               }
+           } else {
+               for (y = 0; y < height; y++) {
+                   xpmNextString(data);
+                   for (x = 0; x < width; x++, iptr++) {
+                       for (a = 0, s = buf; a < cpp; a++, s++)
+                           *s = xpmGetC(data); /* int assigned to char, not a problem here */
+                       for (a = 0; a < ncolors; a++)
+                           if (!strcmp(colorTable[a].string, buf))
+                               break;
+                       if (a == ncolors) {     /* no color matches */
+                           XpmFree(iptr2);
+                           return (XpmFileInvalid);
+                       }
+                       *iptr = a;
+                   }
+               }
+           }
+       }
+       break;
+    }
+    *pixels = iptr2;
+    return (XpmSuccess);
+}
+
+int
+xpmParseExtensions(
+    xpmData             *data,
+    XpmExtension       **extensions,
+    unsigned int        *nextensions)
+{
+    XpmExtension *exts = NULL, *ext;
+    unsigned int num = 0;
+    unsigned int nlines, a, l, notstart, notend = 0;
+    int status;
+    char *string, *s, *s2, **sp;
+
+    xpmNextString(data);
+    exts = (XpmExtension *) XpmMalloc(sizeof(XpmExtension));
+    /* get the whole string */
+    status = xpmGetString(data, &string, &l);
+    if (status != XpmSuccess) {
+       XpmFree(exts);
+       return (status);
+    }
+    /* look for the key word XPMEXT, skip lines before this */
+    while ((notstart = strncmp("XPMEXT", string, 6))
+          && (notend = strncmp("XPMENDEXT", string, 9))) {
+       XpmFree(string);
+       xpmNextString(data);
+       status = xpmGetString(data, &string, &l);
+       if (status != XpmSuccess) {
+           XpmFree(exts);
+           return (status);
+       }
+    }
+    if (!notstart)
+       notend = strncmp("XPMENDEXT", string, 9);
+    while (!notstart && notend) {
+       /* there starts an extension */
+       ext = (XpmExtension *)
+           XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); /* can the loop be forced to iterate often enough to make "(num + 1) * sizeof(XpmExtension)" wrapping? */
+       if (!ext) {
+           XpmFree(string);
+           XpmFreeExtensions(exts, num);
+           return (XpmNoMemory);
+       }
+       exts = ext;
+       ext += num;
+       /* skip whitespace and store its name */
+       s2 = s = string + 6;
+       while (isspace(*s2))
+           s2++;
+       a = s2 - s;
+       ext->name = (char *) XpmMalloc(l - a - 6);
+       if (!ext->name) {
+           XpmFree(string);
+           ext->lines = NULL;
+           ext->nlines = 0;
+           XpmFreeExtensions(exts, num + 1);
+           return (XpmNoMemory);
+       }
+       strncpy(ext->name, s + a, l - a - 6);
+       XpmFree(string);
+       /* now store the related lines */
+       xpmNextString(data);
+       status = xpmGetString(data, &string, &l);
+       if (status != XpmSuccess) {
+           ext->lines = NULL;
+           ext->nlines = 0;
+           XpmFreeExtensions(exts, num + 1);
+           return (status);
+       }
+       ext->lines = (char **) XpmMalloc(sizeof(char *));
+       nlines = 0;
+       while ((notstart = strncmp("XPMEXT", string, 6))
+              && (notend = strncmp("XPMENDEXT", string, 9))) {
+           sp = (char **)
+               XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); /* can we iterate enough for a wrapping? */
+           if (!sp) {
+               XpmFree(string);
+               ext->nlines = nlines;
+               XpmFreeExtensions(exts, num + 1);
+               return (XpmNoMemory);
+           }
+           ext->lines = sp;
+           ext->lines[nlines] = string;
+           nlines++;
+           xpmNextString(data);
+           status = xpmGetString(data, &string, &l);
+           if (status != XpmSuccess) {
+               ext->nlines = nlines;
+               XpmFreeExtensions(exts, num + 1);
+               return (status);
+           }
+       }
+       if (!nlines) {
+           XpmFree(ext->lines);
+           ext->lines = NULL;
+       }
+       ext->nlines = nlines;
+       num++;
+    }
+    if (!num) {
+       XpmFree(string);
+       XpmFree(exts);
+       exts = NULL;
+    } else if (!notend)
+       XpmFree(string);
+    *nextensions = num;
+    *extensions = exts;
+    return (XpmSuccess);
+}
+
+
+/* function call in case of error */
+#undef RETURN
+#define RETURN(status) \
+do { \
+      goto error; \
+} while(0)
+
+/*
+ * This function parses an Xpm file or data and store the found informations
+ * in an an XpmImage structure which is returned.
+ */
+int
+xpmParseData(
+    xpmData    *data,
+    XpmImage   *image,
+    XpmInfo    *info)
+{
+    /* variables to return */
+    unsigned int width, height, ncolors, cpp;
+    unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0;
+    XpmColor *colorTable = NULL;
+    unsigned int *pixelindex = NULL;
+    char *hints_cmt = NULL;
+    char *colors_cmt = NULL;
+    char *pixels_cmt = NULL;
+
+    unsigned int cmts;
+    int ErrorStatus;
+    xpmHashTable hashtable;
+
+    cmts = info && (info->valuemask & XpmReturnComments);
+
+    /*
+     * parse the header
+     */
+    ErrorStatus = xpmParseHeader(data);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /*
+     * read values
+     */
+    ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp,
+                                &x_hotspot, &y_hotspot, &hotspot,
+                                &extensions);
+    if (ErrorStatus != XpmSuccess)
+       return (ErrorStatus);
+
+    /*
+     * store the hints comment line
+     */
+    if (cmts)
+       xpmGetCmt(data, &hints_cmt);
+
+    /*
+     * init the hashtable
+     */
+    if (USE_HASHTABLE) {
+       ErrorStatus = xpmHashTableInit(&hashtable);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+    }
+
+    /*
+     * read colors
+     */
+    ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable);
+    if (ErrorStatus != XpmSuccess) {
+       if (USE_HASHTABLE)
+           xpmHashTableFree(&hashtable);
+       RETURN(ErrorStatus);
+    }
+
+    /*
+     * store the colors comment line
+     */
+    if (cmts)
+       xpmGetCmt(data, &colors_cmt);
+
+    /*
+     * read pixels and index them on color number
+     */
+    ErrorStatus = ParsePixels(data, width, height, ncolors, cpp, colorTable,
+                             &hashtable, &pixelindex);
+
+    /*
+     * free the hastable
+     */
+    if (USE_HASHTABLE)
+       xpmHashTableFree(&hashtable);
+
+    if (ErrorStatus != XpmSuccess)
+       RETURN(ErrorStatus);
+
+    /*
+     * store the pixels comment line
+     */
+    if (cmts)
+       xpmGetCmt(data, &pixels_cmt);
+
+    /*
+     * parse extensions
+     */
+    if (info && (info->valuemask & XpmReturnExtensions)) {
+       if (extensions) {
+           ErrorStatus = xpmParseExtensions(data, &info->extensions,
+                                            &info->nextensions);
+           if (ErrorStatus != XpmSuccess)
+               RETURN(ErrorStatus);
+       } else {
+           info->extensions = NULL;
+           info->nextensions = 0;
+       }
+    }
+
+    /*
+     * store found informations in the XpmImage structure
+     */
+    image->width = width;
+    image->height = height;
+    image->cpp = cpp;
+    image->ncolors = ncolors;
+    image->colorTable = colorTable;
+    image->data = pixelindex;
+
+    if (info) {
+       if (cmts) {
+           info->hints_cmt = hints_cmt;
+           info->colors_cmt = colors_cmt;
+           info->pixels_cmt = pixels_cmt;
+       }
+       if (hotspot) {
+           info->x_hotspot = x_hotspot;
+           info->y_hotspot = y_hotspot;
+           info->valuemask |= XpmHotspot;
+       }
+    }
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (colorTable)
+       xpmFreeColorTable(colorTable, ncolors);
+    if (pixelindex)
+       XpmFree(pixelindex);
+    if (hints_cmt)
+       XpmFree(hints_cmt);
+    if (colors_cmt)
+       XpmFree(colors_cmt);
+    if (pixels_cmt)
+       XpmFree(pixels_cmt);
+
+    return(ErrorStatus);
+}
diff --git a/src/rgb.c b/src/rgb.c
new file mode 100644 (file)
index 0000000..848ae1f
--- /dev/null
+++ b/src/rgb.c
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* rgb.c:                                                                      *
+*                                                                             *
+*  XPM library                                                                *
+*  Rgb file utilities                                                         *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * Part of this code has been taken from the ppmtoxpm.c file written by Mark
+ * W. Snitily but has been modified for my special need
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+#include <ctype.h>
+
+#ifndef FOR_MSW                                /* normal part first, MSW part at
+                                        * the end, (huge ifdef!) */
+/*
+ * Read a rgb text file.  It stores the rgb values (0->65535)
+ * and the rgb mnemonics (malloc'ed) into the "rgbn" array.  Returns the
+ * number of entries stored.
+ */
+int
+xpmReadRgbNames(
+    char       *rgb_fname,
+    xpmRgbName  rgbn[])
+{
+    FILE *rgbf;
+    int n, items, red, green, blue;
+    char line[512], name[512], *rgbname, *s1, *s2;
+    xpmRgbName *rgb;
+
+    /* Open the rgb text file.  Abort if error. */
+    if ((rgbf = fopen(rgb_fname, "r")) == NULL)
+       return 0;
+
+    /* Loop reading each line in the file. */
+    n = 0;
+    rgb = rgbn; 
+    /* Quit if rgb text file has too many entries. */
+    while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) {
+
+       /* Skip silently if line is bad. */
+       items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name);
+       if (items != 4)
+           continue;
+
+       /*
+        * Make sure rgb values are within 0->255 range. Skip silently if
+        * bad.
+        */
+       if (red < 0 || red > 0xFF ||
+           green < 0 || green > 0xFF ||
+           blue < 0 || blue > 0xFF)
+           continue;
+
+       /* Allocate memory for ascii name. If error give up here. */
+       if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1)))
+           break;
+
+       /* Copy string to ascii name and lowercase it. */
+       for (s1 = name, s2 = rgbname; *s1; s1++)
+           *s2++ = tolower(*s1);
+       *s2 = '\0';
+
+       /* Save the rgb values and ascii name in the array. */
+       rgb->r = red * 257;             /* 65535/255 = 257 */
+       rgb->g = green * 257;
+       rgb->b = blue * 257;
+       rgb->name = rgbname;
+       rgb++;
+       n++;
+    }
+
+    fclose(rgbf);
+
+    /* Return the number of read rgb names. */
+    return n < 0 ? 0 : n;
+}
+
+/*
+ * Return the color name corresponding to the given rgb values
+ */
+char *
+xpmGetRgbName(
+    xpmRgbName rgbn[],         /* rgb mnemonics from rgb text file */
+    int                rgbn_max,       /* number of rgb mnemonics in table */
+    int                red,            /* rgb values */
+    int                green,
+    int                blue)
+{
+    int i;
+    xpmRgbName *rgb;
+
+    /*
+     * Just perform a dumb linear search over the rgb values of the color
+     * mnemonics.  One could speed things up by sorting the rgb values and
+     * using a binary search, or building a hash table, etc...
+     */
+    for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
+       if (red == rgb->r && green == rgb->g && blue == rgb->b)
+           return rgb->name;
+
+    /* if not found return NULL */
+    return NULL;
+}
+
+/*
+ * Free the strings which have been malloc'ed in xpmReadRgbNames
+ */
+void
+xpmFreeRgbNames(
+    xpmRgbName rgbn[],
+    int                rgbn_max)
+{
+    int i;
+    xpmRgbName *rgb;
+
+    for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++)
+       XpmFree(rgb->name);
+}
+
+#else                                  /* here comes the MSW part, the
+                                        * second part of the  huge ifdef */
+
+#include "rgbtab.h"                    /* hard coded rgb.txt table */
+
+int
+xpmReadRgbNames(
+    char       *rgb_fname,
+    xpmRgbName  rgbn[])
+{
+    /*
+     * check for consistency???
+     * table has to be sorted for calls on strcasecmp
+     */
+    return (numTheRGBRecords);
+}
+
+/*
+ * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red,
+ * which has something like #0303 for one color
+ */
+char *
+xpmGetRgbName(
+    xpmRgbName rgbn[],         /* rgb mnemonics from rgb text file
+                                * not used */
+    int                rgbn_max,       /* not used */
+    int                red,            /* rgb values */
+    int                green,
+    int                blue)
+
+{
+    int i;
+    unsigned long rgbVal;
+
+    i = 0;
+    while (i < numTheRGBRecords) {
+       rgbVal = theRGBRecords[i].rgb;
+       if (GetRValue(rgbVal) == red &&
+           GetGValue(rgbVal) == green &&
+           GetBValue(rgbVal) == blue)
+           return (theRGBRecords[i].name);
+       i++;
+    }
+    return (NULL);
+}
+
+/* used in XParseColor in simx.c */
+int
+xpmGetRGBfromName(
+    char       *inname,
+    int                *r,
+    int                *g,
+    int                *b)
+{
+    int left, right, middle;
+    int cmp;
+    unsigned long rgbVal;
+    char *name;
+    char *grey, *p;
+
+    name = xpmstrdup(inname);
+
+    /*
+     * the table in rgbtab.c has no names with spaces, and no grey, but a
+     * lot of gray
+     */
+    /* so first extract ' ' */
+    while (p = strchr(name, ' ')) {
+       while (*(p)) {                  /* till eof of string */
+           *p = *(p + 1);              /* copy to the left */
+           p++;
+       }
+    }
+    /* fold to lower case */
+    p = name;
+    while (*p) {
+       *p = tolower(*p);
+       p++;
+    }
+
+    /*
+     * substitute Grey with Gray, else rgbtab.h would have more than 100
+     * 'duplicate' entries
+     */
+    if (grey = strstr(name, "grey"))
+       grey[2] = 'a';
+
+    /* binary search */
+    left = 0;
+    right = numTheRGBRecords - 1;
+    do {
+       middle = (left + right) / 2;
+       cmp = xpmstrcasecmp(name, theRGBRecords[middle].name);
+       if (cmp == 0) {
+           rgbVal = theRGBRecords[middle].rgb;
+           *r = GetRValue(rgbVal);
+           *g = GetGValue(rgbVal);
+           *b = GetBValue(rgbVal);
+           free(name);
+           return (1);
+       } else if (cmp < 0) {
+           right = middle - 1;
+       } else {                        /* > 0 */
+           left = middle + 1;
+       }
+    } while (left <= right);
+
+    /*
+     * I don't like to run in a ColorInvalid error and to see no pixmap at
+     * all, so simply return a red pixel. Should be wrapped in an #ifdef
+     * HeDu
+     */
+
+    *r = 255;
+    *g = 0;
+    *b = 0;                            /* red error pixel */
+
+    free(name);
+    return (1);
+}
+
+void
+xpmFreeRgbNames(
+    xpmRgbName rgbn[],
+    int                rgbn_max)
+{
+    /* nothing to do */
+}
+
+#endif                                 /* MSW part */
diff --git a/src/rgbtab.h b/src/rgbtab.h
new file mode 100644 (file)
index 0000000..3b75184
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* rgbtab.h                                                                    *
+*                                                                             *
+* A hard coded rgb.txt. To keep it short I removed all colornames with        *
+* trailing numbers, Blue3 etc, except the GrayXX. Sorry Grey-lovers I prefer  *
+* Gray ;-). But Grey is recognized on lookups, only on save Gray will be      *
+* used, maybe you want to do some substitue there too.                        *
+*                                                                             *
+* To save memory the RGBs are coded in one long value, as done by the RGB     *
+* macro.                                                                      *
+*                                                                             *
+* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)                           *
+\*****************************************************************************/
+
+
+typedef struct {
+    char *name;
+    COLORREF rgb;                      /* it's unsigned long */
+}      rgbRecord;
+
+/*
+#define myRGB(r,g,b) \
+       ((unsigned long)r<<16|(unsigned long)g<<8|(unsigned long)b)
+*/
+#define myRGB(r,g,b)   RGB(r,g,b)      /* MSW has this macro */
+
+
+static rgbRecord theRGBRecords[] =
+{
+    {"AliceBlue", myRGB(240, 248, 255)},
+    {"AntiqueWhite", myRGB(250, 235, 215)},
+    {"Aquamarine", myRGB(50, 191, 193)},
+    {"Azure", myRGB(240, 255, 255)},
+    {"Beige", myRGB(245, 245, 220)},
+    {"Bisque", myRGB(255, 228, 196)},
+    {"Black", myRGB(0, 0, 0)},
+    {"BlanchedAlmond", myRGB(255, 235, 205)},
+    {"Blue", myRGB(0, 0, 255)},
+    {"BlueViolet", myRGB(138, 43, 226)},
+    {"Brown", myRGB(165, 42, 42)},
+    {"burlywood", myRGB(222, 184, 135)},
+    {"CadetBlue", myRGB(95, 146, 158)},
+    {"chartreuse", myRGB(127, 255, 0)},
+    {"chocolate", myRGB(210, 105, 30)},
+    {"Coral", myRGB(255, 114, 86)},
+    {"CornflowerBlue", myRGB(34, 34, 152)},
+    {"cornsilk", myRGB(255, 248, 220)},
+    {"Cyan", myRGB(0, 255, 255)},
+    {"DarkGoldenrod", myRGB(184, 134, 11)},
+    {"DarkGreen", myRGB(0, 86, 45)},
+    {"DarkKhaki", myRGB(189, 183, 107)},
+    {"DarkOliveGreen", myRGB(85, 86, 47)},
+    {"DarkOrange", myRGB(255, 140, 0)},
+    {"DarkOrchid", myRGB(139, 32, 139)},
+    {"DarkSalmon", myRGB(233, 150, 122)},
+    {"DarkSeaGreen", myRGB(143, 188, 143)},
+    {"DarkSlateBlue", myRGB(56, 75, 102)},
+    {"DarkSlateGray", myRGB(47, 79, 79)},
+    {"DarkTurquoise", myRGB(0, 166, 166)},
+    {"DarkViolet", myRGB(148, 0, 211)},
+    {"DeepPink", myRGB(255, 20, 147)},
+    {"DeepSkyBlue", myRGB(0, 191, 255)},
+    {"DimGray", myRGB(84, 84, 84)},
+    {"DodgerBlue", myRGB(30, 144, 255)},
+    {"Firebrick", myRGB(142, 35, 35)},
+    {"FloralWhite", myRGB(255, 250, 240)},
+    {"ForestGreen", myRGB(80, 159, 105)},
+    {"gainsboro", myRGB(220, 220, 220)},
+    {"GhostWhite", myRGB(248, 248, 255)},
+    {"Gold", myRGB(218, 170, 0)},
+    {"Goldenrod", myRGB(239, 223, 132)},
+    {"Gray", myRGB(126, 126, 126)},
+    {"Gray0", myRGB(0, 0, 0)},
+    {"Gray1", myRGB(3, 3, 3)},
+    {"Gray10", myRGB(26, 26, 26)},
+    {"Gray100", myRGB(255, 255, 255)},
+    {"Gray11", myRGB(28, 28, 28)},
+    {"Gray12", myRGB(31, 31, 31)},
+    {"Gray13", myRGB(33, 33, 33)},
+    {"Gray14", myRGB(36, 36, 36)},
+    {"Gray15", myRGB(38, 38, 38)},
+    {"Gray16", myRGB(41, 41, 41)},
+    {"Gray17", myRGB(43, 43, 43)},
+    {"Gray18", myRGB(46, 46, 46)},
+    {"Gray19", myRGB(48, 48, 48)},
+    {"Gray2", myRGB(5, 5, 5)},
+    {"Gray20", myRGB(51, 51, 51)},
+    {"Gray21", myRGB(54, 54, 54)},
+    {"Gray22", myRGB(56, 56, 56)},
+    {"Gray23", myRGB(59, 59, 59)},
+    {"Gray24", myRGB(61, 61, 61)},
+    {"Gray25", myRGB(64, 64, 64)},
+    {"Gray26", myRGB(66, 66, 66)},
+    {"Gray27", myRGB(69, 69, 69)},
+    {"Gray28", myRGB(71, 71, 71)},
+    {"Gray29", myRGB(74, 74, 74)},
+    {"Gray3", myRGB(8, 8, 8)},
+    {"Gray30", myRGB(77, 77, 77)},
+    {"Gray31", myRGB(79, 79, 79)},
+    {"Gray32", myRGB(82, 82, 82)},
+    {"Gray33", myRGB(84, 84, 84)},
+    {"Gray34", myRGB(87, 87, 87)},
+    {"Gray35", myRGB(89, 89, 89)},
+    {"Gray36", myRGB(92, 92, 92)},
+    {"Gray37", myRGB(94, 94, 94)},
+    {"Gray38", myRGB(97, 97, 97)},
+    {"Gray39", myRGB(99, 99, 99)},
+    {"Gray4", myRGB(10, 10, 10)},
+    {"Gray40", myRGB(102, 102, 102)},
+    {"Gray41", myRGB(105, 105, 105)},
+    {"Gray42", myRGB(107, 107, 107)},
+    {"Gray43", myRGB(110, 110, 110)},
+    {"Gray44", myRGB(112, 112, 112)},
+    {"Gray45", myRGB(115, 115, 115)},
+    {"Gray46", myRGB(117, 117, 117)},
+    {"Gray47", myRGB(120, 120, 120)},
+    {"Gray48", myRGB(122, 122, 122)},
+    {"Gray49", myRGB(125, 125, 125)},
+    {"Gray5", myRGB(13, 13, 13)},
+    {"Gray50", myRGB(127, 127, 127)},
+    {"Gray51", myRGB(130, 130, 130)},
+    {"Gray52", myRGB(133, 133, 133)},
+    {"Gray53", myRGB(135, 135, 135)},
+    {"Gray54", myRGB(138, 138, 138)},
+    {"Gray55", myRGB(140, 140, 140)},
+    {"Gray56", myRGB(143, 143, 143)},
+    {"Gray57", myRGB(145, 145, 145)},
+    {"Gray58", myRGB(148, 148, 148)},
+    {"Gray59", myRGB(150, 150, 150)},
+    {"Gray6", myRGB(15, 15, 15)},
+    {"Gray60", myRGB(153, 153, 153)},
+    {"Gray61", myRGB(156, 156, 156)},
+    {"Gray62", myRGB(158, 158, 158)},
+    {"Gray63", myRGB(161, 161, 161)},
+    {"Gray64", myRGB(163, 163, 163)},
+    {"Gray65", myRGB(166, 166, 166)},
+    {"Gray66", myRGB(168, 168, 168)},
+    {"Gray67", myRGB(171, 171, 171)},
+    {"Gray68", myRGB(173, 173, 173)},
+    {"Gray69", myRGB(176, 176, 176)},
+    {"Gray7", myRGB(18, 18, 18)},
+    {"Gray70", myRGB(179, 179, 179)},
+    {"Gray71", myRGB(181, 181, 181)},
+    {"Gray72", myRGB(184, 184, 184)},
+    {"Gray73", myRGB(186, 186, 186)},
+    {"Gray74", myRGB(189, 189, 189)},
+    {"Gray75", myRGB(191, 191, 191)},
+    {"Gray76", myRGB(194, 194, 194)},
+    {"Gray77", myRGB(196, 196, 196)},
+    {"Gray78", myRGB(199, 199, 199)},
+    {"Gray79", myRGB(201, 201, 201)},
+    {"Gray8", myRGB(20, 20, 20)},
+    {"Gray80", myRGB(204, 204, 204)},
+    {"Gray81", myRGB(207, 207, 207)},
+    {"Gray82", myRGB(209, 209, 209)},
+    {"Gray83", myRGB(212, 212, 212)},
+    {"Gray84", myRGB(214, 214, 214)},
+    {"Gray85", myRGB(217, 217, 217)},
+    {"Gray86", myRGB(219, 219, 219)},
+    {"Gray87", myRGB(222, 222, 222)},
+    {"Gray88", myRGB(224, 224, 224)},
+    {"Gray89", myRGB(227, 227, 227)},
+    {"Gray9", myRGB(23, 23, 23)},
+    {"Gray90", myRGB(229, 229, 229)},
+    {"Gray91", myRGB(232, 232, 232)},
+    {"Gray92", myRGB(235, 235, 235)},
+    {"Gray93", myRGB(237, 237, 237)},
+    {"Gray94", myRGB(240, 240, 240)},
+    {"Gray95", myRGB(242, 242, 242)},
+    {"Gray96", myRGB(245, 245, 245)},
+    {"Gray97", myRGB(247, 247, 247)},
+    {"Gray98", myRGB(250, 250, 250)},
+    {"Gray99", myRGB(252, 252, 252)},
+    {"Green", myRGB(0, 255, 0)},
+    {"GreenYellow", myRGB(173, 255, 47)},
+    {"honeydew", myRGB(240, 255, 240)},
+    {"HotPink", myRGB(255, 105, 180)},
+    {"IndianRed", myRGB(107, 57, 57)},
+    {"ivory", myRGB(255, 255, 240)},
+    {"Khaki", myRGB(179, 179, 126)},
+    {"lavender", myRGB(230, 230, 250)},
+    {"LavenderBlush", myRGB(255, 240, 245)},
+    {"LawnGreen", myRGB(124, 252, 0)},
+    {"LemonChiffon", myRGB(255, 250, 205)},
+    {"LightBlue", myRGB(176, 226, 255)},
+    {"LightCoral", myRGB(240, 128, 128)},
+    {"LightCyan", myRGB(224, 255, 255)},
+    {"LightGoldenrod", myRGB(238, 221, 130)},
+    {"LightGoldenrodYellow", myRGB(250, 250, 210)},
+    {"LightGray", myRGB(168, 168, 168)},
+    {"LightPink", myRGB(255, 182, 193)},
+    {"LightSalmon", myRGB(255, 160, 122)},
+    {"LightSeaGreen", myRGB(32, 178, 170)},
+    {"LightSkyBlue", myRGB(135, 206, 250)},
+    {"LightSlateBlue", myRGB(132, 112, 255)},
+    {"LightSlateGray", myRGB(119, 136, 153)},
+    {"LightSteelBlue", myRGB(124, 152, 211)},
+    {"LightYellow", myRGB(255, 255, 224)},
+    {"LimeGreen", myRGB(0, 175, 20)},
+    {"linen", myRGB(250, 240, 230)},
+    {"Magenta", myRGB(255, 0, 255)},
+    {"Maroon", myRGB(143, 0, 82)},
+    {"MediumAquamarine", myRGB(0, 147, 143)},
+    {"MediumBlue", myRGB(50, 50, 204)},
+    {"MediumForestGreen", myRGB(50, 129, 75)},
+    {"MediumGoldenrod", myRGB(209, 193, 102)},
+    {"MediumOrchid", myRGB(189, 82, 189)},
+    {"MediumPurple", myRGB(147, 112, 219)},
+    {"MediumSeaGreen", myRGB(52, 119, 102)},
+    {"MediumSlateBlue", myRGB(106, 106, 141)},
+    {"MediumSpringGreen", myRGB(35, 142, 35)},
+    {"MediumTurquoise", myRGB(0, 210, 210)},
+    {"MediumVioletRed", myRGB(213, 32, 121)},
+    {"MidnightBlue", myRGB(47, 47, 100)},
+    {"MintCream", myRGB(245, 255, 250)},
+    {"MistyRose", myRGB(255, 228, 225)},
+    {"moccasin", myRGB(255, 228, 181)},
+    {"NavajoWhite", myRGB(255, 222, 173)},
+    {"Navy", myRGB(35, 35, 117)},
+    {"NavyBlue", myRGB(35, 35, 117)},
+    {"OldLace", myRGB(253, 245, 230)},
+    {"OliveDrab", myRGB(107, 142, 35)},
+    {"Orange", myRGB(255, 135, 0)},
+    {"OrangeRed", myRGB(255, 69, 0)},
+    {"Orchid", myRGB(239, 132, 239)},
+    {"PaleGoldenrod", myRGB(238, 232, 170)},
+    {"PaleGreen", myRGB(115, 222, 120)},
+    {"PaleTurquoise", myRGB(175, 238, 238)},
+    {"PaleVioletRed", myRGB(219, 112, 147)},
+    {"PapayaWhip", myRGB(255, 239, 213)},
+    {"PeachPuff", myRGB(255, 218, 185)},
+    {"peru", myRGB(205, 133, 63)},
+    {"Pink", myRGB(255, 181, 197)},
+    {"Plum", myRGB(197, 72, 155)},
+    {"PowderBlue", myRGB(176, 224, 230)},
+    {"purple", myRGB(160, 32, 240)},
+    {"Red", myRGB(255, 0, 0)},
+    {"RosyBrown", myRGB(188, 143, 143)},
+    {"RoyalBlue", myRGB(65, 105, 225)},
+    {"SaddleBrown", myRGB(139, 69, 19)},
+    {"Salmon", myRGB(233, 150, 122)},
+    {"SandyBrown", myRGB(244, 164, 96)},
+    {"SeaGreen", myRGB(82, 149, 132)},
+    {"seashell", myRGB(255, 245, 238)},
+    {"Sienna", myRGB(150, 82, 45)},
+    {"SkyBlue", myRGB(114, 159, 255)},
+    {"SlateBlue", myRGB(126, 136, 171)},
+    {"SlateGray", myRGB(112, 128, 144)},
+    {"snow", myRGB(255, 250, 250)},
+    {"SpringGreen", myRGB(65, 172, 65)},
+    {"SteelBlue", myRGB(84, 112, 170)},
+    {"Tan", myRGB(222, 184, 135)},
+    {"Thistle", myRGB(216, 191, 216)},
+    {"tomato", myRGB(255, 99, 71)},
+    {"Transparent", myRGB(0, 0, 1)},
+    {"Turquoise", myRGB(25, 204, 223)},
+    {"Violet", myRGB(156, 62, 206)},
+    {"VioletRed", myRGB(243, 62, 150)},
+    {"Wheat", myRGB(245, 222, 179)},
+    {"White", myRGB(255, 255, 255)},
+    {"WhiteSmoke", myRGB(245, 245, 245)},
+    {"Yellow", myRGB(255, 255, 0)},
+    {"YellowGreen", myRGB(50, 216, 56)},
+    NULL
+};
+
+static int numTheRGBRecords = 234;
diff --git a/src/scan.c b/src/scan.c
new file mode 100755 (executable)
index 0000000..d2780a1
--- /dev/null
@@ -0,0 +1,1024 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* scan.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Scanning utility for XPM file format                                       *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+/* October 2004, source code review by Thomas Biege <thomas@suse.de> */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "XpmI.h"
+
+#define MAXPRINTABLE 92                        /* number of printable ascii chars
+                                        * minus \ and " for string compat
+                                        * and ? to avoid ANSI trigraphs. */
+
+static char *printable =
+" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\
+ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|";
+
+/*
+ * printable begin with a space, so in most case, due to my algorithm, 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
+ */
+
+
+typedef struct {
+    Pixel *pixels;
+    unsigned int *pixelindex;
+    unsigned int size;
+    unsigned int ncolors;
+    unsigned int mask_pixel;           /* whether there is or not */
+}      PixelsMap;
+
+LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap,
+                       unsigned int *index_return));
+
+LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap,
+                           unsigned int *index_return));
+
+typedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap,
+                           unsigned int *index_return);
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+LFUNC(GetImagePixels, int, (XImage *image, unsigned int width,
+                           unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width,
+                             unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width,
+                             unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width,
+                            unsigned int height, PixelsMap *pmap));
+
+LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width,
+                            unsigned int height, PixelsMap *pmap,
+                            storeFuncPtr storeFunc));
+# else /* AMIGA */
+LFUNC(AGetImagePixels, int, (XImage *image, unsigned int width,
+                            unsigned int height, PixelsMap *pmap,
+                            storeFuncPtr storeFunc));
+# endif/* AMIGA */
+#else  /* ndef FOR_MSW */
+LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width,
+                              unsigned int height, PixelsMap *pmap,
+                              storeFuncPtr storeFunc));
+#endif
+LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp,
+                                 XpmAttributes *attributes));
+
+LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, 
+                            unsigned int ncolors, 
+                            Pixel *pixels, unsigned int mask,
+                            unsigned int cpp, XpmAttributes *attributes));
+
+/*
+ * This function stores the given pixel in the given arrays which are grown
+ * if not large enough.
+ */
+static int
+storePixel(
+    Pixel               pixel,
+    PixelsMap          *pmap,
+    unsigned int       *index_return)
+{
+    unsigned int i;
+    Pixel *p;
+    unsigned int ncolors;
+
+    if (*index_return) {               /* this is a transparent pixel! */
+       *index_return = 0;
+       return 0;
+    }
+    ncolors = pmap->ncolors;
+    p = pmap->pixels + pmap->mask_pixel;
+    for (i = pmap->mask_pixel; i < ncolors; i++, p++)
+       if (*p == pixel)
+           break;
+    if (i == ncolors) {
+       if (ncolors >= pmap->size) {
+           pmap->size *= 2;
+           p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size);
+           if (!p)
+               return (1);
+           pmap->pixels = p;
+
+       }
+       (pmap->pixels)[ncolors] = pixel;
+       pmap->ncolors++;
+    }
+    *index_return = i;
+    return 0;
+}
+
+static int
+storeMaskPixel(
+    Pixel               pixel,
+    PixelsMap          *pmap,
+    unsigned int       *index_return)
+{
+    if (!pixel) {
+       if (!pmap->ncolors) {
+           pmap->ncolors = 1;
+           (pmap->pixels)[0] = 0;
+           pmap->mask_pixel = 1;
+       }
+       *index_return = 1;
+    } else
+       *index_return = 0;
+    return 0;
+}
+
+/* function call in case of error */
+#undef RETURN
+#define RETURN(status) \
+do { \
+      ErrorStatus = status; \
+      goto error; \
+} while(0)
+
+/*
+ * This function scans the given image and stores the found informations in
+ * the given XpmImage structure.
+ */
+int
+XpmCreateXpmImageFromImage(
+    Display            *display,
+    XImage             *image,
+    XImage             *shapeimage,
+    XpmImage           *xpmimage,
+    XpmAttributes      *attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    unsigned int cpp;
+
+    /* variables to return */
+    PixelsMap pmap;
+    XpmColor *colorTable = NULL;
+    int ErrorStatus = 0;
+
+    /* calculation variables */
+    unsigned int width = 0;
+    unsigned int height = 0;
+    unsigned int cppm;                 /* minimum chars per pixel */
+    unsigned int c;
+
+    /* initialize pmap */
+    pmap.pixels = NULL;
+    pmap.pixelindex = NULL;
+    pmap.size = 256;                   /* should be enough most of the time */
+    pmap.ncolors = 0;
+    pmap.mask_pixel = 0;
+
+    /*
+     * get geometry
+     */
+    if (image) {
+       width = image->width;
+       height = image->height;
+    } else if (shapeimage) {
+       width = shapeimage->width;
+       height = shapeimage->height;
+    }
+
+    /*
+     * retrieve information from the XpmAttributes
+     */
+    if (attributes && (attributes->valuemask & XpmCharsPerPixel
+/* 3.2 backward compatibility code */
+                      || attributes->valuemask & XpmInfos))
+/* end 3.2 bc */
+       cpp = attributes->cpp;
+    else
+       cpp = 0;
+
+    if ((height > 0 && width >= UINT_MAX / height) ||
+       width * height >= UINT_MAX / sizeof(unsigned int))
+       RETURN(XpmNoMemory);
+    pmap.pixelindex =
+       (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
+    if (!pmap.pixelindex)
+       RETURN(XpmNoMemory);
+
+    if (pmap.size >= UINT_MAX / sizeof(Pixel)) 
+       RETURN(XpmNoMemory);
+
+    pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size);
+    if (!pmap.pixels)
+       RETURN(XpmNoMemory);
+
+    /*
+     * scan shape mask if any
+     */
+    if (shapeimage) {
+#ifndef FOR_MSW
+# ifndef AMIGA
+       ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap,
+                                     storeMaskPixel);
+# else
+       ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap,
+                                     storeMaskPixel);
+# endif
+#else
+       ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height,
+                                       &pmap, storeMaskPixel);
+#endif
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+    }
+
+    /*
+     * scan the image data
+     * 
+     * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized
+     * functions, otherwise use slower but sure general one.
+     * 
+     */
+
+    if (image) {
+#ifndef FOR_MSW
+# ifndef AMIGA
+       if (((image->bits_per_pixel | image->depth) == 1)  &&
+           (image->byte_order == image->bitmap_bit_order))
+           ErrorStatus = GetImagePixels1(image, width, height, &pmap,
+                                         storePixel);
+       else if (image->format == ZPixmap) {
+           if (image->bits_per_pixel == 8)
+               ErrorStatus = GetImagePixels8(image, width, height, &pmap);
+           else if (image->bits_per_pixel == 16)
+               ErrorStatus = GetImagePixels16(image, width, height, &pmap);
+           else if (image->bits_per_pixel == 32)
+               ErrorStatus = GetImagePixels32(image, width, height, &pmap);
+       } else
+           ErrorStatus = GetImagePixels(image, width, height, &pmap);
+# else
+       ErrorStatus = AGetImagePixels(image, width, height, &pmap,
+                                     storePixel);
+# endif
+#else
+       ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap,
+                                       storePixel);
+#endif
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+    }
+
+    /*
+     * get rgb values and a string of char, and possibly a name for each
+     * color
+     */
+    if (pmap.ncolors >= UINT_MAX / sizeof(XpmColor))
+       RETURN(XpmNoMemory);
+    colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor));
+    if (!colorTable)
+       RETURN(XpmNoMemory);
+
+    /* compute the minimal cpp */
+    for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++)
+       c *= MAXPRINTABLE;
+    if (cpp < cppm)
+       cpp = cppm;
+
+    if (pmap.mask_pixel) {
+       ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes);
+       if (ErrorStatus != XpmSuccess)
+           RETURN(ErrorStatus);
+    }
+
+    ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors,
+                                 pmap.pixels, pmap.mask_pixel, cpp,
+                                 attributes);
+    if (ErrorStatus != XpmSuccess)
+       RETURN(ErrorStatus);
+
+    /*
+     * store found informations in the XpmImage structure
+     */
+    xpmimage->width = width;
+    xpmimage->height = height;
+    xpmimage->cpp = cpp;
+    xpmimage->ncolors = pmap.ncolors;
+    xpmimage->colorTable = colorTable;
+    xpmimage->data = pmap.pixelindex;
+
+    XpmFree(pmap.pixels);
+    return (XpmSuccess);
+
+/* exit point in case of error, free only locally allocated variables */
+error:
+    if (pmap.pixelindex)
+       XpmFree(pmap.pixelindex);
+    if (pmap.pixels)
+       XpmFree(pmap.pixels);
+    if (colorTable)
+       xpmFreeColorTable(colorTable, pmap.ncolors);
+
+    return (ErrorStatus);
+}
+
+static int
+ScanTransparentColor(
+    XpmColor           *color,
+    unsigned int        cpp,
+    XpmAttributes      *attributes)
+{
+    char *s;
+    unsigned int a, b, c;
+
+    /* first get a character string */
+    a = 0;
+    if (cpp >= UINT_MAX - 1)
+       return (XpmNoMemory);
+    if (!(s = color->string = (char *) XpmMalloc(cpp + 1)))
+       return (XpmNoMemory);
+    *s++ = printable[c = a % MAXPRINTABLE];
+    for (b = 1; b < cpp; b++, s++)
+       *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE];
+    *s = '\0';
+
+    /* then retreive related info from the attributes if any */
+    if (attributes && (attributes->valuemask & XpmColorTable
+/* 3.2 backward compatibility code */
+                      || attributes->valuemask & XpmInfos)
+/* end 3.2 bc */
+       && attributes->mask_pixel != XpmUndefPixel) {
+
+       unsigned int key;
+       char **defaults = (char **) color;
+       char **mask_defaults;
+
+/* 3.2 backward compatibility code */
+       if (attributes->valuemask & XpmColorTable)
+/* end 3.2 bc */
+           mask_defaults = (char **) (
+               attributes->colorTable + attributes->mask_pixel);
+/* 3.2 backward compatibility code */
+       else
+           mask_defaults = (char **)
+               ((XpmColor **) attributes->colorTable)[attributes->mask_pixel];
+/* end 3.2 bc */
+       for (key = 1; key <= NKEYS; key++) {
+           if ((s = mask_defaults[key])) {
+               defaults[key] = (char *) xpmstrdup(s);
+               if (!defaults[key])
+                   return (XpmNoMemory);
+           }
+       }
+    } else {
+       color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR);
+       if (!color->c_color)
+           return (XpmNoMemory);
+    }
+    return (XpmSuccess);
+}
+
+static int
+ScanOtherColors(
+    Display            *display,
+    XpmColor           *colors,
+    unsigned int        ncolors,
+    Pixel              *pixels,
+    unsigned int        mask,
+    unsigned int        cpp,
+    XpmAttributes      *attributes)
+{
+    /* variables stored in the XpmAttributes structure */
+    Colormap colormap;
+    char *rgb_fname;
+
+#ifndef FOR_MSW
+    xpmRgbName rgbn[MAX_RGBNAMES];
+#else
+    xpmRgbName *rgbn = NULL; 
+#endif    
+    int rgbn_max = 0;
+    unsigned int i, j, c, i2;
+    XpmColor *color;
+    XColor *xcolors = NULL, *xcolor;
+    char *colorname, *s;
+    XpmColor *colorTable = NULL, **oldColorTable = NULL;
+    unsigned int ancolors = 0;
+    Pixel *apixels = NULL;
+    unsigned int mask_pixel = 0;
+    Bool found;
+
+    /* retrieve information from the XpmAttributes */
+    if (attributes && (attributes->valuemask & XpmColormap))
+       colormap = attributes->colormap;
+    else
+       colormap = XDefaultColormap(display, XDefaultScreen(display));
+    if (attributes && (attributes->valuemask & XpmRgbFilename))
+       rgb_fname = attributes->rgb_fname;
+    else
+       rgb_fname = NULL;
+
+    /* start from the right element */
+    if (mask) {
+       colors++;
+       ncolors--;
+       pixels++;
+    }
+
+    /* first get character strings and rgb values */
+    if (ncolors >= UINT_MAX / sizeof(XColor) || cpp >= UINT_MAX - 1)
+       return (XpmNoMemory);
+    xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors);
+    if (!xcolors)
+       return (XpmNoMemory);
+
+    for (i = 0, i2 = mask, color = colors, xcolor = xcolors;
+        i < ncolors; i++, i2++, color++, xcolor++, pixels++) {
+
+       if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) {
+           XpmFree(xcolors);
+           return (XpmNoMemory);
+       }
+       *s++ = printable[c = i2 % MAXPRINTABLE];
+       for (j = 1; j < cpp; j++, s++)
+           *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE];
+       *s = '\0';
+
+       xcolor->pixel = *pixels;
+    }
+    XQueryColors(display, colormap, xcolors, ncolors);
+
+#ifndef FOR_MSW
+    /* read the rgb file if any was specified */
+    if (rgb_fname)
+       rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn);
+#else
+    /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */
+    rgbn_max = xpmReadRgbNames(NULL, NULL);
+#endif
+
+    if (attributes && attributes->valuemask & XpmColorTable) {
+       colorTable = attributes->colorTable;
+       ancolors = attributes->ncolors;
+       apixels = attributes->pixels;
+       mask_pixel = attributes->mask_pixel;
+    }
+/* 3.2 backward compatibility code */
+    else if (attributes && attributes->valuemask & XpmInfos) {
+       oldColorTable = (XpmColor **) attributes->colorTable;
+       ancolors = attributes->ncolors;
+       apixels = attributes->pixels;
+       mask_pixel = attributes->mask_pixel;
+    }
+/* end 3.2 bc */
+
+    for (i = 0, color = colors, xcolor = xcolors; i < ncolors;
+                                                 i++, color++, xcolor++) {
+
+       /* look for related info from the attributes if any */
+       found = False;
+       if (ancolors) {
+           unsigned int offset = 0;
+
+           for (j = 0; j < ancolors; j++) {
+               if (j == mask_pixel) {
+                   offset = 1;
+                   continue;
+               }
+               if (apixels[j - offset] == xcolor->pixel)
+                   break;
+           }
+           if (j != ancolors) {
+               unsigned int key;
+               char **defaults = (char **) color;
+               char **adefaults;
+
+/* 3.2 backward compatibility code */
+               if (oldColorTable)
+                   adefaults = (char **) oldColorTable[j];
+               else
+/* end 3.2 bc */
+                   adefaults = (char **) (colorTable + j);
+
+               found = True;
+               for (key = 1; key <= NKEYS; key++) {
+                   if ((s = adefaults[key]))
+                       defaults[key] = (char *) xpmstrdup(s);
+               }
+           }
+       }
+       if (!found) {
+           /* if nothing found look for a color name */
+           colorname = NULL;
+           if (rgbn_max)
+               colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red,
+                                         xcolor->green, xcolor->blue);
+           if (colorname)
+               color->c_color = (char *) xpmstrdup(colorname);
+           else {
+               /* at last store the rgb value */
+               char buf[BUFSIZ];
+#ifndef FOR_MSW
+               sprintf(buf, "#%04X%04X%04X",
+                       xcolor->red, xcolor->green, xcolor->blue);
+#else   
+               sprintf(buf, "#%02x%02x%02x",
+                       xcolor->red, xcolor->green, xcolor->blue);
+#endif                 
+               color->c_color = (char *) xpmstrdup(buf);
+           }
+           if (!color->c_color) {
+               XpmFree(xcolors);
+               xpmFreeRgbNames(rgbn, rgbn_max);
+               return (XpmNoMemory);
+           }
+       }
+    }
+
+    XpmFree(xcolors);
+    xpmFreeRgbNames(rgbn, rgbn_max);
+    return (XpmSuccess);
+}
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+/*
+ * The functions below are written from X11R5 MIT's code (XImUtil.c)
+ *
+ * The idea is to have faster functions than the standard XGetPixel function
+ * to scan the image data. Indeed we can speed up things by suppressing tests
+ * performed for each pixel. We do exactly the same tests but at the image
+ * level.
+ */
+
+static unsigned long Const low_bits_table[] = {
+    0x00000000, 0x00000001, 0x00000003, 0x00000007,
+    0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f,
+    0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff,
+    0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff,
+    0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff,
+    0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff,
+    0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff,
+    0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff,
+    0xffffffff
+};
+
+/*
+ * Default method to scan pixels of an image data structure.
+ * The algorithm used is:
+ *
+ *     copy the source bitmap_unit or Zpixel into temp
+ *     normalize temp if needed
+ *     extract the pixel bits into return value
+ *
+ */
+
+static int
+GetImagePixels(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    PixelsMap          *pmap)
+{
+    char *src;
+    char *dst;
+    unsigned int *iptr;
+    char *data;
+    unsigned int x, y;
+    int bits, depth, ibu, ibpp, offset, i;
+    unsigned long lbt;
+    Pixel pixel, px;
+
+    data = image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+    ibpp = image->bits_per_pixel;
+    offset = image->xoffset;
+
+    if (image->bitmap_unit < 0)
+           return (XpmNoMemory);
+
+    if ((image->bits_per_pixel | image->depth) == 1) {
+       ibu = image->bitmap_unit;
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               src = &data[XYINDEX(x, y, image)];
+               dst = (char *) &pixel;
+               pixel = 0;
+               for (i = ibu >> 3; --i >= 0;)
+                   *dst++ = *src++;
+               XYNORMALIZE(&pixel, image);
+               bits = (x + offset) % ibu;
+               pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1;
+               if (ibpp != depth)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    } else if (image->format == XYPixmap) {
+       int nbytes, bpl, j;
+       long plane = 0;
+       ibu = image->bitmap_unit;
+       nbytes = ibu >> 3;
+       bpl = image->bytes_per_line;
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               pixel = 0;
+               plane = 0;
+               for (i = depth; --i >= 0;) {
+                   src = &data[XYINDEX(x, y, image) + plane];
+                   dst = (char *) &px;
+                   px = 0;
+                   for (j = nbytes; --j >= 0;)
+                       *dst++ = *src++;
+                   XYNORMALIZE(&px, image);
+                   bits = (x + offset) % ibu;
+                   pixel = (pixel << 1) |
+                           (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1);
+                   plane = plane + (bpl * height);
+               }
+               if (ibpp != depth)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    } else if (image->format == ZPixmap) {
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               src = &data[ZINDEX(x, y, image)];
+               dst = (char *) &px;
+               px = 0;
+               for (i = (ibpp + 7) >> 3; --i >= 0;)
+                   *dst++ = *src++;
+               ZNORMALIZE(&px, image);
+               pixel = 0;
+               for (i = sizeof(unsigned long); --i >= 0;)
+                   pixel = (pixel << 8) | ((unsigned char *) &px)[i];
+               if (ibpp == 4) {
+                   if (x & 1)
+                       pixel >>= 4;
+                   else
+                       pixel &= 0xf;
+               }
+               if (ibpp != depth)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    } else
+       return (XpmColorError); /* actually a bad image */
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 32-bits Z image data structure
+ */
+
+#if !defined(WORD64) && !defined(LONG64)
+static unsigned long byteorderpixel = MSBFirst << 24;
+#endif
+
+static int
+GetImagePixels32(
+    XImage              *image,
+    unsigned int        width,
+    unsigned int        height,
+    PixelsMap          *pmap)
+{
+    unsigned char *addr;
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int x, y;
+    unsigned long lbt;
+    Pixel pixel;
+    int depth;
+
+    data = (unsigned char *) image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+#if !defined(WORD64) && !defined(LONG64)
+    if (*((char *) &byteorderpixel) == image->byte_order) {
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX32(x, y, image)];
+               pixel = *((unsigned long *) addr);
+               if (depth != 32)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    } else
+#endif
+    if (image->byte_order == MSBFirst)
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX32(x, y, image)];
+               pixel = ((unsigned long) addr[0] << 24 |
+                        (unsigned long) addr[1] << 16 |
+                        (unsigned long) addr[2] << 8 |
+                        addr[3]);
+               if (depth != 32)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    else
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX32(x, y, image)];
+               pixel = (addr[0] |
+                        (unsigned long) addr[1] << 8 |
+                        (unsigned long) addr[2] << 16 |
+                        (unsigned long) addr[3] << 24);
+               if (depth != 32)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 16-bits Z image data structure
+ */
+
+static int
+GetImagePixels16(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    PixelsMap          *pmap)
+{
+    unsigned char *addr;
+    unsigned char *data;
+    unsigned int *iptr;
+    unsigned int x, y;
+    unsigned long lbt;
+    Pixel pixel;
+    int depth;
+
+    data = (unsigned char *) image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+    if (image->byte_order == MSBFirst)
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX16(x, y, image)];
+               pixel = addr[0] << 8 | addr[1];
+               if (depth != 16)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    else
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               addr = &data[ZINDEX16(x, y, image)];
+               pixel = addr[0] | addr[1] << 8;
+               if (depth != 16)
+                   pixel &= lbt;
+               if (storePixel(pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 8-bits Z image data structure
+ */
+
+static int
+GetImagePixels8(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    PixelsMap          *pmap)
+{
+    unsigned int *iptr;
+    unsigned char *data;
+    unsigned int x, y;
+    unsigned long lbt;
+    Pixel pixel;
+    int depth;
+
+    data = (unsigned char *) image->data;
+    iptr = pmap->pixelindex;
+    depth = image->depth;
+    lbt = low_bits_table[depth];
+    for (y = 0; y < height; y++)
+       for (x = 0; x < width; x++, iptr++) {
+           pixel = data[ZINDEX8(x, y, image)];
+           if (depth != 8)
+               pixel &= lbt;
+           if (storePixel(pixel, pmap, iptr))
+               return (XpmNoMemory);
+       }
+    return (XpmSuccess);
+}
+
+/*
+ * scan pixels of a 1-bit depth Z image data structure
+ */
+
+static int
+GetImagePixels1(
+    XImage             *image,
+    unsigned int        width,
+    unsigned int        height,
+    PixelsMap           *pmap,
+    storeFuncPtr        storeFunc)
+{
+    unsigned int *iptr;
+    unsigned int x, y;
+    char *data;
+    Pixel pixel;
+    int xoff, yoff, offset, bpl;
+
+    data = image->data;
+    iptr = pmap->pixelindex;
+    offset = image->xoffset;
+    bpl = image->bytes_per_line;
+
+    if (image->bitmap_bit_order == MSBFirst)
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               xoff = x + offset;
+               yoff = y * bpl + (xoff >> 3);
+               xoff &= 7;
+               pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0;
+               if ((*storeFunc) (pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    else
+       for (y = 0; y < height; y++)
+           for (x = 0; x < width; x++, iptr++) {
+               xoff = x + offset;
+               yoff = y * bpl + (xoff >> 3);
+               xoff &= 7;
+               pixel = (data[yoff] & (1 << xoff)) ? 1 : 0;
+               if ((*storeFunc) (pixel, pmap, iptr))
+                   return (XpmNoMemory);
+           }
+    return (XpmSuccess);
+}
+
+# else /* AMIGA */
+
+#define CLEAN_UP(status) \
+do {\
+    if (pixels) XpmFree (pixels);\
+    if (tmp_img) FreeXImage (tmp_img);\
+    return (status);\
+} while(0)
+
+static int
+AGetImagePixels (
+    XImage        *image,
+    unsigned int   width,
+    unsigned int   height,
+    PixelsMap     *pmap,
+    int          (*storeFunc) (Pixel, PixelsMap *, unsigned int *))
+{
+    unsigned int   *iptr;
+    unsigned int    x, y;
+    unsigned char  *pixels;
+    XImage         *tmp_img;
+    
+    pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels));
+    if (pixels == NULL)
+       return XpmNoMemory;
+    
+    tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth);
+    if (tmp_img == NULL)
+       CLEAN_UP (XpmNoMemory);
+    
+    iptr = pmap->pixelindex;
+    for (y = 0; y < height; ++y)
+    {
+       ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp);
+       for (x = 0; x < width; ++x, ++iptr)
+       {
+           if ((*storeFunc) (pixels[x], pmap, iptr))
+               CLEAN_UP (XpmNoMemory);
+       }
+    }
+    
+    CLEAN_UP (XpmSuccess);
+}
+
+#undef CLEAN_UP
+
+# endif/* AMIGA */
+#else  /* ndef FOR_MSW */
+static int
+MSWGetImagePixels(
+    Display     *display,
+    XImage      *image,
+    unsigned int  width,
+    unsigned int  height,
+    PixelsMap   *pmap,
+    int                (*storeFunc) (Pixel, PixelsMap*, unsigned int *))
+{
+    unsigned int *iptr;
+    unsigned int x, y;
+    Pixel pixel;
+
+    iptr = pmap->pixelindex;
+
+    SelectObject(*display, image->bitmap);
+    for (y = 0; y < height; y++) {
+       for (x = 0; x < width; x++, iptr++) {
+           pixel = GetPixel(*display, x, y);
+           if ((*storeFunc) (pixel, pmap, iptr))
+               return (XpmNoMemory);
+       }
+    }
+    return (XpmSuccess);
+}
+
+#endif
+
+#ifndef FOR_MSW
+# ifndef AMIGA
+int
+XpmCreateXpmImageFromPixmap(
+    Display            *display,
+    Pixmap              pixmap,
+    Pixmap              shapemask,
+    XpmImage           *xpmimage,
+    XpmAttributes      *attributes)
+{
+    XImage *ximage = NULL;
+    XImage *shapeimage = NULL;
+    unsigned int width = 0;
+    unsigned int height = 0;
+    int ErrorStatus;
+
+    /* get geometry */
+    if (attributes && attributes->valuemask & XpmSize) {
+       width = attributes->width;
+       height = attributes->height;
+    }
+    /* get the ximages */
+    if (pixmap)
+       xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height);
+    if (shapemask)
+       xpmCreateImageFromPixmap(display, shapemask, &shapeimage,
+                                &width, &height);
+
+    /* create the related XpmImage */
+    ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage,
+                                            xpmimage, attributes);
+
+    /* destroy the ximages */
+    if (ximage)
+       XDestroyImage(ximage);
+    if (shapeimage)
+       XDestroyImage(shapeimage);
+
+    return (ErrorStatus);
+}
+
+# endif/* not AMIGA */
+#endif /* ndef FOR_MSW */
diff --git a/src/simx.c b/src/simx.c
new file mode 100644 (file)
index 0000000..97b3b5f
--- /dev/null
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* simx.c: 0.1a                                                                *
+*                                                                             *
+* This emulates some Xlib functionality for MSW. It's not a general solution, *
+* it is close related to XPM-lib. It is only intended to satisfy what is need *
+* there. Thus allowing to read XPM files under MS windows.                    *
+*                                                                             *
+* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)                           *
+\*****************************************************************************/
+
+#ifdef FOR_MSW
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include "xpm.h"
+#include "xpmi.h"                      /* for XpmMalloc */
+
+/*
+ * On DOS size_t is only 2 bytes, thus malloc(size_t s) can only malloc
+ * 64K. BUT an expression data=malloc(width*height) may result in an
+ * overflow. So this function takes a long as input, and returns NULL if the
+ * request is larger than 64K, is size_t is only 2 bytes.
+ *
+ * This requires casts like XpmMalloc( (long)width*(long(height)), else it
+ * might have no effect at all.
+ */
+
+void *
+boundCheckingMalloc(long s)
+{
+    if (sizeof(size_t) == sizeof(long)) {      /* same size, just do it */
+       return (malloc((size_t) s));
+    } else {
+       if (sizeof(size_t) == 2) {
+           if (s > 0xFFFF)
+               return (NULL);          /* to large, size_t with 2 bytes
+                                        * only allows 16 bits */
+           else
+               return (malloc((size_t) s));
+       } else {                        /* it's not a long, not 2 bytes,
+                                        * what is it ??? */
+           return (malloc((size_t) s));
+       }
+    }
+}
+void *
+boundCheckingCalloc(long num, long s)
+{
+    if (sizeof(size_t) == sizeof(long)) {      /* same size, just do it */
+       return (calloc((size_t) num, (size_t) s));
+    } else {
+       if (sizeof(size_t) == 2) {
+           if (s > 0xFFFF || num * s > 0xFFFF)
+               return (NULL);          /* to large, size_t with 2 bytes
+                                        * only allows 16 bits */
+           else
+               return (calloc((size_t) num, (size_t) s));
+       } else {                        /* it's not a long, not 2 bytes,
+                                        * what is it ??? */
+           return (calloc((size_t) num, (size_t) s));
+       }
+    }
+}
+void *
+boundCheckingRealloc(void *p, long s)
+{
+    if (sizeof(size_t) == sizeof(long)) {      /* same size, just do it */
+       return (realloc(p, (size_t) s));
+    } else {
+       if (sizeof(size_t) == 2) {
+           if (s > 0xFFFF)
+               return (NULL);          /* to large, size_t with 2 bytes
+                                        * only allows 16 bits */
+           else
+               return (realloc(p, (size_t) s));
+       } else {                        /* it's not a long, not 2 bytes,
+                                        * what is it ??? */
+           return (realloc(p, (size_t) s));
+       }
+    }
+}
+
+/* static Visual theVisual = { 0 }; */
+Visual *
+XDefaultVisual(Display *display, Screen *screen)
+{
+    return (NULL);                     /* struct could contain info about
+                                        * MONO, GRAY, COLOR */
+}
+
+Screen *
+XDefaultScreen(Display *d)
+{
+    return (NULL);
+}
+
+/* I get only 1 plane but 8 bits per pixel,
+   so I think BITSPIXEL should be depth */
+int 
+XDefaultDepth(Display *display, Screen *screen)
+{
+    int d, b;
+
+    b = GetDeviceCaps(*display, BITSPIXEL);
+    d = GetDeviceCaps(*display, PLANES);
+    return (b);
+}
+
+Colormap *
+XDefaultColormap(Display *display, Screen *screen)
+{
+    return (NULL);
+}
+
+/* convert hex color names,
+   wrong digits (not a-f,A-F,0-9) are treated as zero */
+static int 
+hexCharToInt(c)
+{
+    int r;
+
+    if (c >= '0' && c <= '9')
+       r = c - '0';
+    else if (c >= 'a' && c <= 'f')
+       r = c - 'a' + 10;
+    else if (c >= 'A' && c <= 'F')
+       r = c - 'A' + 10;
+    else
+       r = 0;
+
+    return (r);
+}
+
+static int 
+rgbFromHex(char *hex, int *r, int *g, int *b)
+{
+    int len;
+
+    if (hex == NULL || hex[0] != '#')
+       return (0);
+
+    len = strlen(hex);
+    if (len == 3 + 1) {
+       *r = hexCharToInt(hex[1]);
+       *g = hexCharToInt(hex[2]);
+       *b = hexCharToInt(hex[3]);
+    } else if (len == 6 + 1) {
+       *r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]);
+       *g = hexCharToInt(hex[3]) * 16 + hexCharToInt(hex[4]);
+       *b = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]);
+    } else if (len == 12 + 1) {
+       /* it's like c #32329999CCCC */
+       /* so for now only take two digits */
+       *r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]);
+       *g = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]);
+       *b = hexCharToInt(hex[9]) * 16 + hexCharToInt(hex[10]);
+    } else
+       return (0);
+
+    return (1);
+}
+
+/* Color related functions */
+int 
+XParseColor(Display *d, Colormap *cmap, char *name, XColor *color)
+{
+    int r, g, b;                       /* only 8 bit values used */
+    int okay;
+
+/* TODO: use colormap via PALETTE */
+    /* parse name either in table or #RRGGBB #RGB */
+    if (name == NULL)
+       return (0);
+
+    if (name[0] == '#') {              /* a hex string */
+       okay = rgbFromHex(name, &r, &g, &b);
+    } else {
+       okay = xpmGetRGBfromName(name, &r, &g, &b);
+    }
+
+    if (okay) {
+       color->pixel = RGB(r, g, b);
+       color->red = (BYTE) r;
+       color->green = (BYTE) g;
+       color->blue = (BYTE) b;
+       return (1);
+    } else
+       return (0);                     /* --> ColorError */
+}
+
+
+int 
+XAllocColor(Display *d, Colormap cmap, XColor *color)
+{
+/* colormap not used yet so color->pixel is the real COLORREF (RBG) and not an
+   index in some colormap as in X */
+    return (1);
+}
+void 
+XQueryColors(Display *display, Colormap *colormap,
+            XColor *xcolors, int ncolors)
+{
+/* under X this fills the rgb values to given .pixel */
+/* since there no colormap use FOR_MSW (not yet!!), rgb is plain encoded */
+    XColor *xc = xcolors;
+    int i;
+
+    for (i = 0; i < ncolors; i++, xc++) {
+       xc->red = GetRValue(xc->pixel);
+       xc->green = GetGValue(xc->pixel);
+       xc->blue = GetBValue(xc->pixel);
+    }
+    return;
+}
+int 
+XFreeColors(Display *d, Colormap cmap,
+           unsigned long pixels[], int npixels, unsigned long planes)
+{
+    /* no colormap yet */
+    return (0);                                /* correct ??? */
+}
+
+/* XImage functions */
+XImage *
+XCreateImage(Display *d, Visual *v,
+            int depth, int format,
+            int x, int y, int width, int height,
+            int pad, int foo)
+{
+    XImage *img = (XImage *) XpmMalloc(sizeof(XImage));
+
+    if (img) {
+       /*JW: This is what it should be, but the picture comes out
+             just black!?  It appears to be doing monochrome reduction,
+             but I've got no clue why.  Using CreateBitmap() is supposed
+             to be slower, but otherwise ok
+         if ( depth == GetDeviceCaps(*d, BITSPIXEL) ) {
+           img->bitmap = CreateCompatibleBitmap(*d, width, height);
+        } else*/ {
+           img->bitmap = CreateBitmap(width, height, 1 /* plane */ ,
+                                      depth /* bits per pixel */ , NULL);
+       }
+       img->width = width;
+       img->height = height;
+       img->depth = depth;
+    }
+    return (img);
+
+}
+
+void 
+XImageFree(XImage *img)
+{
+    if (img) {
+       XpmFree(img);
+    }
+}
+void 
+XDestroyImage(XImage *img)
+{
+    if (img) {
+       DeleteObject(img->bitmap);      /* check return ??? */
+       XImageFree(img);
+    }
+}
+
+#endif
diff --git a/src/simx.h b/src/simx.h
new file mode 100644 (file)
index 0000000..7c4c4b9
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* simx.h: 0.1a                                                                *
+*                                                                             *
+* This emulates some Xlib functionality for MSW. It's not a general solution, *
+* it is close related to XPM-lib. It is only intended to satisfy what is need *
+* there. Thus allowing to read XPM files under MS windows.                    *
+*                                                                             *
+* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de)                           *
+\*****************************************************************************/
+
+
+#ifndef _SIMX_H
+#define _SIMX_H
+
+#ifdef FOR_MSW
+
+#include "windows.h"                   /* MS windows GDI types */
+#define _XFUNCPROTOBEGIN
+#define _XFUNCPROTOEND
+#define NO_ZPIPE
+
+/*
+ * minimal portability layer between ansi and KR C
+ */
+/* this comes from xpm.h, and is here again, to avoid complicated
+    includes, since this is included from xpm.h */
+/* these defines get undefed at the end of this file */
+#if __STDC__ || defined(__cplusplus) || defined(c_plusplus)
+ /* ANSI || C++ */
+#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
+
+
+FUNC(boundCheckingMalloc, void *, (long s));
+FUNC(boundCheckingCalloc, void *, (long num, long s));
+FUNC(boundCheckingRealloc, void *, (void *p, long s));
+
+/* define MSW types for X window types,
+   I don't know much about MSW, but the following defines do the job */
+
+typedef HDC Display;                   /* this should be similar */
+typedef void *Screen;                  /* not used */
+typedef void *Visual;                  /* not used yet, is for GRAY, COLOR,
+                                        * MONO */
+
+typedef void *Colormap;                        /* should be COLORPALETTE, not done
+                                        * yet */
+
+typedef COLORREF Pixel;
+
+#define PIXEL_ALREADY_TYPEDEFED                /* to let xpm.h know about it */
+
+typedef struct {
+    Pixel pixel;
+    BYTE red, green, blue;
+}      XColor;
+
+typedef struct {
+    HBITMAP bitmap;
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+}      XImage;
+
+#if defined(__cplusplus) || defined(c_plusplus)
+extern "C" {
+#endif
+/* some replacements for X... functions */
+
+/* XDefaultXXX */
+    FUNC(XDefaultVisual, Visual *, (Display *display, Screen *screen));
+    FUNC(XDefaultScreen, Screen *, (Display *d));
+    FUNC(XDefaultColormap, Colormap *, (Display *display, Screen *screen));
+    FUNC(XDefaultDepth, int, (Display *d, Screen *s));
+
+/* color related */
+    FUNC(XParseColor, int, (Display *, Colormap *, char *, XColor *));
+    FUNC(XAllocColor, int, (Display *, Colormap, XColor *));
+    FUNC(XQueryColors, void, (Display *display, Colormap *colormap,
+                             XColor *xcolors, int ncolors));
+    FUNC(XFreeColors, int, (Display *d, Colormap cmap,
+                           unsigned long pixels[],
+                           int npixels, unsigned long planes));
+/* XImage */
+    FUNC(XCreateImage, XImage *, (Display *, Visual *, int depth, int format,
+                                 int x, int y, int width, int height,
+                                 int pad, int foo));
+
+/* free and destroy bitmap */
+    FUNC(XDestroyImage, void /* ? */ , (XImage *));
+/* free only, bitmap remains */
+    FUNC(XImageFree, void, (XImage *));
+#if defined(__cplusplus) || defined(c_plusplus)
+} /* end of extern "C" */
+#endif /* cplusplus */
+
+#define ZPixmap 1                      /* not really used */
+#define XYBitmap 1                     /* not really used */
+
+#ifndef True
+#define True 1
+#define False 0
+#endif
+#ifndef Bool
+typedef BOOL Bool;             /* take MSW bool */
+#endif
+/* make these local here, simx.c gets the same from xpm.h */
+#undef LFUNC
+#undef FUNC
+
+/* Some functions and constants that have non-standard names in the
+   MS library.  */
+#define bzero(addr,sz) memset(addr, 0, sz)
+#define close _close
+#define fdopen _fdopen
+#define index strchr
+#define open _open
+#define O_RDONLY _O_RDONLY
+#define rindex strrchr
+#define strdup _strdup
+
+
+#endif /* def FOR_MSW */
+
+#endif /* _SIMX_H */
diff --git a/sxpm/Makefile.am b/sxpm/Makefile.am
new file mode 100755 (executable)
index 0000000..3e718da
--- /dev/null
@@ -0,0 +1,41 @@
+if BUILD_SXPM
+
+bin_PROGRAMS = sxpm
+
+AM_CPPFLAGS = -I$(top_srcdir)/include
+AM_CFLAGS = $(CWARNFLAGS) $(SXPM_CFLAGS)
+AM_LDFLAGS = $(XPM_LIBS)
+
+sxpm_SOURCES = sxpm.c
+
+LDADD = $(SXPM_LIBS) $(top_builddir)/src/libXpm.la
+
+# Man page
+appmandir = $(APP_MAN_DIR)
+
+appman_PRE = sxpm.man
+appman_DATA = $(appman_PRE:man=@APP_MAN_SUFFIX@)
+
+CLEANFILES = $(appman_DATA)
+
+SUFFIXES = .$(APP_MAN_SUFFIX) .man
+
+# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure
+.man.$(APP_MAN_SUFFIX):
+       $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@
+
+if USE_GETTEXT
+noinst_DATA = sxpm.po
+
+sxpm.po: $(sxpm_SOURCES:%=$(srcdir)/%)
+       $(AM_V_GEN)xgettext -c"L10N_Comments" -d sxpm -n $(sxpm_SOURCES:%=$(srcdir)/%)
+
+CLEANFILES += sxpm.po
+endif
+endif
+
+EXTRA_DIST = \
+       plaid_ext.xpm \
+       plaid_mask.xpm \
+       plaid.xpm \
+       sxpm.man
diff --git a/sxpm/plaid.xpm b/sxpm/plaid.xpm
new file mode 100644 (file)
index 0000000..b0e9200
--- /dev/null
@@ -0,0 +1,34 @@
+/* XPM */
+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 green    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 "
+} ;
diff --git a/sxpm/plaid_ext.xpm b/sxpm/plaid_ext.xpm
new file mode 100644 (file)
index 0000000..8538952
--- /dev/null
@@ -0,0 +1,43 @@
+/* XPM */
+static char * plaid[] = {
+/* plaid pixmap 
+ * width height ncolors chars_per_pixel */
+"22 22 4 2 XPMEXT",
+/* colors */
+"   c red      m white  s light_color ",
+"Y  c green    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 ",
+"XPMEXT ext1 data1",
+"XPMEXT ext2",
+"data2_1",
+"data2_2",
+"XPMEXT ext3",
+"data3",
+"XPMEXT",
+"data4",
+"XPMENDEXT"
+} ;
diff --git a/sxpm/plaid_mask.xpm b/sxpm/plaid_mask.xpm
new file mode 100644 (file)
index 0000000..167d338
--- /dev/null
@@ -0,0 +1,35 @@
+/* XPM */
+static char * plaid[] = {
+/* plaid pixmap 
+ * width height ncolors chars_per_pixel */
+"22 22 5 2",
+/* colors */
+".  c red      m white  s light_color ",
+"Y  c green    m black  s lines_in_mix ",
+"+  c yellow   m white  s lines_in_dark ",
+"x             m black  s dark_color ",
+"   c none              s mask ",
+/* 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 ", 
+"            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 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 "
+} ;
diff --git a/sxpm/sxpm.c b/sxpm/sxpm.c
new file mode 100755 (executable)
index 0000000..ea4dde3
--- /dev/null
@@ -0,0 +1,750 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* sxpm.c:                                                                     *
+*                                                                             *
+*  Show XPM File program                                                      *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <X11/StringDefs.h>
+#include <X11/Intrinsic.h>
+#include <X11/IntrinsicP.h>
+#include <X11/Shell.h>
+
+#ifdef VMS
+#include <X11/shape.h>
+#else
+#include <X11/extensions/shape.h>
+#endif
+
+#include <X11/xpm.h>
+
+#ifdef USE_GETTEXT
+#include <locale.h>
+#include <libintl.h>
+#else
+#define gettext(a) (a)
+#endif
+
+/* XPM */
+/* plaid pixmap */
+static char *plaid[] = {
+    /* width height ncolors chars_per_pixel */
+    "22 22 4 2 XPMEXT",
+    /* colors */
+    "   c red  m white  s light_color",
+    "Y  c green        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 ",
+    "bullshit",
+    "XPMEXT ext1 data1",
+    "XPMEXT ext2",
+    "data2_1",
+    "data2_2",
+    "XPMEXT",
+    "foo",
+    "",
+    "XPMEXT ext3",
+    "data3",
+    "XPMENDEXT"
+};
+
+#define win XtWindow(topw)
+#define dpy XtDisplay(topw)
+#define root XRootWindowOfScreen(XtScreen(topw))
+#define xrdb XtDatabase(dpy)
+static Colormap colormap;
+
+void Usage(void);
+void ErrorMessage(int ErrorStatus, char *tag);
+void Punt(int i);
+void VersionInfo(void);
+void kinput(Widget widget, char *tag, XEvent *xe, Boolean *b);
+void GetNumbers(int num, int *format_return,
+               int *libmajor_return,
+               char *libminor_return);
+
+#define IWIDTH      50
+#define IHEIGHT     50
+
+typedef struct _XpmIcon {
+    Pixmap pixmap;
+    Pixmap mask;
+    XpmAttributes attributes;
+}        XpmIcon;
+
+static char **command;
+static Widget topw;
+static XpmIcon view, icon;
+static XrmOptionDescRec options[] = {
+    {"-hints", ".hints", XrmoptionNoArg, (XtPointer) "True"},
+    {"-icon", ".icon", XrmoptionSepArg, (XtPointer) NULL},
+};
+
+int
+main(
+    int                  argc,
+    char       **argv)
+{
+    int ErrorStatus;
+    unsigned int verbose = 0;          /* performs verbose output */
+    unsigned int stdinf = 1;           /* read from stdin */
+    unsigned int stdoutf = 0;          /* write to stdout */
+    unsigned int nod = 0;              /* no display */
+    unsigned int nom = 0;              /* no mask display */
+    unsigned int incResize = 0;
+    unsigned int resize = 0;
+    unsigned int w_rtn;
+    unsigned int h_rtn;
+    char *input = NULL;
+    char *output = NULL;
+    char *iconFile = NULL;
+    unsigned int numsymbols = 0;
+    XpmColorSymbol symbols[10];
+    char *stype;
+    XrmValue val;
+    unsigned long valuemask = 0;
+    int n;
+    Arg args[4];
+
+#ifdef Debug
+    char **data;
+    char *buffer;
+#endif
+
+#ifdef USE_GETTEXT
+    XtSetLanguageProc(NULL,NULL,NULL);
+    bindtextdomain("sxpm",LOCALEDIR);
+    textdomain("sxpm");
+#endif
+
+    topw = XtInitialize(argv[0], "Sxpm",
+                       options, XtNumber(options), &argc, argv);
+
+    if (!topw) {
+       /* L10N_Comments : Error if no $DISPLAY or $DISPLAY can't be opened.
+          Not normally reached as Xt exits before we get here. */
+       fprintf(stderr, gettext("Sxpm Error... [ Undefined DISPLAY ]\n"));
+       exit(1);
+    }
+    colormap = XDefaultColormapOfScreen(XtScreen(topw));
+
+    /*
+     * geometry management
+     */
+
+    if (XrmGetResource(xrdb, NULL, "sxpm.geometry", &stype, &val)
+       || XrmGetResource(xrdb, NULL, "Sxpm.geometry", &stype, &val)) {
+
+       int flags;
+       int x_rtn;
+       int y_rtn;
+       char *geo = NULL;
+
+       geo = (char *) val.addr;
+       flags = XParseGeometry(geo, &x_rtn, &y_rtn,
+                              (unsigned int *) &w_rtn,
+                              (unsigned int *) &h_rtn);
+
+       if (!((WidthValue & flags) && (HeightValue & flags)))
+           resize = 1;
+
+    } else
+       resize = 1;
+
+    n = 0;
+    if (resize) {
+       w_rtn = 0;
+       h_rtn = 0;
+       XtSetArg(args[n], XtNwidth, 1);
+       n++;
+       XtSetArg(args[n], XtNheight, 1);
+       n++;
+    }
+    XtSetArg(args[n], XtNmappedWhenManaged, False);
+    n++;
+    XtSetArg(args[n], XtNinput, True);
+    n++;
+    XtSetValues(topw, args, n);
+
+    if ((XrmGetResource(xrdb, "sxpm.hints", "", &stype, &val)
+        || XrmGetResource(xrdb, "Sxpm.hints", "", &stype, &val))
+       && !strcmp((char *) val.addr, "True")) {
+       /* gotcha */
+       incResize = 1;
+       resize = 1;
+    }
+
+    /*
+     * icon management
+     */
+
+    if (XrmGetResource(xrdb, "sxpm.icon", "", &stype, &val)
+       || XrmGetResource(xrdb, "Sxpm.icon", "", &stype, &val)) {
+       iconFile = (char *) val.addr;
+    }
+    if (iconFile) {
+
+       XColor color, junk;
+       Pixel bpix;
+       Window iconW;
+
+       if (XAllocNamedColor(dpy, colormap, "black", &color, &junk))
+           bpix = color.pixel;
+       else
+           bpix = XBlackPixelOfScreen(XtScreen(topw));
+
+       iconW = XCreateSimpleWindow(dpy, root, 0, 0,
+                                   IWIDTH, IHEIGHT, 1, bpix, bpix);
+
+       icon.attributes.valuemask = XpmReturnAllocPixels;
+       ErrorStatus = XpmReadFileToPixmap(dpy, root, iconFile, &icon.pixmap,
+                                         &icon.mask, &icon.attributes);
+       ErrorMessage(ErrorStatus, "Icon");
+
+       XSetWindowBackgroundPixmap(dpy, iconW, icon.pixmap);
+
+       n = 0;
+       XtSetArg(args[n], XtNbackground, bpix);
+       n++;
+       XtSetArg(args[n], XtNiconWindow, iconW);
+       n++;
+       XtSetValues(topw, args, n);
+    }
+
+    /*
+     * arguments parsing
+     */
+
+    command = argv;
+    for (n = 1; n < argc; n++) {
+       if (strcmp(argv[n], "-plaid") == 0) {
+           stdinf = 0;
+           continue;
+       }
+       if (argv[n][0] != '-') {
+           stdinf = 0;
+           input = argv[n];
+           continue;
+       }
+       if ((strlen(argv[n]) == 1) && (argv[n][0] == '-'))
+           /* stdin */
+           continue;
+       if (strcmp(argv[n], "-o") == 0) {
+           if (n < argc - 1) {
+               if ((strlen(argv[n + 1]) == 1) && (argv[n + 1][0] == '-'))
+                   stdoutf = 1;
+               else
+                   output = argv[n + 1];
+               n++;
+               continue;
+           } else
+               Usage();
+       }
+       if (strcmp(argv[n], "-nod") == 0) {
+           nod = 1;
+           continue;
+       }
+       if (strcmp(argv[n], "-nom") == 0) {
+           nom = 1;
+           continue;
+       }
+       if (strcmp(argv[n], "-sc") == 0) {
+           if (n < argc - 2) {
+               valuemask |= XpmColorSymbols;
+               symbols[numsymbols].name = argv[++n];
+               symbols[numsymbols++].value = argv[++n];
+               continue;
+           } else
+               Usage();
+       }
+       if (strcmp(argv[n], "-sp") == 0) {
+           if (n < argc - 2) {
+               valuemask |= XpmColorSymbols;
+               symbols[numsymbols].name = argv[++n];
+               symbols[numsymbols].value = NULL;
+               symbols[numsymbols++].pixel = atol(argv[++n]);
+               continue;
+           }
+       }
+       if (strcmp(argv[n], "-cp") == 0) {
+           if (n < argc - 2) {
+               valuemask |= XpmColorSymbols;
+               symbols[numsymbols].name = NULL;
+               symbols[numsymbols].value = argv[++n];
+               symbols[numsymbols++].pixel = atol(argv[++n]);
+               continue;
+           }
+       }
+       if (strcmp(argv[n], "-mono") == 0) {
+           valuemask |= XpmColorKey;
+           view.attributes.color_key = XPM_MONO;
+           continue;
+       }
+       if (strcmp(argv[n], "-gray4") == 0 || strcmp(argv[n], "-grey4") == 0) {
+           valuemask |= XpmColorKey;
+           view.attributes.color_key = XPM_GRAY4;
+           continue;
+       }
+       if (strcmp(argv[n], "-gray") == 0 || strcmp(argv[n], "-grey") == 0) {
+           valuemask |= XpmColorKey;
+           view.attributes.color_key = XPM_GRAY;
+           continue;
+       }
+       if (strcmp(argv[n], "-color") == 0) {
+           valuemask |= XpmColorKey;
+           view.attributes.color_key = XPM_COLOR;
+           continue;
+       }
+       if (strncmp(argv[n], "-closecolors", 6) == 0) {
+           valuemask |= XpmCloseness;
+           view.attributes.closeness = 40000;
+           continue;
+       }
+       if (strcmp(argv[n], "-rgb") == 0) {
+           if (n < argc - 1) {
+               valuemask |= XpmRgbFilename;
+               view.attributes.rgb_fname = argv[++n];
+               continue;
+           } else
+               Usage();
+
+       }
+       if (strncmp(argv[n], "-version", 4) == 0) {
+           VersionInfo();
+           exit(0);
+       }
+       if (strcmp(argv[n], "-v") == 0) {
+           verbose = 1;
+           continue;
+       }
+       if (strcmp(argv[n], "-pcmap") == 0) {
+           valuemask |= XpmColormap;
+           continue;
+       }
+       Usage();
+    }
+
+    XtRealizeWidget(topw);
+    if (valuemask & XpmColormap) {
+       colormap = XCreateColormap(dpy, win,
+                                  DefaultVisual(dpy, DefaultScreen(dpy)),
+                                  AllocNone);
+       view.attributes.colormap = colormap;
+       XSetWindowColormap(dpy, win, colormap);
+    }
+    view.attributes.colorsymbols = symbols;
+    view.attributes.numsymbols = numsymbols;
+    view.attributes.valuemask = valuemask;
+
+#ifdef Debug
+    /* this is just to test the XpmCreateDataFromPixmap function */
+
+    view.attributes.valuemask |= XpmReturnAllocPixels;
+    view.attributes.valuemask |= XpmReturnExtensions;
+    ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid,
+                                         &view.pixmap, &view.mask,
+                                         &view.attributes);
+    ErrorMessage(ErrorStatus, "Plaid");
+
+    ErrorStatus = XpmCreateDataFromPixmap(dpy, &data, view.pixmap, view.mask,
+                                         &view.attributes);
+    ErrorMessage(ErrorStatus, "Data");
+    if (verbose && view.attributes.nextensions) {
+       unsigned int i, j;
+
+       for (i = 0; i < view.attributes.nextensions; i++) {
+           fprintf(stderr, "Xpm extension : %s\n",
+                   view.attributes.extensions[i].name);
+           for (j = 0; j < view.attributes.extensions[i].nlines; j++)
+               fprintf(stderr, "\t\t%s\n",
+                       view.attributes.extensions[i].lines[j]);
+       }
+    }
+    XFreePixmap(dpy, view.pixmap);
+    if (view.mask)
+       XFreePixmap(dpy, view.mask);
+
+    XFreeColors(dpy, colormap,
+               view.attributes.alloc_pixels,
+               view.attributes.nalloc_pixels, 0);
+
+    XpmFreeAttributes(&view.attributes);
+    view.attributes.valuemask = valuemask;
+#endif
+
+    if (input || stdinf) {
+       view.attributes.valuemask |= XpmReturnInfos;
+       view.attributes.valuemask |= XpmReturnAllocPixels;
+       view.attributes.valuemask |= XpmReturnExtensions;
+
+#ifdef Debug
+       XpmFree(data);
+
+       /*
+        * this is just to test the XpmCreatePixmapFromBuffer and
+        * XpmCreateBufferFromPixmap functions
+        */
+       ErrorStatus = XpmReadFileToBuffer(input, &buffer);
+       ErrorMessage(ErrorStatus, "CreateBufferFromFile");
+
+       ErrorStatus = XpmCreatePixmapFromBuffer(dpy, win, buffer,
+                                               &view.pixmap, &view.mask,
+                                               &view.attributes);
+       ErrorMessage(ErrorStatus, "CreatePixmapFromBuffer");
+       XpmFree(buffer);
+       ErrorStatus = XpmCreateBufferFromPixmap(dpy, &buffer,
+                                               view.pixmap, view.mask,
+                                               &view.attributes);
+       ErrorMessage(ErrorStatus, "CreateBufferFromPixmap");
+       ErrorStatus = XpmWriteFileFromBuffer("buffer_output", buffer);
+       ErrorMessage(ErrorStatus, "WriteFileFromBuffer");
+       XpmFree(buffer);
+       if (view.pixmap) {
+           XFreePixmap(dpy, view.pixmap);
+           if (view.mask)
+               XFreePixmap(dpy, view.mask);
+
+           XFreeColors(dpy, colormap, view.attributes.alloc_pixels,
+                       view.attributes.nalloc_pixels, 0);
+
+           XpmFreeAttributes(&view.attributes);
+       }
+       ErrorStatus = XpmReadFileToData(input, &data);
+       ErrorMessage(ErrorStatus, "ReadFileToData");
+       ErrorStatus = XpmCreatePixmapFromData(dpy, win, data,
+                                             &view.pixmap, &view.mask,
+                                             &view.attributes);
+       ErrorMessage(ErrorStatus, "CreatePixmapFromData");
+       ErrorStatus = XpmWriteFileFromData("sxpmout.xpm", data);
+       ErrorMessage(ErrorStatus, "WriteFileFromData");
+       XpmFree(data);
+       XpmFreeAttributes(&view.attributes);
+#endif
+       ErrorStatus = XpmReadFileToPixmap(dpy, win, input,
+                                         &view.pixmap, &view.mask,
+                                         &view.attributes);
+       ErrorMessage(ErrorStatus, "Read");
+       if (verbose && view.attributes.nextensions) {
+           unsigned int i, j;
+
+           for (i = 0; i < view.attributes.nextensions; i++) {
+               /* L10N_Comments : Output when -v & file has extensions 
+                  %s is replaced by extension name */
+               fprintf(stderr, gettext("Xpm extension : %s\n"),
+                       view.attributes.extensions[i].name);
+               for (j = 0; j < view.attributes.extensions[i].nlines; j++)
+                   fprintf(stderr, "\t\t%s\n",
+                           view.attributes.extensions[i].lines[j]);
+           }
+       }
+    } else {
+#ifdef Debug
+       ErrorStatus = XpmCreatePixmapFromData(dpy, win, data,
+                                             &view.pixmap, &view.mask,
+                                             &view.attributes);
+       XpmFree(data);
+#else
+       ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid,
+                                             &view.pixmap, &view.mask,
+                                             &view.attributes);
+#endif
+       ErrorMessage(ErrorStatus, "Plaid");
+    }
+    if (output || stdoutf) {
+       ErrorStatus = XpmWriteFileFromPixmap(dpy, output, view.pixmap,
+                                            view.mask, &view.attributes);
+       ErrorMessage(ErrorStatus, "Write");
+    }
+    if (!nod) {
+
+       /*
+        * manage display if requested
+        */
+
+       XSizeHints size_hints;
+       char *xString = NULL;
+
+       if (w_rtn && h_rtn
+           && ((w_rtn < view.attributes.width)
+               || h_rtn < view.attributes.height)) {
+           resize = 1;
+       }
+       if (resize) {
+           XtResizeWidget(topw,
+                          view.attributes.width, view.attributes.height, 1);
+       }
+       if (incResize) {
+           size_hints.flags = USSize | PMinSize | PResizeInc;
+           size_hints.height = view.attributes.height;
+           size_hints.width = view.attributes.width;
+           size_hints.height_inc = view.attributes.height;
+           size_hints.width_inc = view.attributes.width;
+       } else
+           size_hints.flags = PMinSize;
+
+       size_hints.min_height = view.attributes.height;
+       size_hints.min_width = view.attributes.width;
+       XSetWMNormalHints(dpy, win, &size_hints);
+
+       if (input) {
+           xString = (char *) XtMalloc((sizeof(char) * strlen(input)) + 20);
+           sprintf(xString, "Sxpm: %s", input);
+           XStoreName(dpy, win, xString);
+           XSetIconName(dpy, win, xString);
+       } else if (stdinf) {
+           XStoreName(dpy, win, "Sxpm: stdin");
+           XSetIconName(dpy, win, "Sxpm: stdin");
+       } else {
+           XStoreName(dpy, win, "Sxpm");
+           XSetIconName(dpy, win, "Sxpm");
+       }
+
+       XtAddEventHandler(topw, KeyPressMask, False,
+                         (XtEventHandler) kinput, NULL);
+       XSetWindowBackgroundPixmap(dpy, win, view.pixmap);
+
+       if (view.mask && !nom)
+           XShapeCombineMask(dpy, win, ShapeBounding, 0, 0,
+                             view.mask, ShapeSet);
+
+       XClearWindow(dpy, win);
+       XtMapWidget(topw);
+       if (xString)
+           XtFree(xString);
+       XtMainLoop();
+    }
+    Punt(0);
+
+    /* Muffle gcc */
+    return 0;
+}
+
+void
+Usage(void)
+{
+    /* L10N_Comments : Usage message (sxpm -h) in two parts. 
+       In the first part %s is replaced by the command name. */
+    fprintf(stderr, gettext("\nUsage:  %s [options...]\n"), command[0]);
+    fprintf(stderr, gettext("Where options are:\n\
+\n\
+[-d host:display]            Display to connect to.\n\
+[-g geom]                    Geometry of window.\n\
+[-hints]                     Set ResizeInc for window.\n\
+[-icon filename]             Set pixmap for iconWindow.\n\
+[-plaid]                     Read the included plaid pixmap.\n\
+[filename]                   Read from file 'filename', and from standard\n\
+                             input if 'filename' is '-'.\n\
+[-o filename]                Write to file 'filename', and to standard\n\
+                             output if 'filename' is '-'.\n\
+[-pcmap]                     Use a private colormap.\n\
+[-closecolors]               Try to use `close' colors.\n\
+[-nod]                       Don't display in window.\n\
+[-nom]                       Don't use clip mask if any.\n\
+[-mono]                      Use the colors specified for a monochrome visual.\n\
+[-grey4]                     Use the colors specified for a 4 greyscale visual.\n\
+[-grey]                      Use the colors specified for a greyscale visual.\n\
+[-color]                     Use the colors specified for a color visual.\n\
+[-sc symbol color]           Override color defaults.\n\
+[-sp symbol pixel]           Override color defaults.\n\
+[-cp color pixel]            Override color defaults.\n\
+[-rgb filename]              Search color names in the rgb text file 'filename'.\n\
+[-v]                         Verbose - print out extensions.\n\
+[-version]                   Print out program's version number\n\
+                             and library's version number if different.\n\
+if no input is specified sxpm reads from standard input.\n\
+\n"));
+    exit(0);
+}
+
+
+void
+ErrorMessage(
+    int                 ErrorStatus,
+    char       *tag)
+{
+    char *error = NULL;
+    char *warning = NULL;
+
+    switch (ErrorStatus) {
+    case XpmSuccess:
+       return;
+    case XpmColorError:
+/* L10N_Comments : The following set of messages are classified as 
+   either errors or warnings.  Based on the class of message, different
+   wrappers are selected at the end to state the message source & class. 
+
+          L10N_Comments : WARNING produced when filename can be read, but
+          contains an invalid color specification (need to create test case)*/
+       warning = gettext("Could not parse or alloc requested color");
+       break;
+    case XpmOpenFailed:
+       /* L10N_Comments : ERROR produced when filename does not exist 
+          or insufficient permissions to open (i.e. sxpm /no/such/file ) */
+       error = gettext("Cannot open file");
+       break;
+    case XpmFileInvalid:
+       /* L10N_Comments : ERROR produced when filename can be read, but
+          is not an XPM file (i.e. sxpm /dev/null ) */
+       error = gettext("Invalid XPM file");
+       break;
+    case XpmNoMemory:
+       /* L10N_Comments : ERROR produced when filename can be read, but
+          is too big for memory 
+          (i.e. limit datasize 32 ; sxpm /usr/dt/backdrops/Crochet.pm ) */
+       error = gettext("Not enough memory");
+       break;
+    case XpmColorFailed:
+       /* L10N_Comments : ERROR produced when filename can be read, but
+          contains an invalid color specification (need to create test case)*/
+       error = gettext("Failed to parse or alloc some color");
+       break;
+    }
+
+    if (warning)
+       /* L10N_Comments : Wrapper around above WARNING messages.
+          First %s is the tag for the operation that produced the warning.
+          Second %s is the message selected from the above set. */
+       fprintf(stderr, gettext("%s Xpm Warning: %s.\n"), tag, warning);
+
+    if (error) {
+       /* L10N_Comments : Wrapper around above ERROR messages.
+          First %s is the tag for the operation that produced the error.
+          Second %s is the message selected from the above set */
+       fprintf(stderr, gettext("%s Xpm Error: %s.\n"), tag, error);
+       Punt(1);
+    }
+}
+
+void
+Punt(int i)
+{
+    if (icon.pixmap) {
+       XFreePixmap(dpy, icon.pixmap);
+       if (icon.mask)
+           XFreePixmap(dpy, icon.mask);
+
+       XFreeColors(dpy, colormap,
+                   icon.attributes.alloc_pixels,
+                   icon.attributes.nalloc_pixels, 0);
+
+       XpmFreeAttributes(&icon.attributes);
+    }
+    if (view.pixmap) {
+       XFreePixmap(dpy, view.pixmap);
+       if (view.mask)
+           XFreePixmap(dpy, view.mask);
+
+       XFreeColors(dpy, colormap,
+                   view.attributes.alloc_pixels,
+                   view.attributes.nalloc_pixels, 0);
+
+       XpmFreeAttributes(&view.attributes);
+    }
+    exit(i);
+}
+
+void
+kinput(
+    Widget      widget,
+    char       *tag,
+    XEvent     *xe,
+    Boolean    *b)
+{
+    char c = '\0';
+
+    XLookupString(&(xe->xkey), &c, 1, NULL, NULL);
+    if (c == 'q' || c == 'Q')
+       Punt(0);
+}
+
+/*
+ * small function to extract various version numbers from the given global
+ * number (following the rule described in xpm.h).
+ */
+void
+GetNumbers(
+    int                 num,
+    int                *format_return,
+    int                *libmajor_return,
+    char       *libminor_return)
+{
+    *format_return = num / 10000;
+    *libmajor_return = (num % 10000) / 100;
+    *libminor_return = 'a' + (num % 10000) % 100 - 1;
+}
+
+void
+VersionInfo(void)
+{
+    int format, libmajor;
+    char libminor;
+
+    GetNumbers(XpmIncludeVersion, &format, &libmajor, &libminor);
+    /* L10N_Comments : sxpm -version output */
+    fprintf(stderr, gettext("sxpm version: %d.%d%c\n"),
+           format, libmajor, libminor);
+    /* L10N_Comments :
+     * if we are linked to an XPM library different from the one we've been
+     * compiled with, print its own number too when sxpm -version is called.
+     */
+    if (XpmIncludeVersion != XpmLibraryVersion()) {
+       GetNumbers(XpmLibraryVersion(), &format, &libmajor, &libminor);
+       fprintf(stderr, gettext("using the XPM library version: %d.%d%c\n"),
+               format, libmajor, libminor);
+    }
+}
diff --git a/sxpm/sxpm.man b/sxpm/sxpm.man
new file mode 100755 (executable)
index 0000000..49cf306
--- /dev/null
@@ -0,0 +1,131 @@
+.\"Copyright (C) 1989-95 GROUPE BULL
+.\"
+.\"Permission is hereby granted, free of charge, to any person obtaining a copy
+.\"of this software and associated documentation files (the "Software"), to
+.\"deal in the Software without restriction, including without limitation the
+.\"rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+.\"sell copies of the Software, and to permit persons to whom the Software is
+.\"furnished to do so, subject to the following conditions:
+.\"
+.\"The above copyright notice and this permission notice shall be included in
+.\"all copies or substantial portions of the Software.
+.\"
+.\"THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+.\"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+.\"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+.\"GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+.\"AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+.\"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+.\"
+.\"Except as contained in this notice, the name of GROUPE BULL shall not be
+.\"used in advertising or otherwise to promote the sale, use or other dealings
+.\"in this Software without prior written authorization from GROUPE BULL.
+.\"
+.nr )S 12
+.TH SXPM 1
+.PD
+.ad b
+.SH NAME
+sxpm \- Show an XPM (X PixMap) file and/or convert XPM 1 or 2 files to XPM 3.
+.SH SYNOPSIS
+\fBsxpm\fR
+[\|\fB-d\fR displayname\|] 
+[\|\fB-g\fR geometry\|] 
+[\|\fB-hints\fR\|] 
+[\|\fB-icon\fR filename\|] 
+[\|\fB-plaid\| | \|\fRfilename\| | \|-\|]
+[\|\fB-o\fR filename\| | \|\fB-o\fR -\|] 
+[\|\fB-pcmap\fR\|] 
+[\|\fB-closecolors\fR\|] 
+[\|\fB-nod\fR\|] 
+[\|\fB-nom\fR\|] 
+[\|\fB-mono | -grey4 | -grey | -color\fR\|] 
+[\|\fB-sc\fR symbol color\|] 
+[\|\fB-sp\fR symbol pixel\|] 
+[\|\fB-cp\fR color pixel\|] 
+[\|\fB-rgb\fR filename\|] 
+[\|\fB-v\fR\|] 
+.SH DESCRIPTION
+.PP
+The \fIsxpm\fP program can be used to view any XPM (version 1, 2, or 3) file
+and/or to convert a file from XPM1 or XPM2 to XPM version 3. If \fIsxpm\fP is
+run with any dummy option specified, the usage is displayed. If no geometry is
+specified, the show window will have the size of the read pixmap. Pressing the
+key Q in the window will quit the program.
+.SH OPTIONS
+.TP 8
+.B \-d \fIdisplay\fP
+Specifies the display to connect to.
+.TP 8
+.B \-g \fIgeom\fP
+Window geometry (default is pixmap's size).
+.TP 8
+.B \-hints
+Set ResizeInc for window.
+.TP 8
+.B \-icon \fIfilename\fP
+Set icon to pixmap created from the file \fIfilename\fP.
+.TP 8
+.B \-plaid
+Show the plaid pixmap which is stored as data\fP.
+.TP 8
+.B \fIfilename\fP
+Read from the file \fIfilename\fP and from standard input if \fIfilename\fP is '-'.
+If no input is specified sxpm reads from standard input.
+.TP 8
+.B \-o \fIfilename\fP
+Write to the file \fIfilename\fP (overwrite if it already exists) and to
+standard output if \fIfilename\fP is '-'.
+.TP 8
+.B \-mono
+Use the colors specified for a monochrome visual.
+.TP 8
+.B \-grey4
+Use the colors specified for a 4 color greyscale visual.
+.TP 8
+.B \-grey
+Use the colors specified for a greyscale visual.
+.TP 8
+.B \-color
+Use the colors specified for a color visual.
+.TP 8
+.B \-pcmap
+Use a private colormap.
+.TP 8
+.B \-closecolors
+Try to use "close colors" before reverting to other visuals.
+.TP 8
+.B \-nod
+Do not display the pixmap in a window.  (Useful when using as converter)
+.TP 8
+.B \-nom
+Do not use the clipmask if there is any.
+.TP 8
+.B \-sc \fIsymbol colorname\fP
+Override default color to \fIsymbol\fP to \fIcolorname\fP.
+.TP 8
+.B \-sp \fIsymbol pixelvalue\fP
+Override default color to \fIsymbol\fP to \fIpixelvalue\fP.
+.TP 8
+.B \-cp \fIcolorname pixelvalue\fP
+Override default color to \fIcolorname\fP to \fIpixelvalue\fP.
+.TP 8
+.B \-rgb \fIfilename\fP
+Search color names in the file \fIfilename\fP and write them out instead of
+the rgb values.
+.TP 8
+.B \-v
+Verbose - to print out extensions (stderr).
+
+
+.SH KNOWN BUGS
+Some window managers may not accept a pixmap which is not a bitmap as icon
+because this does not respect ICCCM, many of the well known ones will accept
+it though.
+
+.SH AUTHOR
+Arnaud Le Hors    (lehors@sophia.inria.fr)
+.br
+Bull Research France
+.br
+Copyright (C) 1989-95 by Groupe Bull.
diff --git a/xpm.pc.in b/xpm.pc.in
new file mode 100644 (file)
index 0000000..e7be72f
--- /dev/null
+++ b/xpm.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: Xpm
+Description: X Pixmap Library
+Version: @PACKAGE_VERSION@
+Requires: x11
+Requires.private: x11
+Cflags: -I${includedir}
+Libs: -L${libdir} -lXpm