]> git.saurik.com Git - wxWidgets.git/commitdiff
wxMSW update for CW, wxMac updated
authorStefan Csomor <csomor@advancedconcepts.ch>
Fri, 3 Dec 1999 15:17:38 +0000 (15:17 +0000)
committerStefan Csomor <csomor@advancedconcepts.ch>
Fri, 3 Dec 1999 15:17:38 +0000 (15:17 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@4806 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

28 files changed:
src/mac/xpm/Attrib.c [new file with mode: 0644]
src/mac/xpm/CrBufFrI.c [new file with mode: 0644]
src/mac/xpm/CrDatFrI.c [new file with mode: 0644]
src/mac/xpm/CrIFrBuf.c [new file with mode: 0644]
src/mac/xpm/CrIFrDat.c [new file with mode: 0644]
src/mac/xpm/Image.c [new file with mode: 0644]
src/mac/xpm/Info.c [new file with mode: 0644]
src/mac/xpm/RdFToBuf.c [new file with mode: 0644]
src/mac/xpm/RdFToDat.c [new file with mode: 0644]
src/mac/xpm/RdFToI.c [new file with mode: 0644]
src/mac/xpm/WrFFrBuf.c [new file with mode: 0644]
src/mac/xpm/WrFFrDat.c [new file with mode: 0644]
src/mac/xpm/WrFFrI.c [new file with mode: 0644]
src/mac/xpm/XpmI.h [new file with mode: 0644]
src/mac/xpm/create.c [new file with mode: 0644]
src/mac/xpm/data.c [new file with mode: 0644]
src/mac/xpm/hashtab.c [new file with mode: 0644]
src/mac/xpm/macx.c [new file with mode: 0644]
src/mac/xpm/macx.cpp [new file with mode: 0644]
src/mac/xpm/macx.h [new file with mode: 0644]
src/mac/xpm/misc.c [new file with mode: 0644]
src/mac/xpm/parse.c [new file with mode: 0644]
src/mac/xpm/rgb.c [new file with mode: 0644]
src/mac/xpm/rgbtab.h [new file with mode: 0644]
src/mac/xpm/scan.c [new file with mode: 0644]
src/mac/xpm/simx.c [new file with mode: 0644]
src/mac/xpm/simx.h [new file with mode: 0644]
src/mac/xpm/xpm.h [new file with mode: 0644]

diff --git a/src/mac/xpm/Attrib.c b/src/mac/xpm/Attrib.c
new file mode 100644 (file)
index 0000000..2373190
--- /dev/null
@@ -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/mac/xpm/CrBufFrI.c b/src/mac/xpm/CrBufFrI.c
new file mode 100644 (file)
index 0000000..59b89c1
--- /dev/null
@@ -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                                                *
+\*****************************************************************************/
+
+#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)!=NULL) 
+           {
+#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/mac/xpm/CrDatFrI.c b/src/mac/xpm/CrDatFrI.c
new file mode 100644 (file)
index 0000000..3a21e3d
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * 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                                                *
+\*****************************************************************************/
+
+#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)!=NULL) {
+#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/mac/xpm/CrIFrBuf.c b/src/mac/xpm/CrIFrBuf.c
new file mode 100644 (file)
index 0000000..4b5ad72
--- /dev/null
@@ -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/mac/xpm/CrIFrDat.c b/src/mac/xpm/CrIFrDat.c
new file mode 100644 (file)
index 0000000..bb342d2
--- /dev/null
@@ -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/mac/xpm/Image.c b/src/mac/xpm/Image.c
new file mode 100644 (file)
index 0000000..9d4057a
--- /dev/null
@@ -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/mac/xpm/Info.c b/src/mac/xpm/Info.c
new file mode 100644 (file)
index 0000000..f15c6c9
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  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/mac/xpm/RdFToBuf.c b/src/mac/xpm/RdFToBuf.c
new file mode 100644 (file)
index 0000000..2745583
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * 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
+ */
+
+#ifdef macintosh
+       #ifdef __std
+               #undef __std
+               #define __std()
+       #endif
+       #include <unistd.h>
+       #include <stat.h>
+       #include <fcntl.h>
+       #include <unix.h>
+#endif
+
+#include "xpmi.h"
+#ifndef macintosh
+       #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
+#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/mac/xpm/RdFToDat.c b/src/mac/xpm/RdFToDat.c
new file mode 100644 (file)
index 0000000..58a97c4
--- /dev/null
@@ -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/mac/xpm/RdFToI.c b/src/mac/xpm/RdFToI.c
new file mode 100644 (file)
index 0000000..83bf922
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * 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                                                *
+\*****************************************************************************/
+
+#ifdef macintosh
+       #ifdef __std
+               #undef __std
+               #define __std()
+       #endif
+       #include <unistd.h>
+       #include <stat.h>
+       #include <fcntl.h>
+       #include <unix.h>
+       #undef NO_ZPIPE
+       #define NO_ZPIPE
+#endif
+
+#include "xpmi.h"
+#ifndef macintosh
+#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
+#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 *compressfile, buf[BUFSIZ];
+# ifdef STAT_ZFILE
+    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/mac/xpm/WrFFrBuf.c b/src/mac/xpm/WrFFrBuf.c
new file mode 100644 (file)
index 0000000..907100a
--- /dev/null
@@ -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/mac/xpm/WrFFrDat.c b/src/mac/xpm/WrFFrDat.c
new file mode 100644 (file)
index 0000000..eaf5eec
--- /dev/null
@@ -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/mac/xpm/WrFFrI.c b/src/mac/xpm/WrFFrI.c
new file mode 100644 (file)
index 0000000..be88120
--- /dev/null
@@ -0,0 +1,363 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+*  WrFFrI.c:                                                                  *
+*                                                                             *
+*  XPM library                                                                *
+*  Write an image and possibly its mask to an XPM file                        *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#include "xpmi.h"
+#ifdef macintosh
+       #undef NO_ZPIPE
+       #define NO_ZPIPE
+#endif
+#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 (dot = index(name, '.')) {
+           strcpy(new_name, name);
+           /* change '.' to '_' */
+           name = s = new_name;
+           while (dot = index(s, '.')) {
+               *dot = '_';
+               s = dot;
+           }
+       }
+       if (dot = 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/mac/xpm/XpmI.h b/src/mac/xpm/XpmI.h
new file mode 100644 (file)
index 0000000..b50e38a
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* XpmI.h:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Internal Include file                                                      *
+*                                                                             *
+*  ** Everything defined here is subject to changes any time. **              *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+#ifndef XPMI_h
+#define XPMI_h
+
+#include "xpm.h"
+
+#ifdef macintosh
+       #undef index
+       #undef rindex
+       #undef bzero
+       #undef bcopy    
+#endif
+
+/*
+ * 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
+
+#if defined(SYSV) || defined(SVR4) || defined(VMS) || defined(WIN32) || defined( macintosh )
+#include <string.h>
+
+#ifndef index
+#define index strchr
+#endif
+
+#ifndef rindex
+#define rindex strrchr
+#endif
+
+#else  /* defined(SYSV) || defined(SVR4) || defined(VMS) */
+#include <strings.h>
+#endif
+
+
+
+#if defined(SYSV) || defined(SVR4) || defined(VMS) || defined(WIN32) || defined( macintosh )
+#ifndef bcopy
+#define bcopy(source, dest, count) memcpy(dest, source, count)
+#endif
+#ifndef bzero
+#define bzero(b, len) memset(b, 0, len)
+#endif
+#endif
+
+/* the following is defined in X11R6 but not in previous versions */
+#ifdef __alpha
+#ifndef LONG64
+#define LONG64
+#endif
+#endif
+
+#ifdef VMS
+#include <unixio.h>
+#include <file.h>
+#endif
+
+/* The following should help people wanting to use their own memory allocation
+ * functions. To avoid the overhead of a function call when the standard
+ * functions are used these are all macros, even the XpmFree function which
+ * needs to be a real function for the outside world though.
+ * So if change these be sure to change the XpmFree function in misc.c
+ * accordingly.
+ */
+#define XpmFree(ptr) free(ptr)
+
+#ifndef FOR_MSW
+#define XpmMalloc(size) malloc((size))
+#define XpmRealloc(ptr, size) realloc((ptr), (size))
+#define XpmCalloc(nelem, elsize) calloc((nelem), (elsize))
+#else
+/* checks for mallocs bigger than 64K */
+#define XpmMalloc(size) boundCheckingMalloc((long)(size))/* in simx.[ch] */
+#define XpmRealloc(ptr, size) boundCheckingRealloc((ptr),(long)(size))
+#define XpmCalloc(nelem, elsize) \
+               boundCheckingCalloc((long)(nelem),(long) (elsize))
+#endif
+
+#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));
+
+/* 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 *)i)
+#define HashColorIndex(slot) ((unsigned int)((*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));
+
+FUNC(xpmGetRGBfromName,int, (char *name, int *r, int *g, int *b));
+
+#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/mac/xpm/create.c b/src/mac/xpm/create.c
new file mode 100644 (file)
index 0000000..b529e65
--- /dev/null
@@ -0,0 +1,1258 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* create.c:                                                                   *
+*                                                                             *
+*  XPM library                                                                *
+*  Create an X image and possibly its related shape mask                      *
+*  from the given XpmImage.                                                   *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#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));
+
+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));
+
+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));
+
+LFUNC(PlatformPutImagePixels, void, (Display *dc, XImage *image,
+                               unsigned int width, unsigned int height,
+                               unsigned int *pixelindex, Pixel *pixels));
+
+
+#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;
+{
+    return (XPM_COLOR);
+}
+
+
+typedef struct {
+    int cols_index;
+    long closeness;
+}      CloseColor;
+
+static int
+closeness_cmp(a, b)
+    Const void *a, *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;
+}
+
+/*
+ * 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) {
+                       return (1);
+               } else
+                   alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel;
+               *image_pixel = xcolor.pixel;
+
+               SET_ZERO_PIXEL( *mask_pixel );
+
+               used_pixels[(*nused_pixels)++] = xcolor.pixel;
+       } 
+       else 
+       {
+               // this is a special for mac - we have to get white as background for transparency
+               #ifdef macintosh
+               SET_WHITE_PIXEL( *image_pixel) ;
+               #else
+               SET_ZERO_PIXEL( *image_pixel);
+               #endif
+               SET_WHITE_PIXEL( *mask_pixel) ;
+
+               /* 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;
+    unsigned int numsymbols;
+    XpmAllocColorFunc allocColor;
+    void *closure;
+
+    char *colorname;
+    unsigned int color, key;
+    Bool pixel_defined;
+    XpmColorSymbol *symbol;
+    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;
+
+    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)) 
+               {
+                       SET_ZERO_PIXEL( *mask_pixels ) ;
+                       *mask_pixel_index = color;
+           } 
+           else
+           {
+               #ifdef macintosh
+                       SET_WHITE_PIXEL( *mask_pixels ) ; // is this correct CS ????
+                       #else
+                       *mask_pixels = 1; // is this correct CS ????
+                       #endif
+               }
+           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);
+
+       PlatformPutImagePixels(display, ximage, image->width, image->height,
+                         image->data, image_pixels);
+
+    }
+    /* 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);
+
+       PlatformPutImagePixels(display, shapeimage, image->width, image->height,
+                         image->data, mask_pixels);
+
+    }
+    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);
+
+    /* XCreateImage has done it all */
+
+    return (XpmSuccess);
+}
+
+static void
+PlatformPutImagePixels(dc, image, width, height, pixelindex, pixels)
+    Display *dc;
+    XImage *image;
+    unsigned int width;
+    unsigned int height;
+    unsigned int *pixelindex;
+    Pixel *pixels;
+{
+
+#ifdef FOR_MSW
+    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);
+#elif macintosh
+       GrafPtr         origPort ;
+       GDHandle        origDevice ;
+       
+    unsigned int *data = pixelindex;
+    unsigned int x, y;
+
+       GetGWorld( &origPort , &origDevice ) ;
+       SetGWorld( image->gworldptr , NULL ) ;
+
+    for (y = 0; y < height; y++) 
+    {
+               for (x = 0; x < width; x++) 
+               {
+               SetCPixel( x, y, &pixels[*(data++)]); // data is [x+y*width] 
+               }
+    }
+    SetGWorld( origPort , origDevice ) ;
+#endif
+}
+
+/*
+ * 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);
+
+    }
+
+    /* 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);
+
+    }
+
+    /*
+     * read pixels and put them in the XImage
+     */
+    ErrorStatus = ParseAndPutPixels(
+                                   display,
+                                   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(
+                 dc,
+                 data, width, height, ncolors, cpp, colorTable, hashtable,
+                 image, image_pixels, shapeimage, shape_pixels)
+    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 *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);
+
+               #elif macintosh
+               GrafPtr         origPort ;
+               GDHandle        origDevice ;
+               
+               GetGWorld( &origPort , &origDevice ) ;
+               // ignore shapedc
+               SetGWorld( image->gworldptr , NULL ) ;
+               
+               #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) 
+                               {
+                                       #if FOR_MSW
+                                       SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]);
+                                       if (shapedc) 
+                                       {
+                                           SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
+                                       }
+                                       #elif macintosh
+                                       SetCPixel( x, y, &image_pixels[colidx[c] - 1]);
+                                       /*
+                                       if (shapedc) 
+                                       {
+                                           SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]);
+                                       }
+                                       */
+                                       #endif
+                               } 
+                               else
+                                       return (XpmFileInvalid);
+                       }
+           }
+               #if FOR_MSW
+           if ( shapedc ) 
+           {
+               SelectObject(shapedc, sobm);
+                       DeleteDC(shapedc);
+           }
+           SelectObject(*dc, obm);
+               #elif macintosh
+       SetGWorld( origPort , origDevice ) ;
+               #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;
+               #ifdef macintosh
+               GrafPtr         origPort ;
+               GDHandle        origDevice ;
+               GetGWorld( &origPort , &origDevice ) ;
+               SetGWorld( image->gworldptr , NULL ) ;
+               #endif
+           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 */
+                       #ifdef macintosh
+               SetGWorld( origPort , origDevice ) ;
+                       #endif
+                       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) {
+
+                       #ifdef FOR_MSW
+                       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]);
+                       }
+                       #elif macintosh
+                       SetCPixel( x, y, &image_pixels[cidx[cc1][cc2] - 1]);  
+                       #endif
+                       } else 
+                       {
+                               #ifdef macintosh
+                       SetGWorld( origPort , origDevice ) ;
+                               #endif
+                           FREE_CIDX;
+                           return (XpmFileInvalid);
+                       }
+                   } else {
+                               #ifdef macintosh
+                       SetGWorld( origPort , origDevice ) ;
+                               #endif
+                       FREE_CIDX;
+                       return (XpmFileInvalid);
+                   }
+               }
+           }
+               #ifdef macintosh
+               SetGWorld( origPort , origDevice ) ;
+               #endif
+           FREE_CIDX;
+       }
+       break;
+
+    default:                           /* Non-optimized case of long color
+                                        * names */
+       {
+           char *s;
+           char buf[BUFSIZ];
+               #ifdef macintosh
+               GrafPtr         origPort ;
+               GDHandle        origDevice ;
+               GetGWorld( &origPort , &origDevice ) ;
+               SetGWorld( image->gworldptr , NULL ) ;
+               #endif
+
+           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 */
+                       {
+                               #ifdef macintosh
+                       SetGWorld( origPort , origDevice ) ;
+                               #endif
+                           return (XpmFileInvalid);
+                       }
+
+                       #if FOR_MSW
+                       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)]);
+                       }
+                       #elif macintosh
+                       SetCPixel( x, y, &image_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 */
+                       {
+                               #ifdef macintosh
+                       SetGWorld( origPort , origDevice ) ;
+                               #endif
+                           return (XpmFileInvalid);
+                       }
+                       
+                       #if FOR_MSW
+                       SelectObject(*dc, image->bitmap);
+                       SetPixel(*dc, x, y, image_pixels[a]);
+                       if (shapeimage) {
+                           SelectObject(*dc, shapeimage->bitmap);
+                           SetPixel(*dc, x, y, shape_pixels[a]);
+                       }
+                       #elif macintosh
+               SetCPixel( x, y, &image_pixels[a]); // data is [x+y*width] 
+                       #endif
+                   }
+               }
+           }
+               #ifdef macintosh
+       SetGWorld( origPort , origDevice ) ;
+               #endif
+
+       }
+       break;
+    }
+    return (XpmSuccess);
+}
diff --git a/src/mac/xpm/data.c b/src/mac/xpm/data.c
new file mode 100644 (file)
index 0000000..b26f3eb
--- /dev/null
@@ -0,0 +1,487 @@
+/*
+ * 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                                                *
+\*****************************************************************************/
+
+#ifndef CXPMPROG
+/* Official version number */
+static char *RCS_Version = "$XpmVersion: 3.4k $";
+
+/* Internal version number */
+static char *RCS_Id = "$Id$";
+
+#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(data)
+    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++)!=NULL && c != data->Eos)
+           {}
+
+       /*
+        * then get to the beginning of the next string looking for possible
+        * comment
+        */
+       if (data->Bos) {
+           while ((c = *data->cptr++)!=NULL  && 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))!=NULL  != 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)!=NULL  && 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",
+#ifdef VMS
+    NULL
+#else
+    NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL
+#endif
+};
+
+/*
+ * 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';
+           #ifdef macintosh
+           ptr = strrchr(buf, '_');
+           #else
+           ptr = rindex(buf, '_');
+           #endif
+           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/mac/xpm/hashtab.c b/src/mac/xpm/hashtab.c
new file mode 100644 (file)
index 0000000..bea343d
--- /dev/null
@@ -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/mac/xpm/macx.c b/src/mac/xpm/macx.c
new file mode 100644 (file)
index 0000000..3f83af3
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * Copyright (C) 1998 Stefan Csomor
+ *
+ * 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 "macx.h"
+#include "simx.h"
+
+XImage *
+AllocXImage (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth)
+{
+    XImage  *img;
+    
+    img = XpmMalloc (sizeof (*img));
+    if (img != NULL)
+    {
+                       Rect rect ;
+                       rect.left = rect.top = 0 ;
+                       rect.bottom = height ;
+                       rect.right = width ;
+
+                       img->width = width;
+                       img->height = height;
+                       
+               
+                       NewGWorld( &img->gworldptr , depth , &rect , NULL , NULL , 0 ) ;
+                       if (img->gworldptr == NULL)
+                       {
+                       XDestroyImage (img);
+                       return NULL;
+                       }
+    }
+    
+    return img;
+}
+
+/*
+
+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/mac/xpm/macx.cpp b/src/mac/xpm/macx.cpp
new file mode 100644 (file)
index 0000000..bf8f457
--- /dev/null
@@ -0,0 +1,488 @@
+/*
+ * Copyright (C) 1998 Stefan Csomor
+ *
+ * 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                                                               *
+\*****************************************************************************/
+
+/*
+extern "C" 
+{
+       #include "XpmI.h"
+       #include "macx.h"
+} ;
+
+XImage * AllocXImage (
+    unsigned int   width,
+    unsigned int   height,
+    unsigned int   depth)
+{
+    XImage  *img;
+    
+    img = (XImage*) XpmMalloc (sizeof (*img));
+    if (img != NULL)
+    {
+               Rect rect = { 0 , 0 , height , width } ;
+
+               img->width = width;
+               img->height = height;
+               
+       
+               NewGWorld( &img->gworldptr , depth , &rect , NULL , NULL , 0 ) ;
+               if (img->gworldptr == NULL)
+               {
+               XDestroyImage (img);
+               return NULL;
+               }
+    }
+    
+    return img;
+}
+
+
+int XDestroyImage ( XImage  *ximage)
+{
+    if (ximage != NULL)
+    {
+               if ( ximage->gworldptr )
+                       DisposeGWorld( ximage->gworldptr ) ;
+
+               XpmFree (ximage);
+    }
+    
+    return Success;
+}
+
+Status XAllocColor( Display dpy, Colormap colormap, XColor  *c ) 
+{
+    unsigned long    pixel;
+    unsigned short   red, green, blue;
+       c->pixel = ( ( (c->red)>>8 ) << 16 ) +  ( ( (c->green)>>8 ) << 8 ) +  ( ( (c->blue)>>8 ) ) ;
+    return Success;
+}
+
+int XFreeColors(Display dpy, Colormap colormap, unsigned long  *pixels, 
+       int npixels, int planes) 
+{
+    return Success;
+}
+
+int XParseColor(Display dpy, Colormap colormap, 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
+       {
+       }
+       return FALSE ;
+}
+
+int XQueryColor(Display dpy, Colormap colormap, XColor *c) 
+{
+       c->pixel = ( ( (c->red)>>8 ) << 16 ) +  ( ( (c->green)>>8 ) << 8 ) +  ( ( (c->blue)>>8 ) ) ;
+
+    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 XQueryColors(Display dpy, Colormap colormap, XColor *defs_in_out, int ncolors) 
+{
+    int   i;
+    
+    for (i = 0; i < ncolors; i++)
+               XQueryColor (dpy, colormap , &defs_in_out[i]);
+    
+    return Success;
+}
+
+int XPutPixel ( XImage *ximage,int  x,int y,unsigned long   pixel)
+{
+       
+       CGrafPtr        origPort ;
+       GDHandle        origDev ;
+       
+       GetGWorld( &origPort , &origDev ) ;
+       SetGWorld( ximage->gworldptr , NULL ) ;
+       RGBColor color ;
+       color.red = (pixel & 0x00FF0000) >> 16 ;
+       color.green = (pixel & 0x0000FF00) >> 8 ;
+       color.blue =  (pixel & 0x000000FF) ;
+       color.red = ( color.red<<8) + color.red ;
+       color.green = ( color.green<<8) + color.green ;
+       color.blue = ( color.blue<<8) + color.blue ;
+       SetCPixel( x , y , &color ) ;
+       SetGWorld( origPort , origDev ) ;
+    return Success;
+}
+*/
+/*
+
+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);
+    }
+}
+
+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/mac/xpm/macx.h b/src/mac/xpm/macx.h
new file mode 100644 (file)
index 0000000..308712b
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 1998 Stefan Csomor, 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.
+ */
+
+/*****************************************************************************\
+* macx.h:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Emulates some Xlib functionality for MacOS.                                *
+*                                                                             *
+*  Developed by Stefan Csomor csomor@advanced.ch,                             *
+*  Amiga version by Lorens Younes (d93-hyo@nada.kth.se)                       *
+*  1.00 10/11/98 Initial attempt ;-)                                          *
+\*****************************************************************************/
+
+#ifndef MAC_X
+#define MAC_X
+
+#define Success   0
+
+/* really never used */
+#define ZPixmap   2
+
+#define Bool     int
+#define Status   int
+#define True     1
+#define False    0
+
+typedef CTabHandle     Colormap;
+
+typedef void  *Visual;
+
+typedef struct {
+       int                     width, height;
+               GWorldPtr                       gworldptr ;
+}   XImage;
+
+typedef struct {
+    unsigned long    pixel;
+    unsigned short   red, green, blue;
+}   XColor;
+
+typedef GDevice*       Display; // actually this is a entire workstation (analogon x-server)
+
+#define XGrabServer(dpy)     /*GrabServer*/
+#define XUngrabServer(dpy)   /*UngrabServer*/
+
+#define XDefaultScreen(dpy)          (GetMainDevice())
+#define XDefaultVisual(dpy, scr)     (NULL)
+#define XDefaultColormap(dpy, scr)   ((**((*dpy)->gdPMap)).pmTable)
+#define XDefaultDepth(dpy, scr)      ((**((*dpy)->gdPMap)).pixelSize)
+
+#define XCreateImage(dpy, vi, depth, format, offset, data, width, height, pad, bpl) \
+       (AllocXImage (width, height, depth))
+int XDestroyImage(XImage  *ximage) ;
+
+Status XAllocColor( Display dpy, Colormap colormap, XColor  *screen_in_out ) ;
+int XFreeColors(Display dpy, Colormap colormap, unsigned long  *pixels, int npixels, int planes) ;
+Status XParseColor(Display dpy, Colormap colormap, char *spec, XColor *exact_def_return) ;
+int XQueryColor(Display dpy, Colormap colormap, XColor *def_in_out) ;
+int XQueryColors(Display dpy, Colormap colormap, XColor *defs_in_out, int ncolors) ;
+XImage * AllocXImage (unsigned int   width, unsigned int   height,unsigned int   depth);
+int XPutPixel ( XImage *ximage,int  x,int y,unsigned long   pixel);
+
+#endif
diff --git a/src/mac/xpm/misc.c b/src/mac/xpm/misc.c
new file mode 100644 (file)
index 0000000..868c447
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* misc.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Miscellaneous utilities                                                    *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+#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/mac/xpm/parse.c b/src/mac/xpm/parse.c
new file mode 100644 (file)
index 0000000..c771689
--- /dev/null
@@ -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.
+ */
+
+/*****************************************************************************\
+* parse.c:                                                                    *
+*                                                                             *
+*  XPM library                                                                *
+*  Parse an XPM file or array and store the found informations                *
+*  in the given XpmImage structure.                                           *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+#include "xpmi.h"
+#include <ctype.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) {
+           #ifdef macintosh // we have a strange parameter problem here
+               ptr = strchr(ptr, '_'); // index
+           #else
+               ptr = index(ptr, '_'); 
+               #endif
+               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, 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))!=NULL ) {
+               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))!=NULL ) {
+               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))!=NULL 
+          && (notend = strncmp("XPMENDEXT", string, 9))!=NULL ) {
+       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))!=NULL 
+              && (notend = strncmp("XPMENDEXT", string, 9))!=NULL ) {
+           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/mac/xpm/rgb.c b/src/mac/xpm/rgb.c
new file mode 100644 (file)
index 0000000..0a0ae38
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+ * 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>
+
+#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
+ */
+/* portable rgb values have 16 bit unsigned value range for each color these are promoted from the table */
+
+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, ' '))!=NULL) {
+       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"))!=NULL)
+       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
+     */
+
+#ifdef FOR_MSW
+    *r = 255;
+    *g = 0;
+    *b = 0;                            /* red error pixel */
+#else
+    *r = 0xFFFF;
+    *g = 0;
+    *b = 0;                            /* red error pixel */
+#endif
+    free(name);
+    return (1);
+}
+
+void
+xpmFreeRgbNames(rgbn, rgbn_max)
+    xpmRgbName rgbn[];
+    int rgbn_max;
+
+{
+    /* nothing to do */
+}
diff --git a/src/mac/xpm/rgbtab.h b/src/mac/xpm/rgbtab.h
new file mode 100644 (file)
index 0000000..717dfe4
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * 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;
+    unsigned long rgb;                 /* it's unsigned long */
+}      rgbRecord;
+
+/*
+#define myRGB(r,g,b) \
+       ((unsigned long)r<<16|(unsigned long)g<<8|(unsigned long)b)
+*/
+#ifdef FOR_MSW
+#define myRGB(r,g,b)   RGB(r,g,b)      /* MSW has this macro */
+#else
+#define myRGB(r,g,b)((r<<16)+(g<<8)+(b))
+#define GetRValue(c) ((((c&0x00FF0000)>>16)<<8)+((c&0x00FF0000)>>16))
+#define GetGValue(c) ((((c&0x0000FF00)>>8)<<8)+((c&0x0000FF00)>>8))
+#define GetBValue(c) (((c&0x000000FF)<<8)+(c&0x000000FF))
+#endif
+
+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/mac/xpm/scan.c b/src/mac/xpm/scan.c
new file mode 100644 (file)
index 0000000..ebab00d
--- /dev/null
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* scan.c:                                                                     *
+*                                                                             *
+*  XPM library                                                                *
+*  Scanning utility for XPM file format                                       *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#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));
+
+LFUNC(PlatformGetImagePixels, int, (Display *d, XImage *image, unsigned int width,
+                              unsigned int height, PixelsMap *pmap,
+                              int (*storeFunc) ()));
+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 ( IS_EQUAL_PIXEL(*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 (IS_ZERO_PIXEL(pixel)) {
+       if (!pmap->ncolors) {
+           pmap->ncolors = 1;
+           SET_ZERO_PIXEL((pmap->pixels)[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;
+
+    /* 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) {
+
+       ErrorStatus = PlatformGetImagePixels(display, shapeimage, width, height,
+                                       &pmap, storeMaskPixel);
+
+       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) {
+
+       ErrorStatus = PlatformGetImagePixels(display, image, width, height, &pmap,
+                                       storePixel);
+
+       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;
+
+    xpmRgbName *rgbn = NULL; 
+
+    int rgbn_max = 0;
+    unsigned int i, j, c, i2;
+    XpmColor *color;
+    XColor *xcolors = NULL, *xcolor;
+    char *colorname, *s;
+    XpmColor *colorTable, **oldColorTable = NULL;
+    unsigned int ancolors = 0;
+    Pixel *apixels;
+    unsigned int mask_pixel;
+    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);
+
+    rgbn_max = xpmReadRgbNames(NULL, NULL);
+
+    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 (IS_EQUAL_PIXEL( 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];
+//             sprintf(buf, "#%04X%04X%04X",
+               sprintf(buf, "#%02x%02x%02x",
+                       xcolor->red, xcolor->green, xcolor->blue);
+
+               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);
+}
+
+
+static int
+PlatformGetImagePixels(display, image, width, height, pmap, storeFunc)
+    Display *display;
+    XImage *image;
+    unsigned int width;
+    unsigned int height;
+    PixelsMap *pmap;
+    int (*storeFunc) ();
+{
+       #if FOR_MSW
+    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);
+       }
+    }
+    #elif macintosh
+    #endif
+    return (XpmSuccess);
+}
diff --git a/src/mac/xpm/simx.c b/src/mac/xpm/simx.c
new file mode 100644 (file)
index 0000000..eac5bd3
--- /dev/null
@@ -0,0 +1,355 @@
+/*
+ * 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)                           *
+\*****************************************************************************/
+
+#include "xpm.h"
+#include "xpmi.h"                      /* for XpmMalloc */
+
+#ifdef FOR_MSW
+
+/*
+ * 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));
+       }
+    }
+}
+#endif
+
+/* 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)
+{
+#ifdef FOR_MSW
+    int d, b;
+
+    b = GetDeviceCaps(*display, BITSPIXEL);
+    d = GetDeviceCaps(*display, PLANES);
+    return (b);
+#else
+       return (**((*display)->gdPMap)).pixelSize ;
+#endif
+}
+
+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]);
+               #ifdef macintosh
+               *r <<= 12 ;
+               *g <<= 12 ;
+               *b <<= 12 ;
+               #endif
+    } 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]);
+               #ifdef macintosh
+               *r <<= 8 ;
+               *g <<= 8 ;
+               *b <<= 8 ;
+               #endif
+    } else if (len == 12 + 1) 
+    {
+               /* it's like c #32329999CCCC */
+               #ifdef macintosh
+               *r = hexCharToInt(hex[1]) * 0x1000 + hexCharToInt(hex[2]) *0x0100 + hexCharToInt(hex[3]) *0x0010 + hexCharToInt(hex[4]) ;
+               *g = hexCharToInt(hex[5]) * 0x1000 + hexCharToInt(hex[6]) *0x0100 + hexCharToInt(hex[7]) *0x0010 + hexCharToInt(hex[8]);
+               *b =hexCharToInt(hex[9]) * 0x1000 + hexCharToInt(hex[10]) *0x0100 + hexCharToInt(hex[11]) *0x0010 + hexCharToInt(hex[12]);
+               #else
+               /* 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]);
+               #endif
+    } 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) 
+    {
+       #ifdef FOR_MSW
+                       color->pixel = RGB(r, g, b);
+                       color->red = (BYTE) r;
+                       color->green = (BYTE) g;
+                       color->blue = (BYTE) b;
+       #elif macintosh
+               color->pixel.red = r ;
+               color->pixel.green = g ;
+               color->pixel.blue = b ;
+               
+                       color->red = r;
+                       color->green = g;
+                       color->blue = b;
+       #endif
+               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) 
+    {
+    #if FOR_MSW
+       /*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);
+               }
+       #elif macintosh
+               Rect rect ;
+               
+               rect.left= rect.top = 0 ;
+               rect.right = width ;
+               rect.bottom = height ;
+               
+               NewGWorld( &img->gworldptr , depth , &rect , NULL , NULL , 0 ) ;
+               if (img->gworldptr == NULL)
+               {
+               XDestroyImage (img);
+               return NULL;
+               }
+/*
+               else
+               {
+                       RGBColor                gray = { 0xEEEE ,0xEEEE , 0xEEEE } ;
+                       RGBBackColor( &gray ) ;
+                       EraseRect(&rect) ;
+               }
+*/
+       #endif
+       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) {
+    #if FOR_MSW
+       DeleteObject(img->bitmap);      /* check return ??? */
+       #elif macintosh
+       if ( img->gworldptr )
+               DisposeGWorld( img->gworldptr ) ;
+       #endif
+       XImageFree(img);
+    }
+}
+
diff --git a/src/mac/xpm/simx.h b/src/mac/xpm/simx.h
new file mode 100644 (file)
index 0000000..a70ad18
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * 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
+
+#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
+
+#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 */
+
+
+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;
+
+#elif macintosh
+
+/* define Mac types for X window types */
+
+typedef GDevice* 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 RGBColor Pixel;
+
+#define PIXEL_ALREADY_TYPEDEFED                /* to let xpm.h know about it */
+
+typedef struct {
+    Pixel pixel;
+    unsigned short   red, green, blue;
+}      XColor;
+
+typedef struct {
+       GWorldPtr                       gworldptr ;
+    unsigned int width;
+    unsigned int height;
+    unsigned int depth;
+}      XImage;
+
+#endif
+
+#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
+#ifdef FOR_MSW
+typedef BOOL Bool;             /* take MSW bool */
+#elif macintosh
+typedef Boolean Bool;          /* take MSW bool */
+#endif
+#endif
+/* make these local here, simx.c gets the same from xpm.h */
+#undef LFUNC
+#undef FUNC
+
+#endif /* _SIMX_H */
diff --git a/src/mac/xpm/xpm.h b/src/mac/xpm/xpm.h
new file mode 100644 (file)
index 0000000..1680f63
--- /dev/null
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 1989-95 GROUPE BULL
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of GROUPE BULL shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from GROUPE BULL.
+ */
+
+/*****************************************************************************\
+* xpm.h:                                                                      *
+*                                                                             *
+*  XPM library                                                                *
+*  Include file                                                               *
+*                                                                             *
+*  Developed by Arnaud Le Hors                                                *
+\*****************************************************************************/
+
+/*
+ * The code related to FOR_MSW has been added by
+ * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94
+ */
+
+/*
+ * The code related to AMIGA has been added by
+ * Lorens Younes (d93-hyo@nada.kth.se) 4/96
+ */
+
+#ifndef XPM_h
+#define XPM_h
+
+/*
+ * first some identification numbers:
+ * the version and revision numbers are determined with the following rule:
+ * SO Major number = LIB minor version number.
+ * SO Minor number = LIB sub-minor version number.
+ * e.g: Xpm version 3.2f
+ *      we forget the 3 which is the format number, 2 gives 2, and f gives 6.
+ *      thus we have XpmVersion = 2 and XpmRevision = 6
+ *      which gives  SOXPMLIBREV = 2.6
+ *
+ * Then the XpmIncludeVersion number is built from these numbers.
+ */
+#define XpmFormat 3
+#define XpmVersion 4
+#define XpmRevision 11
+#define XpmIncludeVersion ((XpmFormat * 100 + XpmVersion) * 100 + XpmRevision)
+
+#ifndef XPM_NUMBERS
+
+#ifdef FOR_MSW
+#define IS_EQUAL_PIXEL( a , b ) ( a == b )
+#define IS_ZERO_PIXEL(a) (!(a) )
+#define SET_ZERO_PIXEL(a) { (a)  = 0 }
+#define SET_WHITE_PIXEL(a) { (a)  = 0 }
+# 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++ */
+#elif AMIGA
+#define IS_EQUAL_PIXEL( a , b ) ( a == b )
+#define IS_ZERO_PIXEL(a) (!(a) )
+#define SET_ZERO_PIXEL(a) { (a)  = 0 }
+#define SET_WHITE_PIXEL(a) { (a)  = 0 }
+#  include "amigax.h"
+#elif macintosh
+#define IS_EQUAL_PIXEL( a , b ) ( (a).red == (b).red && (a).green == (b).green && (a).blue == (b).blue )
+#define IS_ZERO_PIXEL(a) (!(a).red && !(a).green && !(a).blue )
+#define SET_ZERO_PIXEL(a) { (a).red = 0 ; (a).green = 0 ;(a).blue = 0 ;}
+#define SET_WHITE_PIXEL(a) { (a).red = 0xFFFF ; (a).green = 0xFFFF ;(a).blue = 0xFFFF ;}
+#  include "simx.h"            
+#  define NEED_STRCASECMP
+#  define NEED_STRDUP
+#else
+#define IS_EQUAL_PIXEL( a , b ) ( a == b )
+#define IS_ZERO_PIXEL(a) (!(a) )
+#define SET_ZERO_PIXEL(a) { (a)  = 0 }
+#define SET_WHITE_PIXEL(a) { (a)  = 0 }
+#  include <X11/Xlib.h>
+#  include <X11/Xutil.h>
+#endif
+
+/* 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
+
+
+    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));
+
+    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, ());
+    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, ());
+
+    /* XpmImage functions */
+    FUNC(XpmReadFileToXpmImage, int, (char *filename,
+                                     XpmImage *image,
+                                     XpmInfo *info));
+
+    FUNC(XpmWriteFileFromXpmImage, int, (char *filename,
+                                        XpmImage *image,
+                                        XpmInfo *info));
+
+    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));
+
+    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