summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES957
-rw-r--r--COPYRIGHT31
-rw-r--r--FAQ.html344
-rw-r--r--FILES68
-rw-r--r--README.AMIGA10
-rw-r--r--README.MSW127
-rw-r--r--README.html303
-rw-r--r--cxpm/cxpm.c153
-rw-r--r--cxpm/cxpm.man49
-rw-r--r--include/X11/xpm.h502
-rw-r--r--src/Attrib.c302
-rw-r--r--src/CrBufFrI.c401
-rw-r--r--src/CrBufFrP.c75
-rw-r--r--src/CrDatFrI.c341
-rw-r--r--src/CrDatFrP.c74
-rw-r--r--src/CrIFrBuf.c115
-rw-r--r--src/CrIFrDat.c120
-rw-r--r--src/CrIFrP.c55
-rw-r--r--src/CrPFrBuf.c76
-rw-r--r--src/CrPFrDat.c79
-rw-r--r--src/CrPFrI.c59
-rw-r--r--src/Image.c61
-rw-r--r--src/Info.c124
-rw-r--r--src/RdFToBuf.c118
-rw-r--r--src/RdFToDat.c65
-rw-r--r--src/RdFToI.c224
-rw-r--r--src/RdFToP.c75
-rw-r--r--src/WrFFrBuf.c55
-rw-r--r--src/WrFFrDat.c59
-rw-r--r--src/WrFFrI.c360
-rw-r--r--src/WrFFrP.c74
-rw-r--r--src/XpmI.h314
-rw-r--r--src/amigax.c382
-rw-r--r--src/amigax.h151
-rw-r--r--src/create.c2484
-rw-r--r--src/data.c476
-rw-r--r--src/hashtab.c234
-rw-r--r--src/misc.c124
-rw-r--r--src/parse.c749
-rw-r--r--src/rgb.c282
-rw-r--r--src/rgbtab.h292
-rw-r--r--src/scan.c1007
-rw-r--r--src/simx.c290
-rw-r--r--src/simx.h139
-rw-r--r--sxpm/plaid.xpm34
-rw-r--r--sxpm/plaid_ext.xpm43
-rw-r--r--sxpm/plaid_mask.xpm35
-rw-r--r--sxpm/sxpm.c709
-rw-r--r--sxpm/sxpm.man131
-rw-r--r--xpm.PS.gzbin0 -> 49010 bytes
50 files changed, 13332 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
new file mode 100644
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/COPYRIGHT b/COPYRIGHT
new file mode 100644
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/FAQ.html b/FAQ.html
new file mode 100644
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
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/README.AMIGA b/README.AMIGA
new file mode 100644
index 0000000..7a40137
--- /dev/null
+++ b/README.AMIGA
@@ -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/README.MSW b/README.MSW
new file mode 100644
index 0000000..f631525
--- /dev/null
+++ b/README.MSW
@@ -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/README.html b/README.html
new file mode 100644
index 0000000..6711f23
--- /dev/null
+++ b/README.html
@@ -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/cxpm/cxpm.c b/cxpm/cxpm.c
new file mode 100644
index 0000000..20b4905
--- /dev/null
+++ b/cxpm/cxpm.c
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+/* $XFree86: xc/extras/Xpm/cxpm/cxpm.c,v 1.2 2001/08/01 00:44:34 tsi Exp $ */
+
+/*****************************************************************************\
+* cxpm.c: *
+* *
+* Check XPM File program *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+
+#define CXPMPROG
+
+#include "../lib/XpmI.h"
+
+#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(data)
+ xpmData *data;
+{
+ int c = getc(data->stream.file);
+ if (c == '\n') {
+ data->lineNum++;
+ data->charNum = 0;
+ } else {
+ data->charNum++;
+ }
+ return c;
+}
+
+static void
+sUngetc(data, c)
+ xpmData *data;
+ int c;
+{
+ 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 "../lib/data.c"
+#include "../lib/parse.c"
+#include "../lib/RdFToI.c" /* only for OpenReadFile and xpmDataClose */
+#include "../lib/hashtab.c"
+#include "../lib/misc.c"
+#include "../lib/Attrib.c"
+#include "../lib/Image.c"
+
+void
+ErrorMessage(ErrorStatus, data)
+ int ErrorStatus;
+ xpmData *data;
+
+{
+ char *error = NULL;
+
+ switch (ErrorStatus) {
+ case XpmSuccess:
+ return;
+ case XpmOpenFailed:
+ error = "Cannot open file";
+ break;
+ case XpmFileInvalid:
+ error = "Invalid XPM file";
+ break;
+ case XpmNoMemory:
+ error = "Not enough memory";
+ break;
+ case XpmColorFailed:
+ error = "Failed to parse color";
+ break;
+ }
+
+ if (error) {
+ fprintf(stderr, "Xpm Error: %s.\n", error);
+ if (ErrorStatus == XpmFileInvalid && data)
+ fprintf(stderr, "Error found line %d near character %d\n",
+ data->lineNum + 1,
+ data->charNum + 1);
+ exit(1);
+ }
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ XpmImage image;
+ char *filename;
+ int ErrorStatus;
+ xpmData data;
+
+ if (argc > 1) {
+ if (!strcmp(argv[1], "-?") || !strncmp(argv[1], "-h", 2)) {
+ fprintf(stderr, "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
index 0000000..21d63fd
--- /dev/null
+++ b/cxpm/cxpm.man
@@ -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/include/X11/xpm.h b/include/X11/xpm.h
new file mode 100644
index 0000000..786f3c3
--- /dev/null
+++ b/include/X11/xpm.h
@@ -0,0 +1,502 @@
+/*
+ * 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.
+ */
+/* $XFree86: xc/extras/Xpm/lib/xpm.h,v 1.2 2001/08/22 23:36:44 dawes Exp $ */
+
+/*****************************************************************************\
+* 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
+
+/* make sure we know whether function prototypes are needed or not */
+#ifndef NeedFunctionPrototypes
+# if defined(__STDC__) || defined(__cplusplus) || defined(c_plusplus)
+# define NeedFunctionPrototypes 1
+# else
+# define NeedFunctionPrototypes 0
+# endif
+#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)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Colormap /* colormap */,
+ char* /* colorname */,
+ XColor* /* xcolor */,
+ void* /* closure */
+#endif
+);
+
+typedef int (*XpmFreeColorsFunc)(
+#if NeedFunctionPrototypes
+ Display* /* display */,
+ Colormap /* colormap */,
+ Pixel* /* pixels */,
+ int /* npixels */,
+ void* /* closure */
+#endif
+);
+
+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 */
+#if NeedFunctionPrototypes
+#define FUNC(f, t, p) extern t f p
+#define LFUNC(f, t, p) static t f p
+#else
+#define FUNC(f, t, p) extern t f()
+#define LFUNC(f, t, p) static t f()
+#endif
+
+
+/*
+ * functions declarations
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 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));
+
+#ifdef __cplusplus
+} /* for C++ V2.0 */
+#endif
+
+
+/* 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/src/Attrib.c b/src/Attrib.c
new file mode 100644
index 0000000..04b843b
--- /dev/null
+++ b/src/Attrib.c
@@ -0,0 +1,302 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+/* 3.2 backward compatibility code */
+LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors,
+ XpmColor ***oldct));
+
+LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, int ncolors));
+
+/*
+ * Create a colortable compatible with the old style colortable
+ */
+static int
+CreateOldColorTable(ct, ncolors, oldct)
+ XpmColor *ct;
+ int ncolors;
+ XpmColor ***oldct;
+{
+ XpmColor **colorTable, **color;
+ int a;
+
+ 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(colorTable, ncolors)
+ 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);
+ XpmFree(colorTable);
+ }
+}
+
+/* end 3.2 bc */
+
+/*
+ * Free the computed color table
+ */
+void
+xpmFreeColorTable(colorTable, ncolors)
+ 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(extensions, nextensions)
+ XpmExtension *extensions;
+ int nextensions;
+{
+ unsigned int i, j, nlines;
+ XpmExtension *ext;
+ char **sptr;
+
+ if (extensions) {
+ 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)
+ XpmFree(*sptr);
+ if (ext->lines)
+ XpmFree(ext->lines);
+ }
+ XpmFree(extensions);
+ }
+}
+
+/*
+ * Return the XpmAttributes structure size
+ */
+
+int
+XpmAttributesSize()
+{
+ return sizeof(XpmAttributes);
+}
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitAttributes(attributes)
+ 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(attributes, image, info)
+ 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(attributes)
+ 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 100644
index 0000000..da6735f
--- /dev/null
+++ b/src/CrBufFrI.c
@@ -0,0 +1,401 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/CrBufFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
+
+#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 *used_size,
+ unsigned int width, unsigned int height,
+ unsigned int cpp, unsigned int *pixels,
+ XpmColor *colors));
+
+LFUNC(WriteExtensions, void, (char *dataptr, unsigned int *used_size,
+ XpmExtension *ext, unsigned int num));
+
+LFUNC(ExtensionsSize, int, (XpmExtension *ext, unsigned int num));
+LFUNC(CommentsSize, int, (XpmInfo *info));
+
+int
+XpmCreateBufferFromImage(display, buffer_return, image, shapeimage, attributes)
+ 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) \
+{ \
+ ErrorStatus = status; \
+ goto error; \
+}
+
+int
+XpmCreateBufferFromXpmImage(buffer_return, image, info)
+ 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;
+
+ *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 = (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
+ sprintf(ptr + 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
+ sprintf(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;
+ 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
+ sprintf(ptr + 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')
+ */
+ ptr_size += image->height * (image->width * image->cpp + 4) + 1;
+
+ 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
+ sprintf(ptr + used_size, "/*%s*/\n", info->pixels_cmt);
+#ifdef VOID_SPRINTF
+ used_size += strlen(info->pixels_cmt) + 5;
+#endif
+ }
+ WritePixels(ptr + used_size, &used_size, image->width, image->height,
+ image->cpp, image->data, image->colorTable);
+
+ /* print extensions */
+ if (extensions)
+ WriteExtensions(ptr + 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(dataptr, data_size, used_size, colors, ncolors, cpp)
+ char **dataptr;
+ unsigned int *data_size;
+ unsigned int *used_size;
+ XpmColor *colors;
+ unsigned int ncolors;
+ unsigned int cpp;
+{
+ char buf[BUFSIZ];
+ unsigned int a, key, l;
+ char *s, *s2;
+ char **defaults;
+
+ *buf = '"';
+ for (a = 0; a < ncolors; a++, colors++) {
+
+ defaults = (char **) colors;
+ s = buf + 1;
+ strncpy(s, *defaults++, cpp);
+ s += cpp;
+
+ for (key = 1; key <= NKEYS; key++, defaults++) {
+ if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+ s +=
+#endif
+ sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+ s += strlen(s);
+#endif
+ }
+ }
+ strcpy(s, "\",\n");
+ l = s + 3 - buf;
+ 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(dataptr, used_size, width, height, cpp, pixels, colors)
+ char *dataptr;
+ 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;
+
+ h = height - 1;
+ for (y = 0; y < h; y++) {
+ *s++ = '"';
+ for (x = 0; x < width; x++, pixels++) {
+ strncpy(s, colors[*pixels].string, cpp);
+ s += cpp;
+ }
+ strcpy(s, "\",\n");
+ s += 3;
+ }
+ /* duplicate some code to avoid a test in the loop */
+ *s++ = '"';
+ for (x = 0; x < width; x++, pixels++) {
+ strncpy(s, colors[*pixels].string, cpp);
+ s += cpp;
+ }
+ *s++ = '"';
+ *used_size += s - dataptr;
+}
+
+static int
+ExtensionsSize(ext, num)
+ XpmExtension *ext;
+ unsigned int num;
+{
+ unsigned int x, y, a, size;
+ char **line;
+
+ size = 0;
+ for (x = 0; x < num; x++, ext++) {
+ /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */
+ size += strlen(ext->name) + 11;
+ a = ext->nlines;
+ 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"' */
+ return size + 13;
+}
+
+static void
+WriteExtensions(dataptr, used_size, ext, num)
+ char *dataptr;
+ 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
+ sprintf(s, ",\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
+ sprintf(s, ",\n\"%s\"", *line);
+#ifdef VOID_SPRINTF
+ s += strlen(*line) + 4;
+#endif
+ }
+ }
+ strcpy(s, ",\n\"XPMENDEXT\"");
+ *used_size += s - dataptr + 13;
+}
+
+static int
+CommentsSize(info)
+ XpmInfo *info;
+{
+ int size = 0;
+
+ /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */
+ 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
index 0000000..4aec4fb
--- /dev/null
+++ b/src/CrBufFrP.c
@@ -0,0 +1,75 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmCreateBufferFromPixmap(display, buffer_return, pixmap, shapemask,
+ attributes)
+ 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 100644
index 0000000..71fac8b
--- /dev/null
+++ b/src/CrDatFrI.c
@@ -0,0 +1,341 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/CrDatFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
+
+#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 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 offset,
+ XpmExtension *ext, unsigned int num,
+ unsigned int ext_nlines));
+
+int
+XpmCreateDataFromImage(display, data_return, image, shapeimage, attributes)
+ 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) \
+{ \
+ ErrorStatus = status; \
+ goto exit; \
+}
+
+int
+XpmCreateDataFromXpmImage(data_return, image, info)
+ 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;
+ header_size = sizeof(char *) * header_nlines;
+ header = (char **) XpmCalloc(header_size, sizeof(char *));
+ 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;
+ data_size = header_size + (image->height + ext_nlines) * sizeof(char *)
+ + image->height * offset + ext_size;
+
+ data = (char **) XpmMalloc(data_size);
+ if (!data)
+ RETURN(XpmNoMemory);
+
+ data_nlines = header_nlines + image->height + ext_nlines;
+ *data = (char *) (data + data_nlines);
+ n = image->ncolors;
+ for (l = 0, sptr = data, sptr2 = header; l <= n; 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, image->width, image->height,
+ image->cpp, image->data, image->colorTable);
+
+ /* print extensions */
+ if (extensions)
+ CreateExtensions(data + 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(dataptr, data_size, colors, ncolors, cpp)
+ 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;
+
+ for (a = 0; a < ncolors; a++, colors++, dataptr++) {
+
+ defaults = (char **) colors;
+ strncpy(buf, *defaults++, cpp);
+ s = buf + cpp;
+
+ for (key = 1; key <= NKEYS; key++, defaults++) {
+ if ((s2 = *defaults)) {
+#ifndef VOID_SPRINTF
+ s +=
+#endif
+ sprintf(s, "\t%s %s", xpmColorKeys[key - 1], s2);
+#ifdef VOID_SPRINTF
+ s += strlen(s);
+#endif
+ }
+ }
+ l = s - buf + 1;
+ s = (char *) XpmMalloc(l);
+ if (!s)
+ return (XpmNoMemory);
+ *data_size += l;
+ *dataptr = strcpy(s, buf);
+ }
+ return (XpmSuccess);
+}
+
+static void
+CreatePixels(dataptr, width, height, cpp, pixels, colors)
+ char **dataptr;
+ unsigned int width;
+ unsigned int height;
+ unsigned int cpp;
+ unsigned int *pixels;
+ XpmColor *colors;
+{
+ char *s;
+ unsigned int x, y, h, offset;
+
+ h = height - 1;
+ offset = width * cpp + 1;
+ for (y = 0; y < h; y++, dataptr++) {
+ s = *dataptr;
+ for (x = 0; x < width; x++, pixels++) {
+ strncpy(s, colors[*pixels].string, cpp);
+ s += cpp;
+ }
+ *s = '\0';
+ *(dataptr + 1) = *dataptr + offset;
+ }
+ /* duplicate some code to avoid a test in the loop */
+ s = *dataptr;
+ for (x = 0; x < width; x++, pixels++) {
+ strncpy(s, colors[*pixels].string, cpp);
+ s += cpp;
+ }
+ *s = '\0';
+}
+
+static void
+CountExtensions(ext, num, ext_size, ext_nlines)
+ 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(dataptr, offset, ext, num, ext_nlines)
+ char **dataptr;
+ 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++) {
+ sprintf(*dataptr, "XPMEXT %s", ext->name);
+ a++;
+ if (a < ext_nlines)
+ *(dataptr + 1) = *dataptr + strlen(ext->name) + 8;
+ dataptr++;
+ b = ext->nlines;
+ 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
index 0000000..1593b7b
--- /dev/null
+++ b/src/CrDatFrP.c
@@ -0,0 +1,74 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmCreateDataFromPixmap(display, data_return, pixmap, shapemask, attributes)
+ 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
index 0000000..ba863ac
--- /dev/null
+++ b/src/CrIFrBuf.c
@@ -0,0 +1,115 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+LFUNC(OpenBuffer, void, (char *buffer, xpmData *mdata));
+
+int
+XpmCreateImageFromBuffer(display, buffer, image_return,
+ shapeimage_return, attributes)
+ 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(buffer, image, info)
+ 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(buffer, mdata)
+ 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
index 0000000..f3c19c7
--- /dev/null
+++ b/src/CrIFrDat.c
@@ -0,0 +1,120 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+LFUNC(OpenArray, void, (char **data, xpmData *mdata));
+
+int
+XpmCreateImageFromData(display, data, image_return,
+ shapeimage_return, attributes)
+ 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(data, image, info)
+ 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(data, mdata)
+ 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
index 0000000..f8aa4ed
--- /dev/null
+++ b/src/CrIFrP.c
@@ -0,0 +1,55 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+void
+xpmCreateImageFromPixmap(display, pixmap, ximage_return, width, height)
+ 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
index 0000000..19e7cb9
--- /dev/null
+++ b/src/CrPFrBuf.c
@@ -0,0 +1,76 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmCreatePixmapFromBuffer(display, d, buffer, pixmap_return,
+ shapemask_return, attributes)
+ 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
index 0000000..fcbe5f1
--- /dev/null
+++ b/src/CrPFrDat.c
@@ -0,0 +1,79 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmCreatePixmapFromData(display, d, data, pixmap_return,
+ shapemask_return, attributes)
+ 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
index 0000000..0661a4e
--- /dev/null
+++ b/src/CrPFrI.c
@@ -0,0 +1,59 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+void
+xpmCreatePixmapFromImage(display, d, ximage, pixmap_return)
+ 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
index 0000000..0753622
--- /dev/null
+++ b/src/Image.c
@@ -0,0 +1,61 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitXpmImage(image)
+ XpmImage *image;
+{
+ image->ncolors = 0;
+ image->colorTable = NULL;
+ image->data = NULL;
+}
+
+/*
+ * Free the XpmImage data which have been allocated
+ */
+void
+XpmFreeXpmImage(image)
+ 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
index 0000000..9bc41c8
--- /dev/null
+++ b/src/Info.c
@@ -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.
+ */
+
+/*****************************************************************************\
+* Info.c: *
+* *
+* XPM library *
+* Functions related to the XpmInfo structure. *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+/*
+ * Init returned data to free safely later on
+ */
+void
+xpmInitXpmInfo(info)
+ 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(info)
+ 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(info, attributes)
+ 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(info, attributes)
+ 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/RdFToBuf.c b/src/RdFToBuf.c
new file mode 100644
index 0000000..898a9fc
--- /dev/null
+++ b/src/RdFToBuf.c
@@ -0,0 +1,118 @@
+/*
+ * 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
+ */
+
+#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(filename, buffer_return)
+ char *filename;
+ char **buffer_return;
+{
+ int fd, fcheck, 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 = (int) 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
index 0000000..4bb28fc
--- /dev/null
+++ b/src/RdFToDat.c
@@ -0,0 +1,65 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmReadFileToData(filename, data_return)
+ 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 100644
index 0000000..867d656
--- /dev/null
+++ b/src/RdFToI.c
@@ -0,0 +1,224 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/RdFToI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
+
+#include "XpmI.h"
+#include <sys/stat.h>
+#if !defined(NO_ZPIPE) && defined(WIN32)
+# define popen _popen
+# define pclose _pclose
+# if defined(STAT_ZFILE)
+# include <io.h>
+# define stat _stat
+# define fstat _fstat
+# endif
+#endif
+
+LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata));
+LFUNC(xpmDataClose, void, (xpmData *mdata));
+
+#ifndef CXPMPROG
+int
+XpmReadFileToImage(display, filename,
+ image_return, shapeimage_return, attributes)
+ 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(filename, image, info)
+ 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 */
+
+/*
+ * open the given file to be read as an xpmData which is returned.
+ */
+static int
+OpenReadFile(filename, mdata)
+ char *filename;
+ xpmData *mdata;
+{
+#ifndef NO_ZPIPE
+ char buf[BUFSIZ];
+# ifdef STAT_ZFILE
+ char *compressfile;
+ struct stat status;
+# endif
+#endif
+
+ if (!filename) {
+ mdata->stream.file = (stdin);
+ mdata->type = XPMFILE;
+ } else {
+#ifndef NO_ZPIPE
+ int len = strlen(filename);
+ if ((len > 2) && !strcmp(".Z", filename + (len - 2))) {
+ mdata->type = XPMPIPE;
+ sprintf(buf, "uncompress -c \"%s\"", filename);
+ if (!(mdata->stream.file = popen(buf, "r")))
+ return (XpmOpenFailed);
+
+ } else if ((len > 3) && !strcmp(".gz", filename + (len - 3))) {
+ mdata->type = XPMPIPE;
+ sprintf(buf, "gunzip -qc \"%s\"", filename);
+ if (!(mdata->stream.file = popen(buf, "r")))
+ return (XpmOpenFailed);
+
+ } else {
+# ifdef STAT_ZFILE
+ if (!(compressfile = (char *) XpmMalloc(len + 4)))
+ return (XpmNoMemory);
+
+ sprintf(compressfile, "%s.Z", filename);
+ if (!stat(compressfile, &status)) {
+ sprintf(buf, "uncompress -c \"%s\"", compressfile);
+ if (!(mdata->stream.file = popen(buf, "r"))) {
+ XpmFree(compressfile);
+ return (XpmOpenFailed);
+ }
+ mdata->type = XPMPIPE;
+ } else {
+ sprintf(compressfile, "%s.gz", filename);
+ if (!stat(compressfile, &status)) {
+ sprintf(buf, "gunzip -c \"%s\"", compressfile);
+ if (!(mdata->stream.file = popen(buf, "r"))) {
+ XpmFree(compressfile);
+ return (XpmOpenFailed);
+ }
+ mdata->type = XPMPIPE;
+ } else {
+# endif
+#endif
+ if (!(mdata->stream.file = fopen(filename, "r"))) {
+#if !defined(NO_ZPIPE) && defined(STAT_ZFILE)
+ XpmFree(compressfile);
+#endif
+ return (XpmOpenFailed);
+ }
+ mdata->type = XPMFILE;
+#ifndef NO_ZPIPE
+# ifdef STAT_ZFILE
+ }
+ }
+ XpmFree(compressfile);
+# endif
+ }
+#endif
+ }
+ 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(mdata)
+ xpmData *mdata;
+{
+ switch (mdata->type) {
+ case XPMFILE:
+ if (mdata->stream.file != (stdin))
+ fclose(mdata->stream.file);
+ break;
+#ifndef NO_ZPIPE
+ case XPMPIPE:
+ pclose(mdata->stream.file);
+ break;
+#endif
+ }
+}
diff --git a/src/RdFToP.c b/src/RdFToP.c
new file mode 100644
index 0000000..212d260
--- /dev/null
+++ b/src/RdFToP.c
@@ -0,0 +1,75 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmReadFileToPixmap(display, d, filename, pixmap_return,
+ shapemask_return, attributes)
+ 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
index 0000000..3ed6685
--- /dev/null
+++ b/src/WrFFrBuf.c
@@ -0,0 +1,55 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmWriteFileFromBuffer(filename, buffer)
+ 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;
+
+ return XpmSuccess;
+}
diff --git a/src/WrFFrDat.c b/src/WrFFrDat.c
new file mode 100644
index 0000000..bfaa909
--- /dev/null
+++ b/src/WrFFrDat.c
@@ -0,0 +1,59 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmWriteFileFromData(filename, data)
+ 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 100644
index 0000000..0769f80
--- /dev/null
+++ b/src/WrFFrI.c
@@ -0,0 +1,360 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/WrFFrI.c,v 1.2 2001/10/28 03:32:09 tsi Exp $ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#include "XpmI.h"
+#if !defined(NO_ZPIPE) && defined(WIN32)
+# define popen _popen
+# define pclose _pclose
+#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, filename, image, shapeimage, attributes)
+ 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(filename, image, info)
+ char *filename;
+ XpmImage *image;
+ XpmInfo *info;
+{
+ xpmData mdata;
+ char *name, *dot, *s, new_name[BUFSIZ];
+ 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 = rindex(filename, '/'))
+#ifdef AMIGA
+ && !(name = rindex(filename, ':'))
+#endif
+ )
+ name = filename;
+ else
+ name++;
+#endif
+ /* let's try to make a valid C syntax name */
+ if (index(name, '.')) {
+ strcpy(new_name, name);
+ /* change '.' to '_' */
+ name = s = new_name;
+ while ((dot = index(s, '.'))) {
+ *dot = '_';
+ s = dot;
+ }
+ }
+ if (index(name, '-')) {
+ if (name != new_name) {
+ strcpy(new_name, name);
+ name = new_name;
+ }
+ /* change '-' to '_' */
+ s = name;
+ while ((dot = index(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, image, name, info)
+ 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, colors, ncolors)
+ 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, width, height, cpp, pixels, colors)
+ 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;
+ 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, ext, num)
+ 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\"");
+}
+
+/*
+ * open the given file to be written as an xpmData which is returned
+ */
+static int
+OpenWriteFile(filename, mdata)
+ char *filename;
+ xpmData *mdata;
+{
+#ifndef NO_ZPIPE
+ char buf[BUFSIZ];
+
+#endif
+
+ if (!filename) {
+ mdata->stream.file = (stdout);
+ mdata->type = XPMFILE;
+ } else {
+#ifndef NO_ZPIPE
+ int len = strlen(filename);
+ if (len > 2 && !strcmp(".Z", filename + (len - 2))) {
+ sprintf(buf, "compress > \"%s\"", filename);
+ if (!(mdata->stream.file = popen(buf, "w")))
+ return (XpmOpenFailed);
+
+ mdata->type = XPMPIPE;
+ } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) {
+ sprintf(buf, "gzip -q > \"%s\"", filename);
+ if (!(mdata->stream.file = popen(buf, "w")))
+ return (XpmOpenFailed);
+
+ mdata->type = XPMPIPE;
+ } else {
+#endif
+ if (!(mdata->stream.file = fopen(filename, "w")))
+ return (XpmOpenFailed);
+
+ mdata->type = XPMFILE;
+#ifndef NO_ZPIPE
+ }
+#endif
+ }
+ return (XpmSuccess);
+}
+
+/*
+ * close the file related to the xpmData if any
+ */
+static void
+xpmDataClose(mdata)
+ xpmData *mdata;
+{
+ switch (mdata->type) {
+ case XPMFILE:
+ if (mdata->stream.file != (stdout))
+ fclose(mdata->stream.file);
+ break;
+#ifndef NO_ZPIPE
+ case XPMPIPE:
+ pclose(mdata->stream.file);
+ break;
+#endif
+ }
+}
diff --git a/src/WrFFrP.c b/src/WrFFrP.c
new file mode 100644
index 0000000..b78ea0c
--- /dev/null
+++ b/src/WrFFrP.c
@@ -0,0 +1,74 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+int
+XpmWriteFileFromPixmap(display, filename, pixmap, shapemask, attributes)
+ 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 100644
index 0000000..237a535
--- /dev/null
+++ b/src/XpmI.h
@@ -0,0 +1,314 @@
+/*
+ * 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.
+ */
+/* $XFree86: xc/extras/Xpm/lib/XpmI.h,v 1.8 2002/01/07 19:40:23 dawes Exp $ */
+
+/*****************************************************************************\
+* 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 <stdio.h>
+#include <stdlib.h>
+/* stdio.h doesn't declare popen on a Sequent DYNIX OS */
+#ifdef sequent
+extern FILE *popen();
+#endif
+
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+
+#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
+
+#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 {
+ int size;
+ int limit;
+ 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
index 0000000..aa82d49
--- /dev/null
+++ b/src/amigax.c
@@ -0,0 +1,382 @@
+/*
+ * 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 *
+\*****************************************************************************/
+
+#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
index 0000000..213ed76
--- /dev/null
+++ b/src/amigax.h
@@ -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 100644
index 0000000..770fbf8
--- /dev/null
+++ b/src/create.c
@@ -0,0 +1,2484 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/create.c,v 1.3 2002/01/07 19:40:49 dawes Exp $ */
+
+/*
+ * 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
+ */
+
+#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));
+LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel));
+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(s1, s2)
+ register char *s1, *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 *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, colormap, colorname, xcolor, closure)
+ 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, colormap, visual, col, image_pixel, mask_pixel,
+ alloc_pixels, nalloc_pixels, attributes, cols, ncols,
+ allocColor, closure)
+ Display *display;
+ Colormap colormap;
+ Visual *visual;
+ XColor *col;
+ Pixel *image_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, colormap, visual, colorname, color_index,
+ image_pixel, mask_pixel, mask_pixel_index,
+ alloc_pixels, nalloc_pixels, used_pixels, nused_pixels,
+ attributes, cols, ncols, allocColor, closure)
+ Display *display;
+ Colormap colormap;
+ Visual *visual;
+ char *colorname;
+ unsigned int color_index;
+ Pixel *image_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, attributes, colors, ncolors, image_pixels, mask_pixels,
+ mask_pixel_index, alloc_pixels, nalloc_pixels,
+ used_pixels, nused_pixels)
+ 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
+ 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, colormap, pixels, n, closure)
+ 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) \
+{ \
+ ErrorStatus = status; \
+ goto error; \
+}
+
+int
+XpmCreateImageFromXpmImage(display, image,
+ image_return, shapeimage_return, attributes)
+ 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;
+ void *closure;
+
+ /* 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;
+ if (attributes && (attributes->valuemask & XpmColorClosure))
+ closure = attributes->color_closure;
+ else
+ closure = NULL;
+
+ ErrorStatus = XpmSuccess;
+
+ /* 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, visual, depth, format, width, height, image_return)
+ 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)
+ /* now that bytes_per_line must have been set properly alloc data */
+ (*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 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(bpt, nb)
+ register unsigned char *bpt;
+ register int nb;
+{
+ do {
+ *bpt = _reverse_byte[*bpt];
+ bpt++;
+ } while (--nb > 0);
+ return 0;
+}
+
+
+void
+xpm_xynormalizeimagebits(bp, img)
+ 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(bp, img)
+ 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(src, dstoffset, numbits, dst)
+ 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(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ register char *src;
+ register char *dst;
+ register unsigned int *iptr;
+ register int x, y, i;
+ register char *data;
+ Pixel pixel, px;
+ int nbytes, depth, ibu, ibpp;
+
+ data = image->data;
+ iptr = pixelindex;
+ depth = image->depth;
+ if (depth == 1) {
+ ibu = image->bitmap_unit;
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++, iptr++) {
+ 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(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ unsigned char *data;
+ unsigned int *iptr;
+ int y;
+ Pixel pixel;
+
+#ifdef WITHOUT_SPEEDUPS
+
+ 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 */
+
+ 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(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ unsigned char *data;
+ unsigned int *iptr;
+ int y;
+
+#ifdef WITHOUT_SPEEDUPS
+
+ 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;
+
+ 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(image, width, height, pixelindex, pixels)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ unsigned int *pixelindex;
+ Pixel *pixels;
+{
+ char *data;
+ unsigned int *iptr;
+ int y;
+
+#ifdef WITHOUT_SPEEDUPS
+
+ 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 */
+
+ 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(image, width, height, pixelindex, pixels)
+ 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;
+ int y;
+ char *data;
+
+#ifdef WITHOUT_SPEEDUPS
+
+ 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, d, image,
+ pixmap_return, shapemask_return, attributes)
+ 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(dc, image, width, height, pixelindex, pixels)
+ 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(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ register char *src;
+ register char *dst;
+ register int i;
+ Pixel px;
+ int nbytes;
+
+ 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(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ register char *src;
+ register char *dst;
+ register int i;
+ Pixel px;
+ int nbytes, ibpp;
+
+ 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;
+}
+
+static int
+PutPixel32(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ unsigned char *addr;
+
+ addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)];
+ *((unsigned long *)addr) = pixel;
+ return 1;
+}
+
+static int
+PutPixel32MSB(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ unsigned char *addr;
+
+ 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(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ unsigned char *addr;
+
+ 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(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ unsigned char *addr;
+
+ addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
+ addr[0] = pixel >> 8;
+ addr[1] = pixel;
+ return 1;
+}
+
+static int
+PutPixel16LSB(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ unsigned char *addr;
+
+ addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)];
+ addr[1] = pixel >> 8;
+ addr[0] = pixel;
+ return 1;
+}
+
+static int
+PutPixel8(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ ximage->data[ZINDEX8(x, y, ximage)] = pixel;
+ return 1;
+}
+
+static int
+PutPixel1MSB(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ 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(ximage, x, y, pixel)
+ register XImage *ximage;
+ int x;
+ int y;
+ unsigned long pixel;
+{
+ 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, data, image_return, shapeimage_return,
+ image, info, attributes)
+ 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;
+ void *closure;
+
+ /* 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;
+ if (attributes && (attributes->valuemask & XpmColorClosure))
+ closure = attributes->color_closure;
+ else
+ closure = NULL;
+
+ 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 hastable
+ */
+ 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 */
+ 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
+ dc,
+#endif
+ data, width, height, ncolors, cpp, colorTable, hashtable,
+ image, image_pixels, shapeimage, shape_pixels)
+#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
+
+
+ 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];
+ int char1;
+
+ bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
+ for (a = 0; a < ncolors; a++) {
+ char1 = 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];
+
+ 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 100644
index 0000000..dea87b4
--- /dev/null
+++ b/src/data.c
@@ -0,0 +1,476 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/data.c,v 1.4 2002/01/07 19:40:49 dawes Exp $ */
+
+#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
+#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(data)
+ 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(data, buf, buflen)
+ 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);
+}
+
+/*
+ * skip whitespace and compute the following unsigned int,
+ * returns 1 if one is found and 0 if not
+ */
+int
+xpmNextUI(data, ui_return)
+ 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(data, sptr, l)
+ 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(data, cmt)
+ xpmData *data;
+ char **cmt;
+{
+ if (!data->type)
+ *cmt = NULL;
+ else if (data->CommentLength) {
+ *cmt = (char *) XpmMalloc(data->CommentLength + 1);
+ 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(data)
+ xpmData *data;
+{
+ char buf[BUFSIZ];
+ 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 = rindex(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
index 0000000..7d596ec
--- /dev/null
+++ b/src/hashtab.c
@@ -0,0 +1,234 @@
+/*
+ * 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 *
+* *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+LFUNC(AtomMake, xpmHashAtom, (char *name, void *data));
+LFUNC(HashTableGrows, int, (xpmHashTable * table));
+
+static xpmHashAtom
+AtomMake(name, data) /* 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(table, s)
+ 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(table)
+ xpmHashTable *table;
+{
+ xpmHashAtom *atomTable = table->atomTable;
+ int size = table->size;
+ xpmHashAtom *t, *p;
+ int i;
+ int oldSize = size;
+
+ t = atomTable;
+ HASH_TABLE_GROWS
+ table->size = size;
+ table->limit = size / 3;
+ 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(table, tag, data)
+ 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(table)
+ xpmHashTable *table;
+{
+ xpmHashAtom *p;
+ xpmHashAtom *atomTable;
+
+ table->size = INITIAL_HASH_SIZE;
+ table->limit = table->size / 3;
+ table->used = 0;
+ 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(table)
+ 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
index 0000000..7a9ecb5
--- /dev/null
+++ b/src/misc.c
@@ -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 *
+\*****************************************************************************/
+
+#include "XpmI.h"
+
+#ifdef NEED_STRDUP
+/*
+ * in case strdup is not provided by the system here is one
+ * which does the trick
+ */
+char *
+xpmstrdup(s1)
+ char *s1;
+{
+ char *s2;
+ int l = strlen(s1) + 1;
+
+ if (s2 = (char *) XpmMalloc(l))
+ strcpy(s2, s1);
+ return s2;
+}
+
+#endif
+
+unsigned int
+xpmatoui(p, l, ui_return)
+ 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(errcode)
+ 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()
+{
+ return XpmIncludeVersion;
+}
+
+
+/* The following should help people wanting to use their own functions */
+#ifdef XpmFree
+#undef XpmFree
+#endif
+
+void
+XpmFree(ptr)
+ void *ptr;
+{
+ free(ptr);
+}
diff --git a/src/parse.c b/src/parse.c
new file mode 100644
index 0000000..fc8cd2b
--- /dev/null
+++ b/src/parse.c
@@ -0,0 +1,749 @@
+/*
+ * 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.
+ */
+/* $XFree86: xc/extras/Xpm/lib/parse.c,v 1.3 2001/10/28 03:32:10 tsi Exp $ */
+
+/*****************************************************************************\
+* 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/parse.c,v 1.3 2001/10/28 03:32:10 tsi Exp $ */
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+#include "XpmI.h"
+#include <ctype.h>
+#include <string.h>
+
+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(data, width, height, ncolors, cpp,
+ x_hotspot, y_hotspot, hotspot, extensions)
+ xpmData *data;
+ unsigned int *width, *height, *ncolors, *cpp;
+ unsigned int *x_hotspot, *y_hotspot, *hotspot;
+ unsigned int *extensions;
+{
+ unsigned int l;
+ char buf[BUFSIZ];
+
+ 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 = index(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(data, ncolors, cpp, colorTablePtr, hashtable)
+ xpmData *data;
+ unsigned int ncolors;
+ unsigned int cpp;
+ XpmColor **colorTablePtr;
+ xpmHashTable *hashtable;
+{
+ unsigned int key = 0, l, a, b;
+ unsigned int curkey; /* current color key */
+ unsigned int lastwaskey; /* key read */
+ char buf[BUFSIZ];
+ char curbuf[BUFSIZ]; /* current buffer */
+ char **sptr, *s;
+ XpmColor *color;
+ XpmColor *colorTable;
+ char **defaults;
+ int ErrorStatus;
+
+ 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
+ */
+ 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 */
+ s = (char *) XpmMalloc(strlen(curbuf) + 1);
+ if (!s) {
+ xpmFreeColorTable(colorTable, ncolors);
+ return (XpmNoMemory);
+ }
+ defaults[curkey] = s;
+ strcpy(s, curbuf);
+ }
+ 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)
+ strcat(curbuf, " "); /* append space */
+ buf[l] = '\0';
+ strcat(curbuf, buf);/* append buf */
+ lastwaskey = 0;
+ }
+ }
+ if (!curkey) { /* key without value */
+ xpmFreeColorTable(colorTable, ncolors);
+ return (XpmFileInvalid);
+ }
+ s = defaults[curkey] = (char *) XpmMalloc(strlen(curbuf) + 1);
+ if (!s) {
+ xpmFreeColorTable(colorTable, ncolors);
+ return (XpmNoMemory);
+ }
+ strcpy(s, curbuf);
+ }
+ } 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
+ */
+ 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')
+ strcat(curbuf, " ");/* append space */
+ buf[l] = '\0';
+ strcat(curbuf, buf); /* append buf */
+ }
+ s = (char *) XpmMalloc(strlen(curbuf) + 1);
+ if (!s) {
+ xpmFreeColorTable(colorTable, ncolors);
+ return (XpmNoMemory);
+ }
+ strcpy(s, curbuf);
+ color->c_color = s;
+ *curbuf = '\0'; /* reset curbuf */
+ if (a < ncolors - 1)
+ xpmNextString(data); /* get to the next string */
+ }
+ }
+ *colorTablePtr = colorTable;
+ return (XpmSuccess);
+}
+
+static int
+ParsePixels(data, width, height, ncolors, cpp, colorTable, hashtable, pixels)
+ 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;
+ unsigned int a, x, y;
+
+#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];
+
+ 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 {int f; for (f = 0; f < 256; f++) \
+if (cidx[f]) XpmFree(cidx[f]);}
+
+ /* array of pointers malloced by need */
+ unsigned short *cidx[256];
+ int char1;
+
+ bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */
+ for (a = 0; a < ncolors; a++) {
+ char1 = 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];
+
+ 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);
+ 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);
+ 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(data, extensions, nextensions)
+ 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));
+ 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 *));
+ 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) \
+{ \
+ goto error; \
+}
+
+/*
+ * This function parses an Xpm file or data and store the found informations
+ * in an an XpmImage structure which is returned.
+ */
+int
+xpmParseData(data, image, info)
+ 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 hastable
+ */
+ 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
index 0000000..b26ee3f
--- /dev/null
+++ b/src/rgb.c
@@ -0,0 +1,282 @@
+/*
+ * 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
+ */
+
+#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(rgb_fname, rgbn)
+ 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(rgbn, rgbn_max, red, green, blue)
+ xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file */
+ int rgbn_max; /* number of rgb mnemonics in table */
+ int red, green, blue; /* rgb values */
+
+{
+ 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(rgbn, rgbn_max)
+ 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(rgb_fname, rgbn)
+ 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(rgbn, rgbn_max, red, green, blue)
+ xpmRgbName rgbn[]; /* rgb mnemonics from rgb text file
+ * not used */
+ int rgbn_max; /* not used */
+ int red, green, blue; /* rgb values */
+
+{
+ 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(inname, r, g, b)
+ char *inname;
+ int *r, *g, *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(rgbn, rgbn_max)
+ 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
index 0000000..3b75184
--- /dev/null
+++ b/src/rgbtab.h
@@ -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 100644
index 0000000..6175ca4
--- /dev/null
+++ b/src/scan.c
@@ -0,0 +1,1007 @@
+/*
+ * 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 *
+\*****************************************************************************/
+/* $XFree86: xc/extras/Xpm/lib/scan.c,v 1.3 2002/01/07 19:40:49 dawes Exp $ */
+
+/*
+ * 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
+ */
+
+#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, 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, pmap, index_return)
+ 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, pmap, index_return)
+ 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) \
+{ \
+ ErrorStatus = status; \
+ goto error; \
+}
+
+/*
+ * This function scans the given image and stores the found informations in
+ * the given XpmImage structure.
+ */
+int
+XpmCreateXpmImageFromImage(display, image, shapeimage,
+ xpmimage, attributes)
+ 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;
+
+ pmap.pixelindex =
+ (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int));
+ if (!pmap.pixelindex)
+ 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
+ */
+
+ 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(color, cpp, attributes)
+ XpmColor *color;
+ unsigned int cpp;
+ XpmAttributes *attributes;
+{
+ char *s;
+ unsigned int a, b, c;
+
+ /* first get a character string */
+ a = 0;
+ 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, colors, ncolors, pixels, mask, cpp, attributes)
+ Display *display;
+ XpmColor *colors;
+ 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 */
+ 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(image, width, height, pmap)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ PixelsMap *pmap;
+{
+ char *src;
+ char *dst;
+ unsigned int *iptr;
+ char *data;
+ int x, y, i;
+ int bits, depth, ibu, ibpp, offset;
+ 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->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(image, width, height, pmap)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ PixelsMap *pmap;
+{
+ unsigned char *addr;
+ unsigned char *data;
+ unsigned int *iptr;
+ 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(image, width, height, pmap)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ PixelsMap *pmap;
+{
+ unsigned char *addr;
+ unsigned char *data;
+ unsigned int *iptr;
+ 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(image, width, height, pmap)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ PixelsMap *pmap;
+{
+ unsigned int *iptr;
+ unsigned char *data;
+ 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(image, width, height, pmap, storeFunc)
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ PixelsMap *pmap;
+ storeFuncPtr storeFunc;
+{
+ unsigned int *iptr;
+ 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) \
+{\
+ if (pixels) XpmFree (pixels);\
+ if (tmp_img) FreeXImage (tmp_img);\
+ return (status);\
+}
+
+static int
+AGetImagePixels (
+ XImage *image,
+ unsigned int width,
+ unsigned int height,
+ PixelsMap *pmap,
+ int (*storeFunc) ())
+{
+ 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, image, width, height, pmap, storeFunc)
+ Display *display;
+ XImage *image;
+ unsigned int width;
+ unsigned int height;
+ PixelsMap *pmap;
+ int (*storeFunc) ();
+{
+ 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, pixmap, shapemask,
+ xpmimage, attributes)
+ 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
index 0000000..5e5537d
--- /dev/null
+++ b/src/simx.c
@@ -0,0 +1,290 @@
+/*
+ * 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
+
+#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
index 0000000..001cfdb
--- /dev/null
+++ b/src/simx.h
@@ -0,0 +1,139 @@
+/*
+ * 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 */
+
+/*
+ * 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
+
+#endif /* def FOR_MSW */
+
+#endif /* _SIMX_H */
diff --git a/sxpm/plaid.xpm b/sxpm/plaid.xpm
new file mode 100644
index 0000000..b0e9200
--- /dev/null
+++ b/sxpm/plaid.xpm
@@ -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
index 0000000..8538952
--- /dev/null
+++ b/sxpm/plaid_ext.xpm
@@ -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
index 0000000..167d338
--- /dev/null
+++ b/sxpm/plaid_mask.xpm
@@ -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 100644
index 0000000..b98ea9f
--- /dev/null
+++ b/sxpm/sxpm.c
@@ -0,0 +1,709 @@
+/*
+ * 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.
+ */
+/* $XFree86: xc/extras/Xpm/sxpm/sxpm.c,v 1.3 2001/10/28 03:32:13 tsi Exp $ */
+
+/*****************************************************************************\
+* sxpm.c: *
+* *
+* Show XPM File program *
+* *
+* Developed by Arnaud Le Hors *
+\*****************************************************************************/
+
+#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>
+
+/* 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 ErrorMessage();
+void Punt();
+void VersionInfo();
+
+#ifdef __STDC__
+void kinput(Widget widget, char *tag, XEvent *xe, Boolean *b);
+#else
+void kinput();
+#endif
+
+#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(argc, argv)
+ 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
+
+ topw = XtInitialize(argv[0], "Sxpm",
+ options, XtNumber(options), &argc, argv);
+
+ if (!topw) {
+ fprintf(stderr, "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++) {
+ 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]);
+ }
+ }
+ } 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()
+{
+ fprintf(stderr, "\nUsage: %s [options...]\n", command[0]);
+ fprintf(stderr, "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(ErrorStatus, tag)
+ int ErrorStatus;
+ char *tag;
+{
+ char *error = NULL;
+ char *warning = NULL;
+
+ switch (ErrorStatus) {
+ case XpmSuccess:
+ return;
+ case XpmColorError:
+ warning = "Could not parse or alloc requested color";
+ break;
+ case XpmOpenFailed:
+ error = "Cannot open file";
+ break;
+ case XpmFileInvalid:
+ error = "Invalid XPM file";
+ break;
+ case XpmNoMemory:
+ error = "Not enough memory";
+ break;
+ case XpmColorFailed:
+ error = "Failed to parse or alloc some color";
+ break;
+ }
+
+ if (warning)
+ fprintf(stderr, "%s Xpm Warning: %s.\n", tag, warning);
+
+ if (error) {
+ fprintf(stderr, "%s Xpm Error: %s.\n", tag, error);
+ Punt(1);
+ }
+}
+
+void
+Punt(i)
+ 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, tag, xe, b)
+ 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(num, format_return, libmajor_return, libminor_return)
+ 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()
+{
+ int format, libmajor;
+ char libminor;
+
+ GetNumbers(XpmIncludeVersion, &format, &libmajor, &libminor);
+ fprintf(stderr, "sxpm version: %d.%d%c\n",
+ format, libmajor, libminor);
+ /*
+ * if we are linked to an XPM library different from the one we've been
+ * compiled with, print its own number too.
+ */
+ if (XpmIncludeVersion != XpmLibraryVersion()) {
+ GetNumbers(XpmLibraryVersion(), &format, &libmajor, &libminor);
+ fprintf(stderr, "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 100644
index 0000000..8e5d593
--- /dev/null
+++ b/sxpm/sxpm.man
@@ -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.PS.gz b/xpm.PS.gz
new file mode 100644
index 0000000..40e25de
--- /dev/null
+++ b/xpm.PS.gz
Binary files differ