From cbda6dc9cd6a8a8268b26ee7973bb6040b4739d3 Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:46:11 +0900 Subject: [PATCH 1/1] Initialize Tizen 2.3 --- AUTHORS | 3 + COPYING | 70 ++ COPYRIGHT | 31 + ChangeLog | 896 ++++++++++++++++++ INSTALL | 291 ++++++ Makefile.am | 23 + NEWS.old | 957 +++++++++++++++++++ README | 25 + configure.ac | 69 ++ cxpm/Makefile.am | 15 + cxpm/cxpm.c | 177 ++++ doc/FAQ.html | 344 +++++++ doc/Makefile.am | 6 + doc/README.AMIGA | 10 + doc/README.MSW | 127 +++ doc/README.html | 303 ++++++ doc/xpm.PS.gz | Bin 0 -> 49010 bytes include/Makefile.am | 1 + include/X11/xpm.h | 477 ++++++++++ m4/ax_define_dir.m4 | 49 + man/Makefile.am | 34 + man/cxpm.man | 49 + man/sxpm.man | 131 +++ packaging/libXpm.spec | 69 ++ src/Attrib.c | 308 ++++++ src/CrBufFrI.c | 449 +++++++++ src/CrBufFrP.c | 77 ++ src/CrDatFrI.c | 403 ++++++++ src/CrDatFrP.c | 77 ++ src/CrIFrBuf.c | 117 +++ src/CrIFrDat.c | 122 +++ src/CrIFrP.c | 58 ++ src/CrPFrBuf.c | 78 ++ src/CrPFrDat.c | 81 ++ src/CrPFrI.c | 62 ++ src/Image.c | 62 ++ src/Info.c | 125 +++ src/Makefile.am | 43 + src/RdFToBuf.c | 124 +++ src/RdFToDat.c | 68 ++ src/RdFToI.c | 273 ++++++ src/RdFToP.c | 77 ++ src/WrFFrBuf.c | 60 ++ src/WrFFrDat.c | 62 ++ src/WrFFrI.c | 364 +++++++ src/WrFFrP.c | 77 ++ src/XpmI.h | 329 +++++++ src/amigax.c | 385 ++++++++ src/amigax.h | 151 +++ src/create.c | 2517 +++++++++++++++++++++++++++++++++++++++++++++++++ src/data.c | 481 ++++++++++ src/hashtab.c | 239 +++++ src/misc.c | 124 +++ src/parse.c | 805 ++++++++++++++++ src/rgb.c | 287 ++++++ src/rgbtab.h | 292 ++++++ src/scan.c | 1024 ++++++++++++++++++++ src/simx.c | 293 ++++++ src/simx.h | 154 +++ sxpm/Makefile.am | 25 + sxpm/plaid.xpm | 34 + sxpm/plaid_ext.xpm | 43 + sxpm/plaid_mask.xpm | 35 + sxpm/sxpm.c | 750 +++++++++++++++ xpm.pc.in | 12 + 65 files changed, 15304 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 COPYRIGHT create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 NEWS.old create mode 100644 README create mode 100644 configure.ac create mode 100644 cxpm/Makefile.am create mode 100644 cxpm/cxpm.c create mode 100644 doc/FAQ.html create mode 100644 doc/Makefile.am create mode 100644 doc/README.AMIGA create mode 100644 doc/README.MSW create mode 100644 doc/README.html create mode 100644 doc/xpm.PS.gz create mode 100644 include/Makefile.am create mode 100644 include/X11/xpm.h create mode 100644 m4/ax_define_dir.m4 create mode 100644 man/Makefile.am create mode 100644 man/cxpm.man create mode 100644 man/sxpm.man create mode 100755 packaging/libXpm.spec create mode 100644 src/Attrib.c create mode 100644 src/CrBufFrI.c create mode 100644 src/CrBufFrP.c create mode 100644 src/CrDatFrI.c create mode 100644 src/CrDatFrP.c create mode 100644 src/CrIFrBuf.c create mode 100644 src/CrIFrDat.c create mode 100644 src/CrIFrP.c create mode 100644 src/CrPFrBuf.c create mode 100644 src/CrPFrDat.c create mode 100644 src/CrPFrI.c create mode 100644 src/Image.c create mode 100644 src/Info.c create mode 100644 src/Makefile.am create mode 100644 src/RdFToBuf.c create mode 100644 src/RdFToDat.c create mode 100644 src/RdFToI.c create mode 100644 src/RdFToP.c create mode 100644 src/WrFFrBuf.c create mode 100644 src/WrFFrDat.c create mode 100644 src/WrFFrI.c create mode 100644 src/WrFFrP.c create mode 100644 src/XpmI.h create mode 100644 src/amigax.c create mode 100644 src/amigax.h create mode 100644 src/create.c create mode 100644 src/data.c create mode 100644 src/hashtab.c create mode 100644 src/misc.c create mode 100644 src/parse.c create mode 100644 src/rgb.c create mode 100644 src/rgbtab.h create mode 100644 src/scan.c create mode 100644 src/simx.c create mode 100644 src/simx.h create mode 100644 sxpm/Makefile.am create mode 100644 sxpm/plaid.xpm create mode 100644 sxpm/plaid_ext.xpm create mode 100644 sxpm/plaid_mask.xpm create mode 100644 sxpm/sxpm.c create mode 100644 xpm.pc.in diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..1f3e437 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Xpm was originally written by Groupe Bull, but maintainence has since passed +through the hands of XFree86, and to freedesktop.org; Daniel Stone is the +current maintainer. diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..af47549 --- /dev/null +++ b/COPYING @@ -0,0 +1,70 @@ +Copyright (C) 1989-95 GROUPE BULL + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of GROUPE BULL shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from GROUPE BULL. + +Copyright (C) 1998 Arnaud LE HORS + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +Arnaud LE HORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Arnaud LE HORS shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from Arnaud LE HORS. + +Copyright (C) 19896 Lorens Younes + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Lorens Younes shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from Lorens Younes. + + diff --git a/COPYRIGHT b/COPYRIGHT new file mode 100644 index 0000000..378d563 --- /dev/null +++ b/COPYRIGHT @@ -0,0 +1,31 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +Arnaud LE HORS BULL Research FRANCE -- Koala Project + (XPM - X PixMap format version 2 & 3) + Internet: lehors@sophia.inria.fr +Surface Mail: Arnaud LE HORS, INRIA - Sophia Antipolis, + 2004, route des Lucioles, 06565 Valbonne Cedex -- FRANCE + Voice phone: (33) 93.65.77.71, Fax: (33) 93 65 77 66, Telex: 97 00 50 F diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..5b2eaef --- /dev/null +++ b/ChangeLog @@ -0,0 +1,896 @@ +commit acaaea96776b36c097d5413040c5ce85d3ae6cb9 +Author: Alan Coopersmith +Date: Wed Mar 7 20:39:55 2012 -0800 + + libXpm 3.5.10 + + Signed-off-by: Alan Coopersmith + +commit 1450186652cb9d2efe55c8da7cb64996eddd34c7 +Author: Alan Coopersmith +Date: Fri Nov 18 23:25:16 2011 -0800 + + closeness_cmp: maintain constness when casting pointers + + create.c: In function 'closeness_cmp': + create.c:224:5: warning: cast discards qualifiers from pointer target type + create.c:224:5: warning: cast discards qualifiers from pointer target type + + Signed-off-by: Alan Coopersmith + +commit 7aa7b34491de534da56d637552ee86f94f038cc3 +Author: Alan Coopersmith +Date: Fri Nov 18 23:22:12 2011 -0800 + + sxpm: make ErrorMessage take const char * arg to fix -Wwrite-strings warnings + + Signed-off-by: Alan Coopersmith + +commit 4cedf181bcfe13e5d206554c51edb82cb17e7ad5 +Author: Jeremy Huddleston +Date: Fri Nov 11 10:17:11 2011 -0800 + + Include missing headers + + This fixes implicit declarations for strdup and strcasecmp. + + Signed-off-by: Jeremy Huddleston + +commit 933b5d1f1fe9273d1a984707687b36ec61c4c5af +Author: Alan Coopersmith +Date: Thu Nov 10 21:32:15 2011 -0800 + + Fix gcc -Wwrite-strings warnings that don't require public API changes + + Signed-off-by: Alan Coopersmith + +commit 696be14bcb4daef5280b425e297223c6ae530cb5 +Author: Alan Coopersmith +Date: Thu Nov 10 21:03:44 2011 -0800 + + Assume C89 and just use const, not local Const macro + + Signed-off-by: Alan Coopersmith + +commit 29972ebbb2409bcba87637069a7ad9a958b3325d +Author: Julien Cristau +Date: Sat Sep 24 19:18:56 2011 +0200 + + Link sxpm against -lX11 + + It calls various Xlib functions so should link with -lX11 directly. + + Signed-off-by: Julien Cristau + +commit 3ea70059805b3ebc795f797b5880b90b6b3a9235 +Author: Alan Coopersmith +Date: Fri Sep 16 22:48:53 2011 -0700 + + Strip trailing whitespace + + Performed with: find * -type f | xargs perl -i -p -e 's{[ \t]+$}{}' + git diff -w & git diff -b show no diffs from this change + + Signed-off-by: Alan Coopersmith + +commit 0c9e200c3975917f5d78eac67b1f4cedefd73079 +Author: Gaetan Nadon +Date: Sat Mar 5 20:39:03 2011 -0500 + + man: add missing title header (.TH) __xorgversion__ + + Signed-off-by: Gaetan Nadon + +commit 0f8f24302bb0e35eaab16f16358bf9c44f9f3af1 +Author: Gaetan Nadon +Date: Sat Mar 5 15:35:17 2011 -0500 + + config: move man pages into their own directory + + As per X.Org guidelines. + Fix whitespace issues. + + Signed-off-by: Gaetan Nadon + +commit 9c622c5fc82f2a19ae41e75398fee4ff1de52a1d +Author: Gaetan Nadon +Date: Wed Feb 2 11:43:44 2011 -0500 + + config: minor layout change in configure.ac + + Group statements per section as per Autoconf standard layout + Quote statements where appropriate. + No functional configuration changes + + This helps automated maintenance and release activities. + Details can be found in http://wiki.x.org/wiki/NewModuleGuidelines + + Signed-off-by: Gaetan Nadon + +commit 22a434d061af224536baee6c6110b603c5c96b2c +Author: Alan Coopersmith +Date: Fri Oct 29 17:29:25 2010 -0700 + + libXpm 3.5.9 + + Signed-off-by: Alan Coopersmith + +commit c11f1bd18303139f070e1873382632ee80cd9878 +Author: Gaetan Nadon +Date: Wed Oct 20 08:30:56 2010 -0400 + + config: remove obsolete FILES file from the Imakefile days + + It lists the files contained in the original + BULL Research Koala Project. + + Signed-off-by: Gaetan Nadon + +commit 0ea6c432a068fc4edf90c614e68a4f4be94edd14 +Author: Gaetan Nadon +Date: Sun Oct 17 12:51:15 2010 -0400 + + doc: move doc files to the newly created doc dir. + + As per guidelines for all xorg modules. + + Signed-off-by: Gaetan Nadon + +commit 7a3e69cfb079c7345f3d9b1217f373a706ba544c +Author: Gaetan Nadon +Date: Fri Oct 15 17:14:39 2010 -0400 + + config: provide a Makefile for the include directory + + Reduce some complexity in the src makefile as it should not + handle sibling directories. + + Signed-off-by: Gaetan Nadon + +commit e50f645f4cc5bb1db0e025fc6e39c6e84a894c13 +Author: Gaetan Nadon +Date: Fri Oct 15 14:56:32 2010 -0400 + + libXpm make: remove redundant -I. + + It is always included by Automake + + Signed-off-by: Gaetan Nadon + +commit 8dee37ff3bb908d597d53f2b335fc2111643cce7 +Author: Gaetan Nadon +Date: Sun Oct 24 19:39:54 2010 -0400 + + sxpm make: no need to use a per target LDADD + + There is only one program in this makefile. + + Signed-off-by: Gaetan Nadon + +commit 34abbaaacddf1018d1805bc4890226ab200a50fb +Author: Gaetan Nadon +Date: Fri Oct 15 11:45:58 2010 -0400 + + sxpm make: remove redundant $(XMP_LIBS) linker flags + + SXPM_LIBS contains the complete list of dependencies. + + Signed-off-by: Gaetan Nadon + +commit b818f5cf7f7d8240db2a94ebcc28603730760e48 +Author: Gaetan Nadon +Date: Fri Oct 15 10:21:08 2010 -0400 + + src make: remove -I$(top_builddir)/include + + This directory does not exist, only object code is created + in "builddir". + + Signed-off-by: Gaetan Nadon + +commit 78bca7e85b930593fefe85cc51b5e24f98de31d0 +Author: Gaetan Nadon +Date: Thu Oct 14 21:56:21 2010 -0400 + + config: fix warnings, m4 quoting and layout + + Fix some m4 quoting + Fix some autoconf warnings + Regroup statements per section + Add comments + + Signed-off-by: Gaetan Nadon + +commit 8e47c819490331c01959332e067f06a382d9a14a +Author: Gaetan Nadon +Date: Thu Oct 14 20:35:47 2010 -0400 + + config: AC_OUTPUT with parms is deprecated, use AC_CONFIG_FILES + + Signed-off-by: Gaetan Nadon + +commit c6915d034fa3f72a9724816d2e3f5e8432ef9321 +Author: Gaetan Nadon +Date: Thu Oct 14 20:33:40 2010 -0400 + + config: AC_HELP_STRING is deprecated, use AS_HELP_STRING + + Signed-off-by: Gaetan Nadon + +commit e2fdf80a7f9feedacf67e46a8e577b2e6d415a5f +Author: Gaetan Nadon +Date: Thu Oct 14 20:29:42 2010 -0400 + + config: remove unrequired AC_SUBST(XPM_CFLAGS) + + This macro is called by PKG_CHECK_MODULES + + Signed-off-by: Gaetan Nadon + +commit 937d8c8cf82bd57e82152af3768bdbfc5de4316a +Author: Gaetan Nadon +Date: Thu Oct 14 20:28:43 2010 -0400 + + config: remove AC_PROG_CC as it overrides AC_PROG_C_C99 + + XORG_STRICT_OPTION from XORG_DEFAULT_OPTIONS calls + AC_PROG_C_C99. This sets gcc with -std=gnu99. + If AC_PROG_CC macro is called afterwards, it resets CC to gcc. + + Signed-off-by: Gaetan Nadon + +commit 0ed9cb4546d0c65f08a9511736400c0f7fba982f +Author: Gaetan Nadon +Date: Thu Oct 14 20:28:08 2010 -0400 + + config: remove unrequired AC_HEADER_STDC + + Autoconf says: + "This macro is obsolescent, as current systems have conforming + header files. New programs need not use this macro". + + Signed-off-by: Gaetan Nadon + +commit e99bce47294eab031fc733d695e3c9589b52aff8 +Author: Gaetan Nadon +Date: Thu Oct 14 20:25:00 2010 -0400 + + config: replace deprecated AM_CONFIG_HEADER with AC_CONFIG_HEADERS + + Regroup AC statements at the top. + + Signed-off-by: Gaetan Nadon + +commit 0b5e15c685d295262bf2307d65bee3a0b28e74f5 +Author: Gaetan Nadon +Date: Thu Oct 14 20:15:08 2010 -0400 + + sxpm: use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS + The value of MAN_SUBST is the same for all X.Org packages. + + Use the appropriate platform version of sed + + Signed-off-by: Gaetan Nadon + +commit 262bb7e9426150f6c7b553d184c51d3884d04adf +Author: Gaetan Nadon +Date: Thu Oct 14 20:11:43 2010 -0400 + + cxpm: use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS + The value of MAN_SUBST is the same for all X.Org packages. + + Signed-off-by: Gaetan Nadon + +commit acd4856aac05a884376736196154842959803aa6 +Author: Gaetan Nadon +Date: Thu Oct 14 20:03:13 2010 -0400 + + config: use AC_PROG_INSTALL now supplied by XORG_DEFAULT_OPTIONS + + It depends on util-macros 1.8 + The LT_AC_PROG_SED macro was never released by libtool. + Neither man makefile actually used $SED anyway. + + Signed-off-by: Gaetan Nadon + +commit d1bd1fbc6d7f7b4817aca4fecd8ccfe80a1c2f03 +Author: Gaetan Nadon +Date: Thu Oct 14 20:02:30 2010 -0400 + + config: upgrade to util-macros 1.8 for additional man page support + + Use MAN_SUBST now supplied in XORG_MANPAGE_SECTIONS + The value of MAN_SUBST is the same for all X.Org packages. + + Signed-off-by: Gaetan Nadon + +commit 3b20344bf3c5ae7a8291041d4887dc8f23644d40 +Author: Colin Harrison +Date: Thu Oct 7 13:49:17 2010 +0200 + + Missing end comment in libXpm/src/parse.c + + CVS tag removal chopped too much out in this case... + + Signed-off-by: Julien Cristau + +commit f8f0a68247b920052df0796a39ebcdc2e4161d05 +Author: Jesse Adkins +Date: Tue Sep 28 13:30:03 2010 -0700 + + Purge cvs tags. + + Signed-off-by: Jesse Adkins + Signed-off-by: Alan Coopersmith + +commit d026662cce0808cf402e0d50932d90984a2ea1bb +Author: Gaetan Nadon +Date: Thu Apr 1 21:11:35 2010 -0400 + + config: update AC_PREREQ statement to 2.60 + + Unrelated to the previous patches, the new value simply reflects + the reality that the minimum level for autoconf to configure + all x.org modules is 2.60 dated June 2006. + + ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz + + Signed-off-by: Gaetan Nadon + +commit d4a7b15b3ed9e7cf94dbf64f929ae954bada9f60 +Author: Gaetan Nadon +Date: Thu Apr 1 21:07:54 2010 -0400 + + config: update and relocate AX_DEFINE_DIR macro + + Remove deprecated acinclude.m4 macro container file + Use separate macro files as per autoconf recommendation + Use the latest version of the macro from GNU + + Signed-off-by: Gaetan Nadon + +commit e0920779d1227338e61aaab16458b9daad508c36 +Author: Gaetan Nadon +Date: Mon Mar 29 14:53:49 2010 -0400 + + config: remove the pkgconfig pc.in file from EXTRA_DIST + + Automake always includes it in the tarball. + + Signed-off-by: Gaetan Nadon + +commit 34ebac912c6f1223a274ab2e4f0c12928d357ddd +Author: Gaetan Nadon +Date: Thu Jan 14 09:36:38 2010 -0500 + + COPYING: add missing copyright notices + + Refer to: amigax.c, cxpm.c + Copyright (C) 1998 Arnaud LE HORS + Copyright (C) 19896 Lorens Younes + + Signed-off-by: Gaetan Nadon + +commit dca7a9ccbdd4c85d84668c3a4bc14b0049f0c893 +Author: Gaetan Nadon +Date: Fri Nov 27 20:56:04 2009 -0500 + + Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES + + Now that the INSTALL file is generated. + Allows running make maintainer-clean. + +commit af0d92b686c65f7ffb5556b74fd937b01719c535 +Author: Gaetan Nadon +Date: Wed Oct 28 14:09:10 2009 -0400 + + INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206 + + Add missing INSTALL file. Use standard GNU file on building tarball + README may have been updated + Remove AUTHORS file as it is empty and no content available yet. + Remove NEWS file as it is empty and no content available yet. + +commit 8bda9cdb6344c6cdf87237cb84c16c54a3ae84d8 +Author: Gaetan Nadon +Date: Tue Oct 27 15:07:25 2009 -0400 + + Deploy the new XORG_DEFAULT_OPTIONS #24242 + + This macro aggregate a number of existing macros that sets commmon + X.Org components configuration options. It shields the configuration file from + future changes. + +commit 089237b624722b141a9ba6888584ebcc5247b227 +Author: Gaetan Nadon +Date: Mon Oct 26 22:08:43 2009 -0400 + + Makefile.am: ChangeLog not required: EXTRA_DIST or *CLEANFILES #24432 + + ChangeLog filename is known to Automake and requires no further + coding in the makefile. + +commit 37e75b28f4d30a66e16cfe192a0612a335aa8d46 +Author: Gaetan Nadon +Date: Thu Oct 22 12:34:19 2009 -0400 + + .gitignore: use common defaults with custom section # 24239 + + Using common defaults will reduce errors and maintenance. + Only the very small or inexistent custom section need periodic maintenance + when the structure of the component changes. Do not edit defaults. + +commit 68ae0e442ad57534c25566284ad049299a982d00 +Author: Jeremy Huddleston +Date: Wed Oct 21 12:47:25 2009 -0700 + + This is not a GNU project, so declare it foreign. + + On Wed, 2009-10-21 at 13:36 +1000, Peter Hutterer wrote: + > On Tue, Oct 20, 2009 at 08:23:55PM -0700, Jeremy Huddleston wrote: + > > I noticed an INSTALL file in xlsclients and libXvMC today, and it + > > was quite annoying to work around since 'autoreconf -fvi' replaces + > > it and git wants to commit it. Should these files even be in git? + > > Can I nuke them for the betterment of humanity and since they get + > > created by autoreconf anyways? + > + > See https://bugs.freedesktop.org/show_bug.cgi?id=24206 + + As an interim measure, replace AM_INIT_AUTOMAKE([dist-bzip2]) with + AM_INIT_AUTOMAKE([foreign dist-bzip2]). This will prevent the generation + of the INSTALL file. It is also part of the 24206 solution. + + Signed-off-by: Jeremy Huddleston + +commit 130b2fb0ea716143c63ba30856eecb351bc2af2a +Author: Alan Coopersmith +Date: Fri Oct 9 10:32:08 2009 -0700 + + libXpm 3.5.8 + + Signed-off-by: Alan Coopersmith + +commit a195bd6d375c311b9bf6d7cce477f1d131425757 +Author: Alan Coopersmith +Date: Thu Oct 8 21:29:45 2009 -0700 + + Migrate to xorg macros 1.3 & XORG_DEFAULT_OPTIONS + + Signed-off-by: Alan Coopersmith + +commit f4c43f70dff3cb9702fd62bc388353d02589e618 +Author: Alan Coopersmith +Date: Thu Oct 8 20:27:49 2009 -0700 + + Replace AC_DEFINE_DIR with AX_DEFINE_DIR from Autoconf Archive + +commit d846316822ba8eb545d41140007ef98a7de9274e +Author: Alan Coopersmith +Date: Tue May 19 01:34:19 2009 -0700 + + Update AC_DEFINE_DIR to latest version from Autoconf Archive + +commit 53f8b42f89214b85804ae9e64c49d1a9c2a7553d +Author: Alan Coopersmith +Date: Mon Feb 2 20:34:35 2009 -0800 + + Add README with pointers to mailing list, bugzilla & git repos + + Signed-off-by: Alan Coopersmith + +commit 6697e31fbb616656b7f34515a79454af394b500a +Author: Paulo Cesar Pereira de Andrade +Date: Fri Jan 30 15:45:20 2009 -0200 + + Janitor: ansification, make distcheck, .gitignore + + The ansification code is minor edit of the patch (by me) at + https://bugs.freedesktop.org/show_bug.cgi?id=14727 + as it would not apply cleanly anymore. + +commit 41e4e2de4d73d098d332ece0410e9f8fda4fe10d +Author: Peter Breitenlohner +Date: Mon Oct 20 19:36:52 2008 -0700 + + X.Org Bug 17944: avoid gcc warning for libXpm + + + + Avoid the gcc warning + cxpm/cxpm.c:102: warning: no previous prototype for 'ErrorMessage' + +commit 64323668c07b4768c57649f5ec7e2888265d1aeb +Author: Matthieu Herrb +Date: Sun Mar 9 08:57:47 2008 +0100 + + nuke RCS Ids + +commit 6ef45c37160079a9aa551adcd841abdb55eabae3 +Author: Benjamin Close +Date: Thu Jan 31 14:42:41 2008 +1030 + + Use libtools SED check rather than autoconf's SED check. + AC_PROG_SED required autoconf 2.60, libtool's should work + regardless. This keeps us supporting 2.57 of autoconf + + Found by: Tinderbox (1.4.1 compile) + +commit 3f7624048aa6064c69e2320a70fb7fc89e0bb7ef +Author: Alan Coopersmith +Date: Thu Jan 24 14:26:34 2008 -0800 + + Bug 14171: sxpm/Makefile.am:21: SED was already defined + + + +commit 503843fd3066031adbd4a362c686acc721787b7d +Author: James Cloos +Date: Thu Dec 6 16:38:36 2007 -0500 + + Replace static ChangeLog with dist-hook to generate from git log + +commit 3e37dd39b6169af9928d5b959c40ba79a07450ee +Author: Alan Coopersmith +Date: Wed Aug 22 13:23:30 2007 -0700 + + Version bump: 3.5.7 + +commit d82244497b54889f91c78585374d1ad6a0cef2cf +Author: Alan Coopersmith +Date: Wed Aug 22 13:08:42 2007 -0700 + + Replace strcpy with strncpy to match previous code block + +commit 47c974872b51b8c1d6965eff4599f8ce739bcedc +Author: Alan Coopersmith +Date: Mon Aug 6 14:22:48 2007 -0700 + + Use srcdir in paths passed to xgettext when making .po files + +commit 6e003fd5f174a8e312d799d7f8812c2a5b87e433 +Author: Alan Coopersmith +Date: Mon Aug 6 12:59:04 2007 -0700 + + Replace index/rindex with C89 standard strchr/strrchr + +commit 43dfc6be8128139888426d8c709aa78efc207953 +Author: Jason Rumney +Date: Mon Aug 6 12:52:52 2007 -0700 + + X.Org Bug #11863: Build libXpm on MS Windows (with MinGW) + + * src/XpmI.h [FOR_MSW]: Include simx.h instead of real X headers. + + * src/simx.h (_XFUNCPROTOBEGIN, _XFUNCPROTOEND, NO_ZPIPE): Define. + (XAllocColor): Fix arg list in prototype. + (bzero, close, fdopen, index, rindex, open, strdup, O_RDONLY): + Map to W32 equivalents. + + * src/RdFToI.c [FOR_MSW]: Include fcntl.h. + +commit 290f0b9115428dab0cbf2880d154468c557b3e7e +Author: Alan Coopersmith +Date: Wed Jul 25 17:45:15 2007 -0700 + + Include comment/copyright/license for AC_DEFINE_DIR in acinclude.m4 + +commit d4bc7dc0dea218cea380aba972f10f60dc1e86ac +Author: Alan Coopersmith +Date: Wed Jun 27 13:54:07 2007 -0700 + + Use AM_CFLAGS & AM_CPPFLAGS to replace per-program and obsolete macros + + Clears some warnings from automake-1.10 + +commit 85a87de3c03ca8be526dedc0a2973f9426518c39 +Author: Alan Coopersmith +Date: Tue Nov 21 17:12:18 2006 -0800 + + Sun bug 4486226: Xpm is not internationalized + + + Use gettext() to allow translated messages in sxpm & cxpm + (cherry picked from bcda4f17ab3fa9f0572f876dbeb09b45fbc23f3d commit) + +commit 3c881daddcc251d6e806715d267e4e55934abd1a +Author: Alan Coopersmith +Date: Tue Nov 21 15:13:44 2006 -0800 + + Add *~ to .gitignore to skip over emacs/patch droppings + +commit 60817dd28774540622ea404f650db8389c66da54 +Author: Adam Jackson +Date: Fri Oct 13 16:23:49 2006 -0400 + + Bump to 3.5.6 + +commit 12dc4dc15234ae818a21c20ebf7b2d053b7a94be +Author: Alan Coopersmith +Date: Thu Jul 13 14:59:03 2006 -0700 + + renamed: .cvsignore -> .gitignore + +commit 4daea919c3aa104b6caf8c0f42f49ae755545986 +Author: Alan Coopersmith +Date: Sat Jun 3 06:11:30 2006 +0000 + + Always initialize atomTable to NULL, so xpmHashTableFree() doesn't try to + free a random value from the stack if xpmHashTableInit returns an + error. + +commit 19855d6e09aa36db7686ad6f538179bf87e9c6ea +Author: Alan Coopersmith +Date: Fri Jun 2 19:48:01 2006 +0000 + + Coverity #1432: Returned without freeing storage "hints_cmt" (in error case + when xpmHashTableInit failed) + +commit 000abcd371d0c4b1d0a5380023d74bf5bfc47685 +Author: Alan Coopersmith +Date: Fri Jun 2 19:33:29 2006 +0000 + + Coverity #1415: Returned without freeing storage "hints_cmt" (in error case + when xpmHashTableInit failed) + +commit 5c70c99833d4040aaf595d0005b861e0a930ee66 +Author: Adam Jackson +Date: Thu Apr 27 00:19:37 2006 +0000 + + Bump to 3.5.5 + +commit 2dcc187c92c1a579e6e9f0bad999a3b4e47228c3 +Author: Matthieu Herrb +Date: Sat Mar 18 15:18:56 2006 +0000 + + doublecheck that a pointer is not NULL before dereferencing it. (Coverity + CID 121). + +commit 93421a53ccf159ff39bc9f8ff72c57246f9cb90c +Author: Kevin E Martin +Date: Thu Dec 15 00:24:31 2005 +0000 + + Update package version number for final X11R7 release candidate. + +commit 2b229ddcb52a3bf9bef32e764f93cc57c1351420 +Author: Kevin E Martin +Date: Tue Dec 6 22:48:44 2005 +0000 + + Change *man_SOURCES ==> *man_PRE to fix autotools warnings. + +commit 50214deb692a9af760088f8e7a51955c7d3f1707 +Author: Kevin E Martin +Date: Sat Dec 3 05:49:44 2005 +0000 + + Update package version number for X11R7 RC3 release. + +commit 19881d3c88ff0713ef550382fd0dfb03123dabed +Author: Alan Coopersmith +Date: Mon Nov 28 22:03:06 2005 +0000 + + Change *mandir targets to use new *_MAN_DIR variables set by xorg-macros.m4 + update to fix bug #5167 (Linux prefers *.1x man pages in man1 subdir) + +commit a6fbdb403efd3bf7e1179660959fd0e66a301ce0 +Author: Kevin E Martin +Date: Sat Nov 19 07:15:42 2005 +0000 + + Update pkgconfig files to separate library build-time dependencies from + application build-time dependencies, and update package deps to work + with separate build roots. + +commit 82513d04a8381da8d2281d7581f6b0d65901aede +Author: Alan Coopersmith +Date: Sun Nov 13 02:08:07 2005 +0000 + + Use sed to substitute variables in man pages + +commit d1b430289b2ddb6c1f3383c5288aa125b058508a +Author: Kevin E Martin +Date: Wed Nov 9 21:19:13 2005 +0000 + + Update package version number for X11R7 RC2 release. + +commit e2c9276ccc1ef619dcfbdeb414ef0dec5113c1ee +Author: Alan Coopersmith +Date: Sat Oct 29 02:26:49 2005 +0000 + + Add --enable-stat-zfile (on by default) to replace Imake's ZFILEDEF = + -DSTAT_ZFILE to enable automatically searching for file.xpm.Z & + file.xpm.gz when file.xpm is requested. + +commit 2f57ab95012d9221cca1af6c0a1ccea5d308c66f +Author: Kevin E Martin +Date: Wed Oct 19 02:48:11 2005 +0000 + + Update package version number for RC1 release. + +commit 72bf88ed120fb888c57ed3223faa316403031b36 +Author: Kevin E Martin +Date: Wed Oct 5 20:24:14 2005 +0000 + + Add missing files to EXTRA_DIST + Fix man page installation + +commit 08c43c5f1f851c1acad360a28767670dc62d8a66 +Author: Matthieu Herrb +Date: Mon Oct 3 19:53:58 2005 +0000 + + Last argument of variable parameter list needs to be casted to a pointer + type. + +commit 5ecad7c12c3104d653972385f548e3f86532cbe3 +Author: Kevin E Martin +Date: Fri Jul 29 21:22:52 2005 +0000 + + Various changes preparing packages for RC0: + - Verify and update package version numbers as needed + - Implement versioning scheme + - Change bug address to point to bugzilla bug entry form + - Disable loadable i18n in libX11 by default (use --enable-loadable-i18n to + reenable it) + - Fix makedepend to use pkgconfig and pass distcheck + - Update build script to build macros first + - Update modular Xorg version + +commit 703207d3b3718223d4b2711fb77fc96a4f3909ef +Author: Matthieu Herrb +Date: Sun Jul 17 10:32:57 2005 +0000 + + fix build outside of $(srcdir) + +commit 5a0177d4474787951c0cae56e285bb075ab405f3 +Author: Alan Coopersmith +Date: Sat Jul 16 21:11:25 2005 +0000 + + Accept autoconf HAVE_STRLCPY as alias for HAS_STRLCAT + +commit fd38ee667976855150d3c1231a1acc2cf1a89330 +Author: Alan Coopersmith +Date: Sat Jul 16 21:10:44 2005 +0000 + + Check for strlcat() for use in parse.c + +commit 9b3eed6e4f7ee542149ecec0d017a3a460f7c084 +Author: Daniel Stone +Date: Sat Jul 16 07:23:39 2005 +0000 + + Set soversion to 4.11.0 with -version-number. + +commit a705a1cd9dc4c4ba1940c9b59d2107ba59360e39 +Author: Keith Packard +Date: Sat Jul 9 06:45:44 2005 +0000 + + Add .cvsignore files + +commit b1d84a9fc9b15232c09b6ce5d96c097fdd4f0a15 +Author: Alexander Gottwald +Date: Thu Jun 9 13:42:36 2005 +0000 + + Use $(top_srcdir)/src instead of $(top_builddir)/src in INCLUDES + +commit 769751fba3e32f49272d19799929e1ad5a3d2cd0 +Author: Søren Sandmann Pedersen +Date: Thu May 19 17:09:13 2005 +0000 + + Add $(top_builddir)/include to INCLUDES + +commit 2cc1896c61eef5739bb6a8ffa89e58ba5c175a05 +Author: Søren Sandmann Pedersen +Date: Thu May 19 15:02:48 2005 +0000 + + - Add build system for lib/Xpm + - Add Xpm to symlink.sh + - Conditionally include config.h in xc/extras/Xpm + +commit cf0d69c7ace679f27f105c582760b9be14923aba +Author: Søren Sandmann Pedersen +Date: Thu May 19 14:37:53 2005 +0000 + + Thu May 19 10:36:54 2005 Søren Sandmann + Add "../lib" to INCLUDES. + Replace #include "../lib/foo" with #include "foo". + +commit 639b3598cd0e7214010248efb62b75ef85a8e5c5 +Author: Matthieu Herrb +Date: Mon Feb 21 20:52:32 2005 +0000 + + Avoid inifite loops. From Chris Gilbert in bug #1920. + +commit f1908d7ee5e2d2d44db2116b3c88213da9dfb854 +Author: Matthieu Herrb +Date: Sat Dec 11 16:14:05 2004 +0000 + + Fix incomplete merge. + +commit b041980732f6a6002001cfe079fdfb982937d4a8 +Author: Matthieu Herrb +Date: Sat Dec 11 16:08:59 2004 +0000 + + more s_open() cleanup. + +commit 90d0638a42553786f54df333f0da4d008e9a0573 +Author: Matthieu Herrb +Date: Sat Dec 11 16:04:34 2004 +0000 + + Replace s_popen() by a more specific function that allows only one command + in the pipe. Remove extraneous tests on file names that broke some + applications. From Alex Reisen in Bugzilla #1920. + +commit 2c23dbf2cafaad72b1f45da915eb87a8f792fdb0 +Author: Roland Mainz +Date: Wed Dec 8 01:16:48 2004 +0000 + + //bugs.freedesktop.org/show_bug.cgi?id=830): Fix libXpm header (xpm.h) to + use the X11 function begin/end marker macros (_XFUNCPROTOBEGIN, + _XFUNCPROTOEND) instead of homegrown (native) C++ code. Patch by Kevin + DeKorte . + +commit 50986a34f231fbc7a4b62466bd89bd4ae4027d2e +Author: Matthieu Herrb +Date: Thu Nov 25 21:19:11 2004 +0000 + + Fixes for CAN-2004-0914 (Thomas Biege). + +commit a983dafac59dcb425666a5a5556da4734e50c6c5 +Author: Egbert Eich +Date: Tue Sep 21 17:57:35 2004 +0000 + + Merged over libXpm security fix provided by Chris Evans, Matthieu Herrb and + Alan Coopersmith from release 6.8.1. + Fail during initialization with error if font/fontset is not set for + widget. This prevents a sig11 later when the non-existent font/fontset + structs are referenced. + Check if xf86Info.kbdProc pointer is really set before calling it on abort + as this pointer won't be set if the new modular keyboard driver is used + (Matthias Hopf). + Added new libs to the bindist control files. + Removed inclusion of unnecessary kernel header on Linux. This may fail in + an -ansi environment. + +commit 2773a7214e282f6f673483f5233b880505947c3f +Author: Egbert Eich +Date: Fri Apr 23 18:42:32 2004 +0000 + + Merging XORG-CURRENT into trunk + +commit 65c64a2eaa8698434f1869dcdcb5d9ccb21c6932 +Author: Egbert Eich +Date: Sun Mar 14 08:28:26 2004 +0000 + + Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004 + +commit 0b313707a677523fed9ac485445e8b09d2a85c13 +Author: Egbert Eich +Date: Wed Mar 3 12:09:53 2004 +0000 + + Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004 + +commit 658f8e9a9094ba5d18743694cad7275be53c7a25 +Author: Egbert Eich +Date: Thu Feb 26 13:34:33 2004 +0000 + + readding XFree86's cvs IDs + +commit 9971f91864e8f722b42c58f2ff19025715f33b98 +Author: Egbert Eich +Date: Thu Feb 26 09:21:31 2004 +0000 + + Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004 + +commit fbfe965054d8144946651b19085684af7f6715b9 +Author: Kaleb Keithley +Date: Tue Nov 25 19:27:16 2003 +0000 + + XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks + +commit c037348b5df0ac94ad4daba59f8bc9acf12ef623 +Author: Kaleb Keithley +Date: Fri Nov 14 16:48:24 2003 +0000 + + XFree86 4.3.0.1 + +commit aafaabc4a0bfab6544e085ee504ad69de4a5ddb1 +Author: Kaleb Keithley +Date: Fri Nov 14 16:48:24 2003 +0000 + + Initial revision diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..8b82ade --- /dev/null +++ b/INSTALL @@ -0,0 +1,291 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008 Free Software Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 6. Often, you can also type `make uninstall' to remove the installed + files again. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *Note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..1f17762 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,23 @@ +# Daniel Stone disowns all copyright on this file; no warranty is given as to its +# suitability or otherwise. + +SUBDIRS = doc include man src sxpm cxpm + +ACLOCAL_AMFLAGS = -I m4 + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = xpm.pc + +EXTRA_DIST = COPYRIGHT NEWS.old + +MAINTAINERCLEANFILES = ChangeLog INSTALL + +.PHONY: ChangeLog INSTALL + +INSTALL: + $(INSTALL_CMD) + +ChangeLog: + $(CHANGELOG_CMD) + +dist-hook: ChangeLog INSTALL diff --git a/NEWS.old b/NEWS.old new file mode 100644 index 0000000..ccec85f --- /dev/null +++ b/NEWS.old @@ -0,0 +1,957 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/**************************************************************************\ +* * +* HISTORY of user-visible changes * +* * +\**************************************************************************/ + +3.4k (98/03/18) + + ENHANCEMENTS: + - A new program called cxpm is provided to check on XPM files and help + figuring out where the file might be invalid. + - The FAQ and README are now in HTML. + + BUGS CORRECTED: + - A bug in writing pixmaps out on an 32 bit depth visual and MSBFirst + machine. + - patch from Uwe Langenkamp + - A severe bug in parsing the pixels section when an unknown character + is encountered. + +3.4j (96/12/31) + + ENHANCEMENTS: + - The XPM library can now be built under Amiga DOS. This entirely comes + from: Lorens Younes + See the README.AMIGA file for details. + - Changes for MSW: big performance improvement in ParseAndPutPixels(), + fixed creation of the mask in SetColor() + - patch from Jan Wielemaker + - makefiles are provided for VMS + - given by Martin P.J. Zinser m.zinser@gsi.de + - Imakefiles reworked to get smoother builds and fixes from: + - Paul DuBois dubois@primate.wisc.edu + - Larry Schwimmer schwim@cyclone.stanford.edu + - thanks to some code rearrangement the library is smaller (the size + reduction goes from 4 to 7% depending on the system) + + BUGS CORRECTED: + - A severe bug (introduced in 3.4i as part of the sprintf + optimization) in code writing XPM extensions to a buffer + XpmCreateBufferFromImage/Pixmap. + - The XpmAttributes definition in xpm.h was declaring nalloc_colors to + be Bool, it's an int. + +3.4i (96/09/13) + + NEW FEATURES: + - The XPM library now allows the application to pass its own color + allocation/free functions. For this matter the following was done: + The XpmAttributes structure has three new fields alloc_color, + free_color, and color_closure. The following new valuemasks were + added XpmAllocColorFunc, XpmFreeColorsFunc, XpmColorClosure. And + two new types were defined XpmAllocColorFunc and XpmFreeColorsFunc. + See documentation for details. + + ENHANCEMENTS: + - Windows NT support. It should compile and run fine based on the X + Consortium X11R6 distribution. + - The README file contains information to compile on Solaris with gcc. + - Part of the code has been optimized by using the value returned by + sprintf instead of calling strlen. Add the flag -DVOID_SPRINTF + if on your system sprintf returns void. + - patch from Thomas Ott thommy@rz.fh-augsburg.de + + BUGS CORRECTED: + - XpmFree is now a real function (simply calling free by default). + + CHANGES TO THE DOC: + - The documentation describes the new XpmAttributes fields and their + use. + +3.4h (96/02/01) + + NEW FEATURES: + - The XpmAttributes has a new member called 'alloc_close_colors' which + lets the caller specify whether close colors should be allocated + using XAllocColor or not. This is especially useful when one uses a + private colormap full of read/write cells. + The xpm.h header file define a new bitmap flag called + XpmAllocCloseColors to use along with this new slot. + - Dale Pease peased@bigbird.cso.gtegsc.com + - The XpmAttributes has a new member called 'bitmap_format' which lets + the caller specify the format of 1 bit depth images (XYBitmap or + ZPixmap). The xpm.h header file define a new bitmap flag called + XpmBitmapFormat to use along with this new field. + + ENHANCEMENTS: + - XpmReadFileTo[Image/Pixmap], XpmCreate[Image/Pixmap]FromData, + XpmCreateImageFromDataFromBuffer functions do no longer use a + temporary XpmImage object, which reduces a lot the amount of memory + used. On the other hand it can take a little more time, but given the + following figures (based on sxpm) it is a real good trade-off. + + Reading a 22x22 pixmap with 5 colors no time change is detected + using time: + real 0.3 + user 0.1 + sys 0.1 + + Reading a 1279x1023 pixmap with 14 colors (quite extreme case for + XPM!) the time goes from: + real 1.9 + user 0.8 + sys 0.8 + + to: + real 2.2 + user 1.8 + sys 0.3 + + Reading the 22x22 pixmap with 5 colors the memory usage (under + purify) goes from: + 255256 code + 55496 data/bss + 163848 heap (peak use) + 4248 stack + to: + 271240 code + 55472 data/bss + 159752 heap (peak use) + 4224 stack + + And reading the 1279x1023 pixmap with 14 colors it goes from: + 255256 code + 55496 data/bss + 6705160 heap (peak use) + 4280 stack + to: + 271240 code + 55472 data/bss + 1732616 heap (peak use) + 4264 stack + + This clearly shows that while for small pixmaps there is no real + difference on both sides, for large pixmaps this makes a huge + difference about the amount of memory used and it is not much + slower. + + Note that you can still get the old behavior using both + XpmReadFileToXpmImage and XpmCreate[Image/Pixmap]FromXpmImage instead + of XpmReadFileTo[Image/Pixmap]. Once more XPM gives you the choice! + + BUGS CORRECTED: + - when defined locally the global symbols strcasecmp and strdup are + now called xpmstrcasecmp and xpmstrdup to avoid any possible + conflict. + - VMS has a bogus file system which requires a work around in + XpmReadFileToBuffer. + - patch from Bob.Deen@jpl.nasa.gov + - the type of the exactColors attribute has been changed from unsigned + int to Bool. + + CHANGES TO THE DOC: + - the documentation describes the new XpmAttributes fields + alloc_close_colors and bitmap_format. + +3.4g (95/10/08) + + ENHANCEMENTS: + - The XpmAttributes structure has now two new slots: alloc_pixels and + nalloc_pixels in order to provide an easy way to free allocated + colors. The new bitmask XpmReturnAllocPixels should be used to + request this data through the valuemask. Unless you really know why, + you should use this instead of XpmReturnPixels, pixels, and npixels. + - the XPM1 format parsing has been improved. + - patch from Chuck Thompson + - compilers defining _STDC_ to something different from 1 are now + considered as ANSI compilers. + - the README file provides now more info on how to build XPM depending + on the system. + + BUGS CORRECTED: + - a bug introduced in 3.4f in the XPM1 format parsing function. + - fix from Chuck Thompson + - the hashtable was not free when the color parsing failed. + - patch from ackley@cs.unm.edu (David Ackley) + - the close color mechanism wasn't used if one of the closeness + parameter was null. Now only one needs to be different from 0. + Lorens Younes d93-hyo@nada.kth.se + - parsing of long comments failed with a segmentation fault. + + CHANGES TO THE DOC: + - the documentation describes the new XpmAttributes fields + alloc_pixels and nalloc_pixels and how they are used. + +3.4f (95/05/29) + + ENHANCEMENTS: + - Defines IMAKE_DEFINES in the top Imakefile so one can easily avoid + building the shared library. + - Add some information about the installation process in the README. + - filenames are surrounded with quotes when calling gzip or compress in + order to allow spaces within filenames. + - William Parn + - the compilation and the shared library building should be smoother + on Alpha OSF/1. + - patch from Dale Moore + + BUGS CORRECTED: + - a segmentation fault occurring in some weird case. + +3.4e (95/03/01) + + ENHANCEMENTS: + - The top Imakefile passes CDEBUGFLAGS and DEFINES to subdirs. Thus + only this Imakefile should need to be edited by users. + - FAQ includes the answer to the question "How can I get a non + rectangular icon using XPM ?" + - VMS support updated + - patch from Martin P.J. Zinser m.zinser@gsi.de + + BUGS CORRECTED: + - XpmCreateImageFromXpmImage() called from XpmReadFileToPixmap() could + lead to a segmentation fault since free was called on a memory block + size variable instead of the block itself. Note: this bug has been + introduced in 3.4d. + +3.4d (95/01/31) + + ENHANCEMENTS: + - sxpm now supports a -version option command. + + BUGS CORRECTED: + - the list of pixels returned in XpmAttributes was wrong when two + colors were defined as None in the read XPM + - Lionel.Mallet@sophia.inria.fr + - the parser was skipping whitespace reading extensions strings. This + has been fixed so extensions lines are now returned exactly as they + are. + - some compilation control added for the dec alpha with X11R5 (LONG64) + - patch from Fredrik Lundh + - when writing an XPM file, '-' characters are replaced with '_' + characters in the array name, in order to get a valid C syntax name. + - XYPixmap format images were not correctly handled. + - XPM1 file with names using multiple '_' characters are now handled + correctly. + - todd@erda.rl.af.mil (Todd Gleason) + +3.4c (94/06/06) + + Yes, this is kind of quick. But this is because no code has been modified, + this is just a new packaging to make the whole stuff more suitable to the + X development team's requests for inclusion in the R6 contrib. + + ENHANCEMENTS: + - Several filenames were too long to fit without any conflict on DOS + and CD-ROM filesystems. They have been renamed. + - Imakefiles use XCOMM for comments instead of the # character. + - the Postscript documentation file doc/xpm.ps is now distributed as + doc/xpm.PS.gz and allows browsing with tools such as ghostview. + - Besides, parts of lib/misc.c have been moved to several new files, + and some functions of data.c have been moved to other files in + order to get a better link profile. + - I've also added a FAQ hoping this will prevent people from + continuously filling my mailbox with the same questions. + - sxpm.c includes instead of "xpm.h" and BUILDINCTOP is + used in Makefiles as expected. + - Everything can be done simply using "xmkmf -a" and "make". + +3.4b (94/05/24) + + ENHANCEMENTS: + - XPM can now be built under MS Windows. Yes, this is possible and this + entirely comes from: + - Hermann Dunkel + See the README.MSW file for details. + + - building the shared library now depends on the SharedLibXpm variable + and no longer on the SharedLibX variable which is private to the X + Window System project. + - patch from Stephen Gildea + Other variables can now be set for the various locations needed. + + - lib/parse.c does no longer use a 256x256 array in the stack but + malloc it instead. + + - The Copyright notice which has been re-written from the X11R6's one + should be clearer and is now present in every file. + + BUGS CORRECTED: + - lib/xpmP.h does no longer define a Boolean type which conflicts with + the Intrinsic definition. Instead the type Bool defined in Xlib is + used. + - neumann@watson.ibm.com (Gustaf Neumann) + +3.4a (94/03/29) + + BUGS CORRECTED: + - passing NULL as shapemask_return to XpmReadFileToPixmap and similar + functions was leading to a bus error. + - Dean Luick + +3.4 (94/03/14) + + IMPORTANT NOTE: + This version is not compatible with 3.3. Fortunately most people should + only need to recompile. + I apology for this but CDE/Motif have put heavy pressure to go that + way. The point is that I designed and released Xpm 3.3 in order to let + OSF include a clean version of Xpm in Motif 2.0. This new version was + not fully compatible with 3.2 but I thought it didn't matter since this + was going to be the first version used within Motif. Unfortunately CDE + was already using xpm-3.2 internally and requires both source and + binary backward compatibility. By the way I must say they didn't drop + us a single line to let us know they were using it and thus were + expecting stability. All this could have been avoided... + + However, since I had to go for a not compatible version I took this as + an opportunity to modify the lower level API, which was new in 3.3 and + which was somewhat clumsy, in order to provide yet a better API. + + The library has been modified to have both source and binary backward + compatibility with xpm-3.2. This implies it is not either source or + binary compatible with 3.3. The fields related to the 3.2 XpmInfos + mechanism have been put back into the XpmAttributes structure. The new + 3.3 XpmInfos struct has been renamed as XpmInfo to avoid conflict with + the old 3.2 flag which is back too. All the semantic related to the + XpmAttributes infos fields is back as well. + + So this new version provides a high level API which is fully + compatible with 3.2 and still provides the 3.3 lower level API + (XpmImage) with the XpmInfos struct renamed as XpmInfo. This leads to + some redundancy but this was the best I could do to satisfy both + CDE/Motif people who needed the backward compatibility and myself (who + always tries to provide you with the best ;-). + + Tests have been successfully performed with pixmap-2.1, pixmap-2.4, and + sxpm. + + ENHANCEMENTS: + - The colorTable member of the XpmAttributes structure is now an + (XpmColor*) in order to be compatible with an XpmImage colorTable. + However in order to be backward compatible this field is cast to + (XpmColor **), which is equivalent to (char ***), when it is used + with the old flags XpmInfos and XpmReturnInfos. To handle the new + type the new flags XpmColorTable and XpmReturnColorTable have been + defined. + - The XpmInfo struct has been extended to avoid having to deal with an + XpmAttributes at the lower level. The idea is that all the data + stored in an Xpm file can be retrieve through both an XpmImage and + an XpmInfo struct. See the documentation for details. + - XpmUndefPixel is defined and exported by xpm.h in order to let + clients providing their own colorTable when writing out an Xpm file. + See the documentation for details. + - in sxpm/sxpm.c, set attribute XtNinput to True on toplevel widget. + Windows that don't "take" input, never get focus, as mandated by + the ICCM. + patch from Henrique Martins + - lib/Imakefile modified to build the shared library under IRIX 5. + patch from simon@lia.di.epfl.ch (Simon Leinen) + + NEW FEATURES: + - a new function and a new define should help client figuring out with + which Xpm library version they are working. These are + XpmIncludeVersion and XpmLibraryVersion(). + +3.3 (93/12/20) + + NEW FEATURES: + - XPM1 files are now supported. + - a new function is provided to get an error string related to the + returned error code. + - suggested by Detlef Schmier + + ENHANCEMENTS: + - gzip and gunzip are called with the -q option (quiet) + - patch from Chris P. Ross + - the parser is again more flexible about the way the strings are + distributed on lines. Actually a single line XPM file can be read. + - the documentation should be clearer about shapemask generation and + XpmAttributes valuemask. + + BUGS CORRECTED: + - reading some binary file was leading to a bus error. + - patch from Detlef Schmier + - the ? character is no longer used when writing an XPM file in order + to avoid possible ANSI trigraphs. + +3.3alpha (93/08/13) + + NEW FEATURES: + - a new level interface is provided to allow applications to do either + icon editing or data caching. + The XpmAttributes has been changed but most applications will just + need to be recompiled. + - new structures are provided to deal with the new lower level: + XpmImage, XpmColor, XpmInfos. + + - a separate distribution called xpm-contrib is available. This + includes the converters which used to be part of this distribution + plus: + two new applications: + * nexpm to draw a pixmap in *any* existing window from + Ralph Betza + * xpmview to display a list of Xpm files from + Jean Michel Leon + + a hacky string to pixmap converter, provided by + Robert H. Forsman Jr. + + The Xpm editor called pixmap will also be part of this contrib. + This does not mean it is the best pixmap editor one can find + but it is the only one that I know of which tries to handle + all the features of this format. + + ENHANCEMENTS: + - the code to build XImage data has been optimized by + jules@x.co.uk (Julian Gosnell) + the old code is still available when compiling with the + -DWITHOUT_SPEEDUPS flag. + + - closecolor code was not re-entrant + - dbl@visual.com (David B. Lewis) + - fix gzip filename (*.gz and no longer *.z). + - Jason Patterson + - sxpm has 2 new options: + -nom to do not display the mask if there is one + -cp to override a color value with a given + pixel, i.e. sxpm plaid.xpm -cp red 4 + + also the '-s' adn '-p' options have been renamed to '-sc' and '-sp'. + + - xpm.h defines XpmFormat, XpmVersion, and XpmRevision numbers. + + BUGS CORRECTED: + - closecolor minor fix + - Jason Patterson + +3.2g (93/04/26) + + ENHANCEMENTS: + - much faster close colors + - piping from/to compressed files now handles GNU's gzip (.z) format + - added XpmColorKey attribute - ability to specify which visual's + colors to use (ie: now it's possible to read in a pixmap in a + color visual, but use the colors specified for monochrome). + - added -mono, -grey4, -grey and -color options to sxpm to demonstrate + the XpmColorKey attribute. + - Jason Patterson + + BUGS CORRECTED: + - fixed bug where redefining "None" as a pixel stopped mask generation + - minor SVR4 defines for + - fixed annoying closecolor bug related to read/write color cells + - fixed minor bug in color value -> pixel overloading + - manual updated to include new red/green/blue closeness attributes + - Jason Patterson + + - the top Imakefile was missing the depend target + - sxpm/Imakefile fixed so that -L../lib is set before the standard + library location. + - Vivek Khera + + - lib/xpmP.h now defines bcopy as memcpy for VMS (required by recent + versions of VMS) + - J. Daniel Smith + + - the lib/Imakefile didn't work with X11R4. + + +3.2f (93/03/17) + + NEW FEATURES: + - the library provides four new functions to deal with Xpm files + loaded in memory as single character strings buffers: + + XpmCreateImageFromBuffer + XpmCreatePixmapFromBuffer + XpmCreateBufferFromImage + XpmCreateBufferFromPixmap + + - in addition, as a convenience, two functions are provided to copy a + file in a buffer and to write a file from a buffer: + + XpmReadFileToBuffer + XpmWriteFileFromBuffer + + ENHANCEMENTS: + - Files are now dispatched in the following sub-directories: + lib, sxpm, and doc. + - Imakefiles will let you build a shared library as well as the static + one (with either X11R4 or X11R5). + - The documentation has been ported from LaTeX to FrameMaker and is + now included in the distribution in its PostScript form (doc/xpm.ps). + Source files are available on request. + Also the documentation has been reorganized and includes a table of + contents and an index of the functions (the number of functions + increasing this became a requisite). + + BUGS CORRECTED: + - Many warnings have been fixed - patch from Daniel Dardailler + daniel@osf.org + +3.2e (93/02/05) + + ENHANCEMENTS: + - use XpmMalloc, XpmRealloc, XpmCalloc, and XpmFree which are defines + in xpmP.h. This should help people wanting to use their own functions. + + BUGS CORRECTED: + - Intrinsic.h is no longer included. + - bzero is defined as memset on SYSV and SVR4. + - some memory initialization bug concerning XpmAttributes. + +3.2d (93/01/27) + + ENHANCEMENTS: + - compile on Solaris 2.0 + - patch from Clint Jeffery + + BUGS CORRECTED: + - shape masks are now set correctly for LSBFirst (Decs). + - pixmaps are now set correctly for 2 bit displays (Nexts). + - patch from Josef Leherbauer + - isspace was called on getc which fails when EOF is returned. + - Marelli Paolo + +3.2c (92/12/29) + + ENHANCEMENTS: + - parsing optimized for single and double characters color + - patch originally from Martin Brunecky + marbru@build1.auto-trol.com + + BUGS CORRECTED: + - XpmFreeExtensions was calling free on some argument without checking + it was not NULL. + - strdup was not correctly defined for systems which do not provide + it. - Hans-Peter Lichtin + - some bug in XpmCrDataFI.c + - Sven Delmas garfield@avalanche.cs.tu-berlin.de + + NOTE: + - there is still a bug with the creation of the clipmask on display of + depth 2 but I can't find a fix because unfortunately I don't have such + a rendering system and nobody gets the time to investigate for me. + +3.2b (92/10/19) + + ENHANCEMENTS: + - Create XpmReadFileToData and XpmWriteFileFromData + - Dan Greening + - added "close colors" support and ability to redefine color values + as pixels at load time, as well as color names + - Jason Patterson + - errors while parsing or allocating colors now revert to other + visual defaults, creating pixmap/image as expected, and returning + XpmSuccess. The old behavior of XpmColorError being returned and no + pixmap/image being created can be retained by setting the + exactColors attribute. + - Jason Patterson + + BUGS CORRECTED: + - SVR4 defines for including instead of + - Jason Patterson + - attributes->extensions and attributes->nextensions fields were not + set correctly when no extensions present in file. + - Simon_Scott Cornish + +3.2a (92/08/17) + + ENHANCEMENTS: + - use the mock lisp hashing function instead of the gnu emacs one, + it is faster in some cases and never slower (I've not found any case). + + BUGS CORRECTED: + - function prototypes for ansi compilers. + - some memory initialization bugs (purify is just great for this). + - empty strings in extensions are now correctly handled. + +3.2 (92/07/06) + + NEW FEATURES: + - both format and functions handle extensions data. This allow people + to store additional data related to a pixmap. See documentation for + detail. + - sxpm supports the new option '-c' to use a private colormap. This is + useful when displaying pixmaps using a lot of colors. + - sxpm supports the new option '-v' (verbose) to get possible + extensions print out on standard error. + + ENHANCEMENTS: + - most of the code has been reworked to be improved and thus almost + every function is faster. It takes less than 6 seconds of real time on + a sun4 to display, with sxpm, a 487x635 pixmap using 213 colors, while + it takes 32 seconds with the old library! It takes 18 seconds to + display a 1279x1023 screen dump using 14 colors while xwud takes 10 + seconds. + Of course performance improvements are not always that great, they + depend on the size and number of colors but I'm sure everybody will + appreciate ;-) + I know how to improve it more but this will require changes in the + architecture so this is not for now. Some optimizations have been + contributed by gregor@kafka.saic.com (gregg hanna) and + jnc@csl.biosci.arizona.edu (John N. Calley). + - the Imakefile is modified to let you install sxpm - Rainer Klute + + - xpmP.h declares popen for Sequent platforms - Clinton Jeffery + + - XpmWriteFileFromImage/Pixmap rather than truncating the pixmap name + to the first dot changes dots to underscores to get a valid C syntax + name. + + + BUGS CORRECTED: + - there was a bug in the image creation function for some 24 bits + displays. It is fixed. + - allocated color pixels are now freed when an error occurs - + nusser@dec1.wu-wien.ac.at (Stefan Nusser) + + CHANGES TO THE DOC: + - the documentation describes the new XpmExtension structure and how + to use it with read and write functions. + +3.1 (92/02/03) + + ENHANCEMENTS: + - sxpm now have more standard options (mainly suggested by + Rainer Sinkwitz ): + + Usage: sxpm [options...] + Where options are: + + [-d host:display] Display to connect to. + [-g geom] Geometry of window. + [-hints] Set ResizeInc for window. + [-icon filename] Set pixmap for iconWindow. + [-s symbol_name color_name] Overwrite color defaults. + [-p symbol_name pixel_value] Overwrite color defaults. + [-plaid] Read the included plaid pixmap. + [filename] Read from file 'filename', and from + standard input if 'filename' is '-'. + [-o filename] Write to file 'filename', and to standard + output if 'filename' is '-'. + [-nod] Don't display in window. + [-rgb filename] Search color names in the rgb text file + 'filename'. + + if no input is specified sxpm reads from standard input. + + + - Xpm functions and Ppm converters now deal with multiword colornames. + patches from Rainer Sinkwitz . + + +3.0 (91/10/03) + + Functions name and defines have been modified again (sorry for that) + as follows: + + XpmReadPixmapFile XpmReadFileToPixmap + XpmWritePixmapFile XpmWriteFileFromPixmap + + XpmPixmapColorError XpmColorError + XpmPixmapSuccess XpmSuccess + XpmPixmapOpenFailed XpmOpenFailed + XpmPixmapFileInvalid XpmFileInvalid + XpmPixmapNoMemory XpmNoMemory + XpmPixmapColorFailed XpmColorFailed + + To update code using Xpm you can use the included shell script called + rename with the sed commands files name-3.0b-3.0c and name-3.0c-3.0. + Old names still valid though. + + NEW FEATURES: + - four new functions to work with images instead of pixmaps: + + XpmReadFileToImage + XpmWriteFileFromImage + XpmCreateImageFromData + XpmCreateDataFromImage + + ENHANCEMENTS: + Algorithms to create and scan images and pixmaps are based on the + MIT's R5 code, thus they are much cleaner than old ones and should + avoid any problem with any visual (yes, I trust MIT folks :-) + + BUGS CORRECTED: + Imakefile use INCDIR instead of ROOTDIR. + + CHANGES TO THE DOC: + - the documentation presents the four new functions. + +3.0c (91/09/18) + + In answer to request of people functions, types and defines names have + been changed as follows: + + XCreatePixmapFromData XpmCreatePixmapFromData + XCreateDataFromPixmap XpmCreateDataFromPixmap + XReadPixmapFile XpmReadPixmapFile + XWritePixmapFile XpmWritePixmapFile + XFreeXpmAttributes XpmFreeAttributes + + PixmapColorError XpmPixmapColorError + PixmapSuccess XpmPixmapSuccess + PixmapOpenFailed XpmPixmapOpenFailed + PixmapFileInvalid XpmPixmapFileInvalid + PixmapNoMemory XpmPixmapNoMemory + PixmapColorFailed XpmPixmapColorFailed + + ColorSymbol XpmColorSymbol + + Generally speaking every public name begins with 'Xpm' and every + private one with 'xpm'. This should avoid any possible conflict. + + Some files have also be renamed accordingly. + + NEW FEATURES: + - support for VMS and two new options for sxpm: icon and hints (see + manual for details) Richard Hess + - DEFINES in Imakefile and Makefile.noXtree allows you to set the + following: + + ZPIPE for un/compressing piped feature (default is on) + NEED_STRCASECMP for system which doesn't provide one (default + is off) + + - xpmtoppm.c has is own strstr function which is used if NEED_STRSTR + is defined when compiling - Hugues.Leroy@irisa.fr (Hugues Leroy). + + BUGS CORRECTED: + - many bugs have been fixed, especially for ansi compilers - + Doyle C. Davidson (doyle@doyled.b23b.ingr.com) and + Clifford D. Morrison (cdm%bigdaddy%edsr@uunet.UU.NET) + - parser is again a little more improved + +3.0b (91/09/12) + + This is a complete new version with a new API and where files and + structures have been renamed. So this should be taken as a new + starting release. + This release should be quickly followed by the 3.0 because I'm planning + to send it for X11R5 contrib which ends October 5th. + + NEW FEATURES: + - support for transparent color. + - support for hotspot. + - a new function: XCreateDataFromPixmap to create an XPM data from a + pixmap in order to be able to create a new pixmap from this data using + the XCreatePixmapFromData function later on. + - a new structure: XpmAttributes which replace the XpmInfo structure + and which leads to a much simpler API with less arguments. + - arguments such as visual, colormap and depth are optional, default + values are taken if omitted. + - parsing and allocating color failures don't simply break anymore. If + another default color can be found it is used and a PixmapColorError + is returned. In case no color can be found then it breaks and returns + PixmapColorFailed. + - for this reason the ErrorStatus codes are redefined as follows: + + null if full success + positive if partial success + negative if failure + + with: + #define PixmapColorError 1 + #define PixmapSuccess 0 + #define PixmapOpenFailed -1 + #define PixmapFileInvalid -2 + #define PixmapNoMemory -3 + #define PixmapColorFailed -4 + + - sxpm prints out a warning when a requested color could not be parsed + or alloc'ed, and an error when none has been found. + - sxpm handles pixmap with transparent color. For this purpose the + plaid_mask.xpm is added to the distribution. + + BUGS CORRECTED: + - I've again improved the memory management. + - the parser is also improved. + - when writing a pixmap to a file the variable name could be + "plaid.xpm" which is not valid in C. Now the extension name is cut off + to give "plaid" as variable name. + - reading multiple words colornames such as "peach puff" where leading + to non readable Xpm files. They are now skipped to have only single + word colorname. Lionel Mallet (mallet@ipvpel.unipv.it). + - parser was triggered by the "/" character inside string. + Doyle C. Davidson (doyle@doyled.b23b.ingr.com). This is corrected. + - sxpm maps the window only if the option "-nod" is not selected. + + CHANGES TO THE DOC: + - the documentation presents the new API and features. + +3.0a (91/04/10) + + This is an alpha version because it supports the new version of XPM, + but the library interface is still the same. Indeed it will change in + future release to get rid of obsolete stuff such as the type argument + of the XWritePixmapFile function. + + ******************************* WARNING ********************************* + The format is not anymore XPM2, it is XPM version 3 which is XPM2 + limited to the C syntax with the key word "XPM" in place of "XPM2 C". + The interface library has not changed yet but the type argument of + XWritePixmapFile and the type member of XpmInfo are not used anymore. + Meanwhile the library which is now called libXpm.a is backward + compatible as XPM2 files can be read. But the XWritePixmapFile + function only writes out XPM version 3 files. + ************************************************************************* + + NEW FEATURES: + - the library doesn't use global variables anymore, thus it should be + able to share it. + - sxpm has been rewritten on top of Xt, it can be used to convert + files from XPM2 to XPM version 3. + - xpm1to2c.perl has been upgraded to the new XPM version and renamed + as xpm1to3.perl + - ppmtoxpm2.c and ppmtoxpm2.1 have been upgraded too and renamed + ppmtoxpm.c and ppmtoxpm.1. In addition the xpmtoppm.c and xpmtoppm.1 + of the pbmplus package have been upgraded too. xpmtoppm can thus + convert XPM version 1 and 3 to a portable pixmap. These files should + replace the original ones which are part of the pbmplus package. See + the ppm.README file for more details. + - the library contains RCS variables which allows you to get revision + numbers with ident (which is part of the RCS package). The Id number + is an internal rcs number for my eyes only. The official one is found + in Version. + + BUGS CORRECTED: + - the memory management has been much improved in order to avoid + memory leaks. + - the XImage building algorithm has been changed to support correctly + different visual depths. There is special code to handle depths 1, 4, + 6, 8, 24, and 32 to build the image and send it in one whack, and + other depths are supported by building the image with XPutPixel which + is slow but sure. + - similar algorithms are used to read pixmaps and write them out. + + CHANGES TO THE DOC: + - the documentation presents the new XPM format. + + +2.8 (90/12/19) + + ******************************* WARNING ********************************* + Since the last release two structures have been modified and have now + bigger sizes, so ANY CODE USING THE libXPM2 NEEDS TO BE RECOMPILED. + ************************************************************************* + + NEW FEATURES: + - the ColorSymbol struct contains the new member 'pixel' which allow + to override default colors by giving a pixel value (in such a case + symbol value must be set to NULL), + - the XpmInfo struct contains the new member 'rgb_fname' in which one + can specify an rgb text file name while writing a pixmap with the + XWritePixmapFile function (otherwise this member should be set to + NULL). This way colorname will be searched and written out if found + instead of the RGB value, + - Imakefile originally provided by stolcke@ICSI.Berkeley.EDU, + - the old Makefile is now distributed as Makefile.noXtree and presents + install targets, + - the demo application is renamed sxpm (Show XPM), creates a window of + the size of the pixmap if no geometry is specified, prints out + messages instead of status when an error occurs, handles the new + option -p for overriding colors by giving a pixel value (not really + useful but is just here to show this new feature), handles the new + option -rgb for specifying an rgb text file, and ends on + keypress as buttonpress, + - defines for SYSV have been provided by Paul Breslaw + , + - the distribution includes a new directory called converters which + contains xpm1to2 and xpm1to2c perl converters and a ppmtoxpm2 + converter provided by Paul Breslaw who upgraded the original ppmtoxpm + written by Mark W. Snitily . + + CHANGES TO THE DOC: + - this file is created and will give old users a quick reference to + changes made from one release to the next one, + - documentation is changed to present the new ColorSymbol structure + and the way to override colors by giving a pixel value, and to present + the new XpmInfo structure and how to use it, + - a man page for sxpm is added to the distrib, + - the README file talks about sxpm and no more demo, and have + reference to the different converters. + +2.7 (90/11/12) + + NEW FEATURES: + - XReadPixmapFile reads from stdin if filename is NULL, + - XWritePixmapFile writes to stdin if filename is NULL, + - the demo application handles the new option -nod for no displaying + the pixmap in a window (useful when used as converter). + + CHANGES TO THE DOC: + - documentation about the new feature. + +2.6 (90/10/29) + + NEW FEATURES: + - from nazgul@alphalpha.com (Kee Hinckley): changes to make the + library usable as C++ code, and on Apollo without any warning. + + BUGS CORRECTED: + - from nazgul@alphalpha.com (Kee Hinckley): the xpm include files was + declaring XWritePixmapFile as taking in arg a Pixmap pointer instead + of a Pixmap. + +2.5 (90/10/17) + + BUGS CORRECTED: + - XWritePixmapFile was not closing the file while ending normally. + +2.4 (90/09/06) + + NEW FEATURES: + - XReadPixmapFile reads from a piped uncompress if the given filename + ends by .Z or if filename.Z exists, + - XWritePixmapFile writes to a piped compress if the given filename + ends by .Z. + + BUGS CORRECTED: + - demo now deals with window manager. + + CHANGES TO THE DOC: + - documentation about compressed files management. + +2.3 (90/08/30) + + BUGS CORRECTED: + - handle monochrome display correctly, + - comments can be empty. + +2.2 (90/08/27) + + BUGS CORRECTED: + - when reading some invalid free was dumping core on some machine. + +2.1 (90/08/24) + + First distribution of XPM2. + diff --git a/README b/README new file mode 100644 index 0000000..9d14a39 --- /dev/null +++ b/README @@ -0,0 +1,25 @@ +libXpm - X Pixmap (XPM) image file format library + +All questions regarding this software should be directed at the +Xorg mailing list: + + http://lists.freedesktop.org/mailman/listinfo/xorg + +Please submit bug reports to the Xorg bugzilla: + + https://bugs.freedesktop.org/enter_bug.cgi?product=xorg + +The master development code repository can be found at: + + git://anongit.freedesktop.org/git/xorg/lib/libXpm + + http://cgit.freedesktop.org/xorg/lib/libXpm + +For patch submission instructions, see: + + http://www.x.org/wiki/Development/Documentation/SubmittingPatches + +For more information on the git code manager, see: + + http://wiki.x.org/wiki/GitPage + diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..ba7e3b4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,69 @@ + +# Initialize Autoconf +AC_PREREQ([2.60]) +AC_INIT([libXpm], [3.5.10], + [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [libXpm]) +AC_CONFIG_SRCDIR([Makefile.am]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +# Initialize Automake +AM_INIT_AUTOMAKE([foreign dist-bzip2]) +AM_MAINTAINER_MODE + +# Initialize libtool +AC_PROG_LIBTOOL + +# Require X.Org macros 1.8 or later for MAN_SUBSTS set by XORG_MANPAGE_SECTIONS +m4_ifndef([XORG_MACROS_VERSION], + [m4_fatal([must install xorg-macros 1.8 or later before running autoconf/autogen])]) +XORG_MACROS_VERSION(1.8) +XORG_DEFAULT_OPTIONS + +# Checks for library functions +AC_CHECK_FUNCS([strlcat]) + +# Obtain compiler/linker options for dependencies +PKG_CHECK_MODULES(XPM, xproto x11) +PKG_CHECK_MODULES(SXPM, x11 xt xext xextproto, build_sxpm=true, build_sxpm=false) +AM_CONDITIONAL(BUILD_SXPM, test x$build_sxpm = xtrue) + +# Internationalization & localization support +AC_SEARCH_LIBS([gettext], [intl], [USE_GETTEXT="yes"], [USE_GETTEXT="no"]) +AC_MSG_CHECKING([where to install localized messages]) +AC_ARG_WITH([localedir], AS_HELP_STRING([--with-localedir=], + [Path to install message files in (default: datadir/locale)]), + [LOCALEDIR=${withval}], [LOCALEDIR=${datadir}/locale]) +AX_DEFINE_DIR([LOCALEDIR], [LOCALEDIR], [Location of translated messages]) +if test "x$LOCALEDIR" = "xno" -o "x$USE_GETTEXT" = "xno" ; then + AC_MSG_RESULT([nowhere]) + USE_GETTEXT="no" +else + AC_MSG_RESULT([$LOCALEDIR]) +fi + +if test "x$USE_GETTEXT" = "xyes" ; then + AC_DEFINE([USE_GETTEXT], 1, + [Define to 1 if you want to use the gettext() function.]) +fi +AM_CONDITIONAL(USE_GETTEXT, test "x$USE_GETTEXT" = "xyes") + +# Optional feature: When ___.xpm is requested, also look for ___.xpm.Z & .gz +# Replaces ZFILEDEF = -DSTAT_ZFILE in old Imakefile +AC_ARG_ENABLE(stat-zfile, + AS_HELP_STRING([--enable-stat-zfile], + [Search for files with .Z & .gz extensions automatically @<:@default=yes@:>@]), + [STAT_ZFILE=$enableval], [STAT_ZFILE=yes]) +if test x$STAT_ZFILE = xyes ; then + AC_DEFINE(STAT_ZFILE, 1, [Define to 1 to automatically look for files with .Z & .gz extensions]) +fi + +AC_CONFIG_FILES([Makefile + doc/Makefile + include/Makefile + man/Makefile + src/Makefile + sxpm/Makefile + cxpm/Makefile + xpm.pc]) +AC_OUTPUT diff --git a/cxpm/Makefile.am b/cxpm/Makefile.am new file mode 100644 index 0000000..4c74ae6 --- /dev/null +++ b/cxpm/Makefile.am @@ -0,0 +1,15 @@ +bin_PROGRAMS = cxpm + +AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/include/X11 +AM_CFLAGS = $(CWARNFLAGS) $(XPM_CFLAGS) + +cxpm_SOURCES = cxpm.c + +if USE_GETTEXT +noinst_DATA = cxpm.po + +cxpm.po: $(cxpm_SOURCES:%=$(srcdir)/%) + $(AM_V_GEN)xgettext -c"L10N_Comments" -d cxpm -n $(cxpm_SOURCES:%=$(srcdir)/%) + +CLEANFILES = cxpm.po +endif diff --git a/cxpm/cxpm.c b/cxpm/cxpm.c new file mode 100644 index 0000000..8b8af9a --- /dev/null +++ b/cxpm/cxpm.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 1998 Arnaud LE HORS + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * Arnaud LE HORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Arnaud LE HORS shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Arnaud LE HORS. + */ + +/*****************************************************************************\ +* cxpm.c: * +* * +* Check XPM File program * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#define CXPMPROG + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#ifdef USE_GETTEXT +#include +#include +#else +#define gettext(a) (a) +#endif + +#undef xpmGetC +#define xpmGetC(data) sGetc(data, data->stream.file) +#define Getc sGetc +#define Ungetc sUngetc + + +/* + * special getc and ungetc counting read lines and characters + * note that 's' could stand both for "special" and "slow" ;-) + */ +static int +sGetc(xpmData *data, FILE *file) +{ + int c = getc(data->stream.file); + if (c == '\n') { + data->lineNum++; + data->charNum = 0; + } else { + data->charNum++; + } + return c; +} + +static void +sUngetc(xpmData *data, int c, FILE *file) +{ + ungetc(c, data->stream.file); + if (c == '\n') { + data->lineNum--; + data->charNum = 0; + } else { + data->charNum--; + } +} + +/* include all the code we need (yeah, I know, quite ugly...) */ +#include "data.c" +#include "parse.c" +#include "RdFToI.c" /* only for OpenReadFile and xpmDataClose */ +#include "hashtab.c" +#include "misc.c" +#include "Attrib.c" +#include "Image.c" + +static void +ErrorMessage( + int ErrorStatus, + xpmData *data) + +{ + char *error = NULL; + + switch (ErrorStatus) { + case XpmSuccess: + return; + case XpmOpenFailed: + /* L10N_Comments : Error produced when filename does not exist + or insufficient permissions to open (i.e. cxpm /no/such/file ) */ + error = gettext("Cannot open file"); + break; + case XpmFileInvalid: + /* L10N_Comments : Error produced when filename can be read, but + is not an XPM file (i.e. cxpm /dev/null ) */ + error = gettext("Invalid XPM file"); + break; + case XpmNoMemory: + /* L10N_Comments : Error produced when filename can be read, but + is too big for memory + (i.e. limit datasize 32 ; cxpm /usr/dt/backdrops/Crochet.pm ) */ + error = gettext("Not enough memory"); + break; + case XpmColorFailed: + /* L10N_Comments : Error produced when filename can be read, but + contains an invalid color specification (need to create test case)*/ + error = gettext("Failed to parse color"); + break; + } + + if (error) { + /* L10N_Comments : Wrapper around above Xpm errors - %s is + replaced with the contents of the error message retrieved above */ + fprintf(stderr, gettext("Xpm Error: %s.\n"), error); + if (ErrorStatus == XpmFileInvalid && data) + /* L10N_Comments : Error produced when filename can be read, but + is not an XPM file (i.e. cxpm /dev/null ) */ + fprintf(stderr, gettext("Error found line %d near character %d\n"), + data->lineNum + 1, + data->charNum + 1); + exit(1); + } +} + +int +main(int argc, char **argv) +{ + XpmImage image; + char *filename; + int ErrorStatus; + xpmData data; + +#ifdef USE_GETTEXT + setlocale(LC_ALL,""); + bindtextdomain("cxpm",LOCALEDIR); + textdomain("cxpm"); +#endif + + if (argc > 1) { + if (!strcmp(argv[1], "-?") || !strncmp(argv[1], "-h", 2)) { + /* L10N_Comments : Usage message produced by running cxpm -h + %s will be replaced by argv[0] (program name) */ + fprintf(stderr, gettext("Usage: %s [filename]\n"), argv[0]); + exit(1); + } + filename = argv[1]; + } else { + filename = NULL; + } + + xpmInitXpmImage(&image); + + if ((ErrorStatus = OpenReadFile(filename, &data)) != XpmSuccess) + ErrorMessage(ErrorStatus, NULL); + + ErrorStatus = xpmParseData(&data, &image, NULL); + ErrorMessage(ErrorStatus, &data); + + xpmDataClose(&data); + XpmFreeXpmImage(&image); + + exit(0); +} diff --git a/doc/FAQ.html b/doc/FAQ.html new file mode 100644 index 0000000..3ac9c0d --- /dev/null +++ b/doc/FAQ.html @@ -0,0 +1,344 @@ + + + + +FAQ XPM + + + +

The XPM
+Frequently Asked Questions

+

+This article contains the answers to some Frequently Asked Questions about the +XPM format and/or library. If you don't find the answer to your problem here, +then you can mail either to lehors@sophia.inria.fr or to the mailing list +xpm-talk@sophia.inria.fr. + + +

Contents

+ +
    +
  1. How do I convert my images to or from XPM ? +
  2. Why are my XPM files said to be invalid ? +
  3. Why does my program core dumps using XPM ? +
  4. Why does my program core dumps using XPM with a widget ? +
  5. How can I get a non rectangular icon using XPM ? +
  6. What exactly triggers the creation of a mask when using XPM ? +
  7. How should I use the mask ? +
  8. Is there a string to pixmap converter somewhere ? +
  9. How can I edit XPM icons ? +
  10. Is there a collection of icons somewhere ? +
  11. The documentation fails to print out. Why ? +
  12. Copyright +
+ + +

1. How do I convert my images to or from XPM ?

+

+ Netpbm is surely the best image conversion package that I know of. It defines + formats for color, gray and monochrome images and provides a set of filters. + Thus a GIF image can be converted to XPM with something like: +

+ $ giftoppm youricon.gif | ppmtoxpm > youricon.xpm +

+ The latest release can be found at least from wuarchive.wustl.edu + (128.252.135.4), directory /graphics/graphics/packages/NetPBM + + +

2. Why are my XPM files said to be invalid ?

+

+ There are three official versions of the XPM format. The XPM library since + version 3.3 can read all them but writes out only XPM 3. Also the small + program called sxpm which is part of the XPM library package can be used to + automatically translate XPM 1 and 2 files to XPM 3 with a command such as: +

+ $ sxpm -nod yourxpm1or2file -o yourxpm3file +

+ Also, the XPM format defines "None" to be the color name meaning + "transparent", but IXI used to hack the XPM library in its early days to + handle transparency as "#Transparent". This makes IXI format not compatible + with the official XPM format, and so not readable neither by the official XPM + library nor any of the programs built on top of it. +

+ The only solutions are either to stick on IXI programs which can deal with + their format or convert your files to the standard XPM format. This can be + done simply by changing "#Transparent" to "None". + + +

3. Why does my program core dumps using XPM ?

+

+ Be sure the XpmAttributes structure you pass by reference has a valid + valuemask. You can give NULL instead if you don't want to use an + XpmAttributes but if you do, you MUST initialize its valuemask component to + some valid value, at least 0, otherwise unpredictable errors can occur. +

+ So instead of doing something like: +

+      XpmAttributes attrib;
+
+      XpmReadFileToPixmap(dpy, d, filename, &pixmap, &mask, &attrib);
+
+

+ you should do: +

+      XpmAttributes attrib;
+
+      attrib.valuemask = 0;
+      XpmReadFileToPixmap(dpy, d, filename, &pixmap, &mask, &attrib);
+
+ + +

4. Why does my program core dumps using XPM with a widget ?

+
    +
  • First the XPM library is Xlib level, so don't pass your widget as a + Drawable parameter. A Drawable is either a Window or a Pixmap. The widget's + window can do the job but: + +
  • Then a widget only gets a Window when realized, so passing XtWindow(widget) + with a not yet realized widget is wrong. Either realize you widget first or + use another window. Since the Drawable parameter is only used to specify + the screen to which the pixmap must be created on, most of the time the + default root window is just fine. +
+ + +

5. How can I get a non rectangular icon using XPM ?

+

+ The X Window System does not support transparent color. However there are + several ways you can use to get the same visual effect using XPM: +

    +
  • First you can use the None color to get a shape mask and use it as + explained below (question 7). + +
  • Second you can define a symbolic color name such as "mask" in the XPM + format file, then use the color overriding mechanism to set this symbolic + color to the color of the underlying object. Note that in this case the XPM + library won't create a shape mask, and that if the color of the underlying + object is changed then you'll have to create a new pixmap. +
+ + +

6. What exactly triggers the creation of a mask when using XPM ?

+

+ Basically a mask is created if "None" is used as one of the color of the + pixmap. Be aware that this is not only true if it is used in the XPM of the + pixmap since the colors can be overridden at load time. So a mask is created + if the "None" color is used at load time, coming either from the XPM + definition or the color overriding. + + +

7. How should I use the mask ?

+

+ There are basically two ways of using the mask: +

    +
  • Use the mask as a shapemask with the X11 Nonrectangular Saphe Window + Extension. Typically this is what should be done when the icon is used in a + desktop. + +
  • Use the mask as a clipmask in the GC you pass to XCopyArea when drawing the + pixmap. So the "transparent" pixels being not actually drawn will get the + underlying pixels colors. +
+ + +

8. Is there a string to pixmap converter for Motif ?

+

+ Yes, Motif 2.0 or later does support XPM pixmaps as well as XBM bitmaps. + + +

9. How can I edit XPM icons ?

+

+ As listed below several editors either commercial or not are supporting the + XPM format. However, pixmap is the one I would recommend since it is freely + available and, being fully dedicated to XPM, it allows to edit all the + special things, such as the symbolic color names, which makes XPM different + from all the other image formats. Pixmap can always be found by ftp from + ftp.x.org (contrib) and avahi.inria.fr (pub/pixmap). +

+Last Update: 3 August 1994 + + +
XPM Icon Editors
ProgramInfosSource/AuthorPlatformsSAXPMcost +
pixmap +Lionel Malletsourceyes3NC + +
pixt +J. Michael Flanerysourceyes1NC + +
pixed
    +
  • part of X.desktop +
  • current version doesn't work on 24-plane displays +
+
IXIMany UNIXno3N/A + +
olpixmap
    +
  • packaged with the OLIT (OpenLook) toolkit +
+
USLSun, SVR4.2, UnixWareno1N/A + +
xfedor
    +
  • only uses XLIB +
  • doesn't work on 24-plane displays +
+
Daniel Dardaillersourceyes3NC + +
SCOpaint
    +
  • included with the ODT package +
+
SCO/Wing EngODTyes2.8N/A + +
pme.icn
    +
  • written in the Icon language +
+
Icon Projectsourceyes3NC + +
PixEditT
    +
  • there is currently no support for editing the colormap +
+
Free Widget Foundationsourceyes3NC + +
xscribble +Robert Forsmansourceyes?NC + +
vueicon
    +
  • included with Vue3.0 +
+
Hewlett-PackardHPyes3N/A + +
iconedit V3 SunSoftSparc/Sun3yes2N/A + +
Pixmap Editor
    +
  • this is a Widget, not a complete program +
+
ICS?yes?? + +
ezX Sunrise Softwarey???N/A + +
XPaint
    +
  • full featured, works on all displays +
  • current release is 2.1.1 (last update January 1994) +
+
David Koblassourceyes3NC + +
Phoenix +ohtcolor@niksula.hut.fisourceyes3NC + +
pixed
    +
  • pixed is part of the TeleUSE UIMS +
  • More info is available from service@ignite.alsys.com +
+
AlsysMany UNIXyes3N/A + +
display +John Cristysourceyes3NC +
+ +

+SA - Stand Alone program
+NC - No Charge (i.e. free); most programs are copyrighted.
+XPM - XPM format supported
+source - built from source code; likely works on all standard X platforms
+N/A - icon editor is normally distributed with other software + +

+Send updates, additions, corrections, etc. to dan@bristol.com + + +

10. Is there a collection of icons somewhere ?

+

+ At least there is one freely available: Anthony's X Icon Library. You can + found it on several ftp servers, such as server.berkeley.edu/pub/AIcons. It + contains only small icons (less than about 100x100 pixels in size) which are + stored in groups in a logical way. Color icons are stored in XPM format and + Black & White icons in XBM. + + +

11. The documentation fails to print out. Why ?

+

+ The PostScript documentation file is formatted for US letter paper. Frame + Maker tries very hard to ensure that you have the right paper and punts if + you don't. However, you can easily work around this problem by applying the + following patch. If for some reason applying the patch fails, you can still + do it by hand. Just locate the corresponding block in the PS file and remove + the lines with a leading '-' character. + By the way, this applies to any doc generated by Frame Maker. The + corresponding block might be slightly different depending on which version of + Frame Maker was used, but it is still easy to locate. + +

+*** xpm.PS      Wed Sep 11 15:47:43 1996
+--- xpm-A4.PS   Thu Nov 21 09:27:28 1996
+***************
+*** 647,668 ****
+        0 ne /edown exch def
+        /yscale exch def
+        /xscale exch def
+-       FMLevel1 {
+-               manualfeed {setmanualfeed} if
+-               /FMdicttop countdictstack 1 add def
+-               /FMoptop count def
+-               setpapername
+-               manualfeed {true} {papersize} ifelse
+-               {manualpapersize} {false} ifelse
+-               {desperatepapersize} {false} ifelse
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-               count -1 FMoptop {pop pop} for
+-               countdictstack -1 FMdicttop {pop end} for
+-               }
+-               {{1 dict dup /PageSize [paperwidth paperheight]put setpagedevice}stopped
+-               { (Can't select requested paper size for Frame print job!) FMFAILURE } if
+-                {1 dict dup /ManualFeed manualfeed put setpagedevice } stopped pop }
+-       ifelse
+
+        FMPColor {
+                currentcolorscreen
+--- 647,652 ----
+
+ + +
+

Copyright (C) 1989-95 GROUPE BULL

+

+Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +

+The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +

+Except as contained in this notice, the name of GROUPE BULL shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from GROUPE BULL. + + diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..5119700 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,6 @@ +EXTRA_DIST = \ + xpm.PS.gz \ + FAQ.html \ + README.AMIGA \ + README.html \ + README.MSW diff --git a/doc/README.AMIGA b/doc/README.AMIGA new file mode 100644 index 0000000..7a40137 --- /dev/null +++ b/doc/README.AMIGA @@ -0,0 +1,10 @@ +The XPM library for Amiga works best with AmigaOS 3.x, but will work +(with limited color support) with earlier OS versions too. It can be +compiled with both SAS/C and GCC (makefiles are included). + +All functions except the Xpm*Pixmap* functions are supported. + +I have also written some Amiga-specific utility functions (not +included). Contact me if you would like to have them too. + +-Lorens Younes (d93-hyo@nada.kth.se) diff --git a/doc/README.MSW b/doc/README.MSW new file mode 100644 index 0000000..6746bc8 --- /dev/null +++ b/doc/README.MSW @@ -0,0 +1,127 @@ + +README.MSW hedu@cul-ipn.uni-kiel.de 5/94 + + The XPM library for MS-Windows + +Motivated by the wxWindows library, which is a (freely available) toolkit +for developing multi-platform, graphical applications from the same body +of C++ code, I wanted to have XPM pixmaps for MS-windows. Instead of rewriting +a XPM-parser I managed to port the XPM-library-code to MS-windows. +Thanks to Anaud Le Hors this became a part of the official XPM-library. + +Until now it's only used together with wxWindows. And even there it's more +a kind of beta. But it should be possible to run it as a simple libxpm.a +without wxWindows. + +The key is a transformation of some X types plus some basic X functions. +There is not yet a special MSW-API, so you should know the X types used. + +The following is done in simx.h: + +typedef HDC Display; +typedef COLORREF Pixel; + +typedef struct { + Pixel pixel; + BYTE red, green, blue; +} XColor; + +typedef struct { + HBITMAP bitmap; + unsigned int width; + unsigned int height; + unsigned int depth; +} XImage; + +With these defines and the according functions from simx.c you can call +XPM-functions the way it's done under X windows. It can look like this: + + ErrorStatus=XpmCreateImageFromData(&dc, data, + &ximage,(XImage **)NULL, &xpmAttr); + ms_bitmap = ximage->bitmap; + // releases the malloc,but do not destroy the bitmap + XImageFree(ximage); + +Supported functions are the Xpm*Image* but not the Xpm*Pixmap*. + +DRAWBACKS: +The main drawback is the missing support for Colormaps! There was nothing for +it in wxWindows, so I did not know how to deal with Colormaps. + +The size of the pixmaps is bounded by malloc() (width*height*2 < 64K). + +Close colors do not look that close. But that seems to be the window system. + +Neither a special API for MSW nor a special MSW documentation other than this. +(I can only point you to wxxpm as an example , see below.) + +INSTALLATION: +There is not yet a makefile with it. Simply take all the *.c files +into your project except the files related to Pixmap operations: *P*.c. +!!!You MUST set FOR_MSW on the preprocessor options!!! +(You might uncomment NEED_STRCASECMP in xpm.h if it's in your lib) +This should compile into libxpm.a. Good luck... + +FTP: +wxWindows is currently available from the Artificial Intelligence +Applications Institute (University of Edinburgh) by anonymous FTP. + skye.aiai.ed.ac.uk pub/wxwin/ +or read http://burray.aiai.ed.ac.uk/aiai/aiai.html + +wxxpm, XPM support for wxWindows, the latest version is available at + yoda.cul-ipn.uni-kiel.de pub/wxxpm/ + and maybe in the contrib or tools of wxWindows + +Please contact me if you have suggestions, comments or problems! + +================================================================ +Some fixes and comments by Jan Wielemaker (jan@swi.psy.uva.nl), +Oct 24, 1996: + + * Please try not to disturb me on this, XPM is not my + piece of cake. + + * Hermann Dunkel has appearently moved in virtual space. + +Changes: + + * I've used the xpm package under NT 4.0 and MSVC++ 4.2. + + * I've made a big performance improvement in + ParseAndPutPixels(), fixed creation of the mask in + SetColor() in create.c. I looked into XCreateImage() + in simx.c, but commented out my improvement for reasons + you'll find there. If you know what is going on, statement + (1) does not apply to you. + +Comments on installation: + + * Donot include the to/from pixmap files into the project. + These are the ones containing a capital P somewhere in their + name. You can also first include all, and then remove all + the files you get errors on :-) + + * The DC that is requested should be a valid memory DC, thus + CreateCompatibleDC(NULL) provides a good generic one, but + GetDC(NULL) doesn't! This costed me some time. + + * The real difficulty is using the mask, mostly due to the + bad documentation. If 95 or NT is your target, use: + + MaskBlt(context.hdc, // Destination DC + x, y, w, h, // Destination area + mhdc, // Memory DC with the image selected + sx, sy, // Source X,Y + msk, // HBITMAP of the mask + sx, sy, // Mask X,Y + MAKEROP4(SRCPAINT, SRCCOPY)); // The magic op code. +================================================================ + + +-- + ////|\\\\ \\\\\\ Hermann Dunkel + O O ////// IPN Uni Kiel, Germany + | \\\\\\ Tel: +49 431 / 880 3144 + \___/ ////// E-mail: hedu@cul-ipn.uni-kiel.de + \_/ \\\\\\ X.400 : c=de;a=d400;p=uni-kiel;ou=nw-didaktik;s=dunkel + diff --git a/doc/README.html b/doc/README.html new file mode 100644 index 0000000..c3175c1 --- /dev/null +++ b/doc/README.html @@ -0,0 +1,303 @@ + + + + +XPM README + + + +

XPM README

+ +

Contents

+ +
    +
  1. What Is XPM? +
  2. Where to get XPM? +
  3. Documentation +
  4. Installation +
      +
    1. With imake +
    2. Without imake +
    +
  5. SXPM +
  6. CXPM +
  7. Other Tools +
  8. Discussion +
  9. Copyright +
+ + +

1. What Is XPM?

+

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

+Here is provided a library containing a set of four functions, similar to the +X bitmap functions as defined in the Xlib: XpmCreatePixmapFromData, +XpmCreateDataFromPixmap, XpmReadFileToPixmap and XpmWriteFileFromPixmap for +respectively including, storing, reading and writing this format, plus four +other: XpmCreateImageFromData, XpmCreateDataFromImage, XpmReadFileToImage and +XpmWriteFileFromImage for working with images instead of pixmaps. +

+This new version provides a C includable format, defaults for different types +of display: monochrome/color/grayscale, hotspot coordinates and symbol names +for colors for overriding default colors when creating the pixmap. It provides +a mechanism for storing information while reading a file which is re-used +while writing. This way comments, default colors and symbol names aren't lost. +It also handles "transparent pixels" by returning a shape mask in addition to +the created pixmap. +

+See the XPM Manual for details. + + +

2. Where to get XPM?

+

+New XPM updates are announced on the comp.windows.x newsgroup, and on the +"xpm-talk" list and you can always consult the XPM Home page at http://www.inria.fr/koala/lehors/xpm.html +

The latest "official" XPM release can always be found at: +
Boston, USA: ftp://ftp.x.org/contrib +
Sophia Antipolis, France: ftp://koala.inria.fr/pub/xpm + + +

3. Documentation

+

+Old users might read the CHANGES file for a history +of changes interesting the user. +

+Read the doc. The documentation is in PostScript format (doc/xpm.PS) and has been produced with +FrameMaker. The source files are available on request. +

+A FAQ (Frequently Asked Questions) is also provided, +so if you experience any problem you should have a look at this file. + + +

4. Installation

+

+To obtain the XPM library, first uncompress and untar the compressed tar file +in an appropriate directory. +

+Then you can either compile XPM via "imake" or in a stand-alone way. + +

4.1. With imake

+

+ Imakefiles are provided to build both shared and unshared libraries. + However, building a shared lib is very OS dependent and often requires + specific files which are not available. Also config files are often not + set correctly for this task. So if it fails you can avoid trying to + build one and simply build the static library instead. In order to do + so you should edit the top Imakefile to add -DSharedLibXpm=NO to the + definition of IMAKE_DEFINES as described. +

+ The compilation and installation of the library and the sxpm program + should only require you to edit the top Imakefile. But you should do so + in order to specify the locations where the various files should be + installed and to set the DEFINES variable accordingly to your system. +

+ On Solaris 2.* the compilation works only in the native svr4 + environment, avoid the bsd one or it won't compile. Especially you + should be using /opt/SUNWspro/bin/cc and not /usr/ucb/cc. + Also since the compiler is no longer part of the OS distribution a lot + of people use gcc instead. This is fine, but be aware that the imake + tool you get as part of the X Window System on a solaris box is + configured for cc. Therefore the compilation using the generated + Makefiles will not succeed unless you have changed the default + configuration. An easy work around is to directly edit the generated + lib/Makefile to change '-K pic' to '-fpic'. Fixing your imake + configuration would be better though. +

+ On Linux, if you do not use ELF yet you'd better get the binary + distribution available from sunsite. Because it's really a pain to + build a shared lib and the current XPM distribution doesn't contain + the jump files you would need to do so. On the other hand people have + had no problems building it using ELF. +

+ Then execute the following command: +

+		xmkmf -a
+
+

+ or if this option is not supported by your version of xmkmf: +

+		xmkmf
+		make Makefiles
+		make includes
+		make depend		(optional)
+
+

+ Then simply execute: +

+		make
+
+

+ which will build the XPM library and the sxpm application. + Then do: +

+	     	make install
+		make install.man
+
+

+ which will install the library and the sxpm program and man page. +

+ If it fails, be sure you have set the DEFINES correctly in the top + Imakefile to suit your machine. + +

NOTE ON USING IMAKE:

+

+ Building the XPM distribution with imake requires to have imake + correctly installed and configured on your + system. I do my best at tweaking the Imakefiles so they work with + as many imake flavors people might have as possible but there is + nothing I can do against wrong imake configurations. So if your + build fails using imake, don't send me email for advice. Get your + imake configuration fixed or forget about it! + + +

4.2. Without imake

+

+ A set of makefiles is provided for those who do not have imake + available on their system. However, this is only provided as a + convenience and you should be considered as a starting point and not as + something ready to use. These makefiles, called Makefile.noX, will most + likely require some editing in order be set accordingly to your system. +

+ Once this setting is done, you should be able to compile XPM, by + executing the following command: +

+	        make -f Makefile.noX
+
+

+ Then to install it, do: +

+		make -f Makefile.noX install
+
+ + +

5. SXPM

+

+In addition to the library the sxpm tool is provided to show XPM file and +convert them from XPM1 or XPM2 to XPM version 3. If you have previously done +'make' or 'make all' you should already have it, otherwise just do: +

+		      cd sxpm; make
+
+

+This application shows you most of the features of XPM and its source can be +used to quickly see how to use the provided functions. +

+By executing 'sxpm -help' you will get the usage. +

+Executing 'sxpm -plaid' will show a demo of the XpmCreatePixmapFromData +function. The pixmap is created from the static variable plaid defined in the +sxpm.c file. sxpm will end when you press the key 'q' in the created window. +

+Executing 'sxpm -plaid -sc lines_in_mix blue' will show the feature of +overriding color symbols giving a colorname, executing 'sxpm -plaid -sp +lines_in_mix 1' will show overriding giving a pixel value, and executing 'sxpm +-plaid -cp red 0' will show overriding giving a color value. +

+Then you should try 'sxpm -plaid -o output' to get an output file using the +XpmWriteFileFromPixmap function. +

+You can now try 'sxpm -plaid -o - -nod -rgb /usr/lib/X11/rgb.txt' to directly +get the pixmap printed out on the standard output with colornames instead of +rgb values. +

+Then you should try 'sxpm plaid.xpm' to use the XpmReadFileToPixmap function, +and 'cat plaid_mask.xpm|sxpm' to see how "transparent pixels" are handled. +

+The XpmCreatePixmapFromData function is on purpose called without any XpmInfos +flag to show the utility of this one. Indeed, compare the color section of the +two files foo and bar obtained from 'sxpm -nod -plaid -o foo' and 'sxpm -nod +plaid.xpm -o bar'. All the default colors and also the comments have been +restored. +

+To end look at plaid_ext.xpm and try "sxpm -nod plaid_ext.xpm -v" to see how +extensions are handled. +

+Of course, other combinations are allowed and should be tried. Thus, 'sxpm +plaid.xpm -o output -nod' will show you how to convert a file from XPM1 or XPM2 +to a XPM version 3 using sxpm. +

+See the manual page for more detail. + + +

6. CXPM

+

+The cxpm tool is provided to help you figure out whether an XPM file is correct +or not with regard to its format. If you have previously done 'make' or +'make all' you should already have it, otherwise just do: +

+		      cd cxpm; make
+
+

+The related man page will tell you everything about it but here is a simple +example of what it does: +

+$ ./cxpm bogus_pixmap
+Xpm Error: Invalid XPM file.
+Error found line 3 near character 5
+
+

+It is pretty limited but at least, unlike sxpm, it gives you some hint on where +the error occured within the file. + + +

7. Other Tools

+

+Several converters dealing with XPM and a pixmap editor can be found in the +xpm-contrib distribution. Also I recommend the use of netpbm to do any kind of +general image operations such as scaling, resizing, dithering, and to convert +from and to any other image format. + +

8. Discussion

+

+There is a mailing list to discuss about XPM which is xpm-talk@sophia.inria.fr. +Any request to subscribe should be sent to xpm-talk-request@sophia.inria.fr. +The archive of the xpm-talk list is available through the web at +http://zenon.inria.fr/koala/xpm-talk-hypermail +and through ftp at ftp://koala.inria.fr/pub/xpm/xpm-talk-archive +

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

Email: lehors@sophia.inria.fr +
Phone: +33 (0)4 93 65 78 89 +
Surface Mail:
+Arnaud Le Hors
+Inria BP.93
+2004, Route des lucioles
+06902 Sophia Antipolis Cedex
+FRANCE + + +


+

Copyright (C) 1989-95 GROUPE BULL

+

+Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: +

+The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +

+Except as contained in this notice, the name of GROUPE BULL shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from GROUPE BULL. + diff --git a/doc/xpm.PS.gz b/doc/xpm.PS.gz new file mode 100644 index 0000000000000000000000000000000000000000..40e25de9d484deacc48785e266707b5c1e33a37d GIT binary patch literal 49010 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 literal 0 HcmV?d00001 diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..99970a5 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1 @@ +nobase_include_HEADERS = X11/xpm.h diff --git a/include/X11/xpm.h b/include/X11/xpm.h new file mode 100644 index 0000000..38c62d8 --- /dev/null +++ b/include/X11/xpm.h @@ -0,0 +1,477 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* xpm.h: * +* * +* XPM library * +* Include file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +#ifndef XPM_h +#define XPM_h + +/* + * first some identification numbers: + * the version and revision numbers are determined with the following rule: + * SO Major number = LIB minor version number. + * SO Minor number = LIB sub-minor version number. + * e.g: Xpm version 3.2f + * we forget the 3 which is the format number, 2 gives 2, and f gives 6. + * thus we have XpmVersion = 2 and XpmRevision = 6 + * which gives SOXPMLIBREV = 2.6 + * + * Then the XpmIncludeVersion number is built from these numbers. + */ +#define XpmFormat 3 +#define XpmVersion 4 +#define XpmRevision 11 +#define XpmIncludeVersion ((XpmFormat * 100 + XpmVersion) * 100 + XpmRevision) + +#ifndef XPM_NUMBERS + +#ifdef FOR_MSW +# define SYSV /* uses memcpy string.h etc. */ +# include +# include "simx.h" /* defines some X stuff using MSW types */ +#define NEED_STRCASECMP /* at least for MSVC++ */ +#else /* FOR_MSW */ +# ifdef AMIGA +# include "amigax.h" +# else /* not AMIGA */ +# include +# include +# endif /* not AMIGA */ +#endif /* FOR_MSW */ + +/* let's define Pixel if it is not done yet */ +#if ! defined(_XtIntrinsic_h) && ! defined(PIXEL_ALREADY_TYPEDEFED) +typedef unsigned long Pixel; /* Index into colormap */ +# define PIXEL_ALREADY_TYPEDEFED +#endif + +/* Return ErrorStatus codes: + * null if full success + * positive if partial success + * negative if failure + */ + +#define XpmColorError 1 +#define XpmSuccess 0 +#define XpmOpenFailed -1 +#define XpmFileInvalid -2 +#define XpmNoMemory -3 +#define XpmColorFailed -4 + +typedef struct { + char *name; /* Symbolic color name */ + char *value; /* Color value */ + Pixel pixel; /* Color pixel */ +} XpmColorSymbol; + +typedef struct { + char *name; /* name of the extension */ + unsigned int nlines; /* number of lines in this extension */ + char **lines; /* pointer to the extension array of strings */ +} XpmExtension; + +typedef struct { + char *string; /* characters string */ + char *symbolic; /* symbolic name */ + char *m_color; /* monochrom default */ + char *g4_color; /* 4 level grayscale default */ + char *g_color; /* other level grayscale default */ + char *c_color; /* color default */ +} XpmColor; + +typedef struct { + unsigned int width; /* image width */ + unsigned int height; /* image height */ + unsigned int cpp; /* number of characters per pixel */ + unsigned int ncolors; /* number of colors */ + XpmColor *colorTable; /* list of related colors */ + unsigned int *data; /* image data */ +} XpmImage; + +typedef struct { + unsigned long valuemask; /* Specifies which attributes are defined */ + char *hints_cmt; /* Comment of the hints section */ + char *colors_cmt; /* Comment of the colors section */ + char *pixels_cmt; /* Comment of the pixels section */ + unsigned int x_hotspot; /* Returns the x hotspot's coordinate */ + unsigned int y_hotspot; /* Returns the y hotspot's coordinate */ + unsigned int nextensions; /* number of extensions */ + XpmExtension *extensions; /* pointer to array of extensions */ +} XpmInfo; + +typedef int (*XpmAllocColorFunc)( + Display* /* display */, + Colormap /* colormap */, + char* /* colorname */, + XColor* /* xcolor */, + void* /* closure */ +); + +typedef int (*XpmFreeColorsFunc)( + Display* /* display */, + Colormap /* colormap */, + Pixel* /* pixels */, + int /* npixels */, + void* /* closure */ +); + +typedef struct { + unsigned long valuemask; /* Specifies which attributes are + defined */ + + Visual *visual; /* Specifies the visual to use */ + Colormap colormap; /* Specifies the colormap to use */ + unsigned int depth; /* Specifies the depth */ + unsigned int width; /* Returns the width of the created + pixmap */ + unsigned int height; /* Returns the height of the created + pixmap */ + unsigned int x_hotspot; /* Returns the x hotspot's + coordinate */ + unsigned int y_hotspot; /* Returns the y hotspot's + coordinate */ + unsigned int cpp; /* Specifies the number of char per + pixel */ + Pixel *pixels; /* List of used color pixels */ + unsigned int npixels; /* Number of used pixels */ + XpmColorSymbol *colorsymbols; /* List of color symbols to override */ + unsigned int numsymbols; /* Number of symbols */ + char *rgb_fname; /* RGB text file name */ + unsigned int nextensions; /* Number of extensions */ + XpmExtension *extensions; /* List of extensions */ + + unsigned int ncolors; /* Number of colors */ + XpmColor *colorTable; /* List of colors */ +/* 3.2 backward compatibility code */ + char *hints_cmt; /* Comment of the hints section */ + char *colors_cmt; /* Comment of the colors section */ + char *pixels_cmt; /* Comment of the pixels section */ +/* end 3.2 bc */ + unsigned int mask_pixel; /* Color table index of transparent + color */ + + /* Color Allocation Directives */ + Bool exactColors; /* Only use exact colors for visual */ + unsigned int closeness; /* Allowable RGB deviation */ + unsigned int red_closeness; /* Allowable red deviation */ + unsigned int green_closeness; /* Allowable green deviation */ + unsigned int blue_closeness; /* Allowable blue deviation */ + int color_key; /* Use colors from this color set */ + + Pixel *alloc_pixels; /* Returns the list of alloc'ed color + pixels */ + int nalloc_pixels; /* Returns the number of alloc'ed + color pixels */ + + Bool alloc_close_colors; /* Specify whether close colors should + be allocated using XAllocColor + or not */ + int bitmap_format; /* Specify the format of 1bit depth + images: ZPixmap or XYBitmap */ + + /* Color functions */ + XpmAllocColorFunc alloc_color; /* Application color allocator */ + XpmFreeColorsFunc free_colors; /* Application color de-allocator */ + void *color_closure; /* Application private data to pass to + alloc_color and free_colors */ + +} XpmAttributes; + +/* XpmAttributes value masks bits */ +#define XpmVisual (1L<<0) +#define XpmColormap (1L<<1) +#define XpmDepth (1L<<2) +#define XpmSize (1L<<3) /* width & height */ +#define XpmHotspot (1L<<4) /* x_hotspot & y_hotspot */ +#define XpmCharsPerPixel (1L<<5) +#define XpmColorSymbols (1L<<6) +#define XpmRgbFilename (1L<<7) +/* 3.2 backward compatibility code */ +#define XpmInfos (1L<<8) +#define XpmReturnInfos XpmInfos +/* end 3.2 bc */ +#define XpmReturnPixels (1L<<9) +#define XpmExtensions (1L<<10) +#define XpmReturnExtensions XpmExtensions + +#define XpmExactColors (1L<<11) +#define XpmCloseness (1L<<12) +#define XpmRGBCloseness (1L<<13) +#define XpmColorKey (1L<<14) + +#define XpmColorTable (1L<<15) +#define XpmReturnColorTable XpmColorTable + +#define XpmReturnAllocPixels (1L<<16) +#define XpmAllocCloseColors (1L<<17) +#define XpmBitmapFormat (1L<<18) + +#define XpmAllocColor (1L<<19) +#define XpmFreeColors (1L<<20) +#define XpmColorClosure (1L<<21) + + +/* XpmInfo value masks bits */ +#define XpmComments XpmInfos +#define XpmReturnComments XpmComments + +/* XpmAttributes mask_pixel value when there is no mask */ +#ifndef FOR_MSW +#define XpmUndefPixel 0x80000000 +#else +/* int is only 16 bit for MSW */ +#define XpmUndefPixel 0x8000 +#endif + +/* + * color keys for visual type, they must fit along with the number key of + * each related element in xpmColorKeys[] defined in XpmI.h + */ +#define XPM_MONO 2 +#define XPM_GREY4 3 +#define XPM_GRAY4 3 +#define XPM_GREY 4 +#define XPM_GRAY 4 +#define XPM_COLOR 5 + + +/* macros for forward declarations of functions with prototypes */ +#define FUNC(f, t, p) extern t f p +#define LFUNC(f, t, p) static t f p + + +/* + * functions declarations + */ + +_XFUNCPROTOBEGIN + +/* FOR_MSW, all ..Pixmap.. are excluded, only the ..XImage.. are used */ +/* Same for Amiga! */ + +#if !defined(FOR_MSW) && !defined(AMIGA) + FUNC(XpmCreatePixmapFromData, int, (Display *display, + Drawable d, + char **data, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateDataFromPixmap, int, (Display *display, + char ***data_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes)); + + FUNC(XpmReadFileToPixmap, int, (Display *display, + Drawable d, + char *filename, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmWriteFileFromPixmap, int, (Display *display, + char *filename, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes)); +#endif + + FUNC(XpmCreateImageFromData, int, (Display *display, + char **data, + XImage **image_return, + XImage **shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateDataFromImage, int, (Display *display, + char ***data_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes)); + + FUNC(XpmReadFileToImage, int, (Display *display, + char *filename, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes)); + + FUNC(XpmWriteFileFromImage, int, (Display *display, + char *filename, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes)); + + FUNC(XpmCreateImageFromBuffer, int, (Display *display, + char *buffer, + XImage **image_return, + XImage **shapemask_return, + XpmAttributes *attributes)); +#if !defined(FOR_MSW) && !defined(AMIGA) + FUNC(XpmCreatePixmapFromBuffer, int, (Display *display, + Drawable d, + char *buffer, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateBufferFromImage, int, (Display *display, + char **buffer_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes)); + + FUNC(XpmCreateBufferFromPixmap, int, (Display *display, + char **buffer_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes)); +#endif + FUNC(XpmReadFileToBuffer, int, (char *filename, char **buffer_return)); + FUNC(XpmWriteFileFromBuffer, int, (char *filename, char *buffer)); + + FUNC(XpmReadFileToData, int, (char *filename, char ***data_return)); + FUNC(XpmWriteFileFromData, int, (char *filename, char **data)); + + FUNC(XpmAttributesSize, int, (void)); + FUNC(XpmFreeAttributes, void, (XpmAttributes *attributes)); + FUNC(XpmFreeExtensions, void, (XpmExtension *extensions, + int nextensions)); + + FUNC(XpmFreeXpmImage, void, (XpmImage *image)); + FUNC(XpmFreeXpmInfo, void, (XpmInfo *info)); + FUNC(XpmGetErrorString, char *, (int errcode)); + FUNC(XpmLibraryVersion, int, (void)); + + /* XpmImage functions */ + FUNC(XpmReadFileToXpmImage, int, (char *filename, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmWriteFileFromXpmImage, int, (char *filename, + XpmImage *image, + XpmInfo *info)); +#if !defined(FOR_MSW) && !defined(AMIGA) + FUNC(XpmCreatePixmapFromXpmImage, int, (Display *display, + Drawable d, + XpmImage *image, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes)); +#endif + FUNC(XpmCreateImageFromXpmImage, int, (Display *display, + XpmImage *image, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes)); + + FUNC(XpmCreateXpmImageFromImage, int, (Display *display, + XImage *image, + XImage *shapeimage, + XpmImage *xpmimage, + XpmAttributes *attributes)); +#if !defined(FOR_MSW) && !defined(AMIGA) + FUNC(XpmCreateXpmImageFromPixmap, int, (Display *display, + Pixmap pixmap, + Pixmap shapemask, + XpmImage *xpmimage, + XpmAttributes *attributes)); +#endif + FUNC(XpmCreateDataFromXpmImage, int, (char ***data_return, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmCreateXpmImageFromData, int, (char **data, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmCreateXpmImageFromBuffer, int, (char *buffer, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmCreateBufferFromXpmImage, int, (char **buffer_return, + XpmImage *image, + XpmInfo *info)); + + FUNC(XpmGetParseError, int, (char *filename, + int *linenum_return, + int *charnum_return)); + + FUNC(XpmFree, void, (void *ptr)); + +_XFUNCPROTOEND + +/* backward compatibility */ + +/* for version 3.0c */ +#define XpmPixmapColorError XpmColorError +#define XpmPixmapSuccess XpmSuccess +#define XpmPixmapOpenFailed XpmOpenFailed +#define XpmPixmapFileInvalid XpmFileInvalid +#define XpmPixmapNoMemory XpmNoMemory +#define XpmPixmapColorFailed XpmColorFailed + +#define XpmReadPixmapFile(dpy, d, file, pix, mask, att) \ + XpmReadFileToPixmap(dpy, d, file, pix, mask, att) +#define XpmWritePixmapFile(dpy, file, pix, mask, att) \ + XpmWriteFileFromPixmap(dpy, file, pix, mask, att) + +/* for version 3.0b */ +#define PixmapColorError XpmColorError +#define PixmapSuccess XpmSuccess +#define PixmapOpenFailed XpmOpenFailed +#define PixmapFileInvalid XpmFileInvalid +#define PixmapNoMemory XpmNoMemory +#define PixmapColorFailed XpmColorFailed + +#define ColorSymbol XpmColorSymbol + +#define XReadPixmapFile(dpy, d, file, pix, mask, att) \ + XpmReadFileToPixmap(dpy, d, file, pix, mask, att) +#define XWritePixmapFile(dpy, file, pix, mask, att) \ + XpmWriteFileFromPixmap(dpy, file, pix, mask, att) +#define XCreatePixmapFromData(dpy, d, data, pix, mask, att) \ + XpmCreatePixmapFromData(dpy, d, data, pix, mask, att) +#define XCreateDataFromPixmap(dpy, data, pix, mask, att) \ + XpmCreateDataFromPixmap(dpy, data, pix, mask, att) + +#endif /* XPM_NUMBERS */ +#endif diff --git a/m4/ax_define_dir.m4 b/m4/ax_define_dir.m4 new file mode 100644 index 0000000..b74d155 --- /dev/null +++ b/m4/ax_define_dir.m4 @@ -0,0 +1,49 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_define_dir.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_DEFINE_DIR(VARNAME, DIR [, DESCRIPTION]) +# +# DESCRIPTION +# +# This macro sets VARNAME to the expansion of the DIR variable, taking +# care of fixing up ${prefix} and such. +# +# VARNAME is then offered as both an output variable and a C preprocessor +# symbol. +# +# Example: +# +# AX_DEFINE_DIR([DATADIR], [datadir], [Where data are placed to.]) +# +# LICENSE +# +# Copyright (c) 2008 Stepan Kasal +# Copyright (c) 2008 Andreas Schwab +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2008 Alexandre Oliva +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AU_ALIAS([AC_DEFINE_DIR], [AX_DEFINE_DIR]) +AC_DEFUN([AX_DEFINE_DIR], [ + prefix_NONE= + exec_prefix_NONE= + test "x$prefix" = xNONE && prefix_NONE=yes && prefix=$ac_default_prefix + test "x$exec_prefix" = xNONE && exec_prefix_NONE=yes && exec_prefix=$prefix +dnl In Autoconf 2.60, ${datadir} refers to ${datarootdir}, which in turn +dnl refers to ${prefix}. Thus we have to use `eval' twice. + eval ax_define_dir="\"[$]$2\"" + eval ax_define_dir="\"$ax_define_dir\"" + AC_SUBST($1, "$ax_define_dir") + AC_DEFINE_UNQUOTED($1, "$ax_define_dir", [$3]) + test "$prefix_NONE" && prefix=NONE + test "$exec_prefix_NONE" && exec_prefix=NONE +]) diff --git a/man/Makefile.am b/man/Makefile.am new file mode 100644 index 0000000..5734e51 --- /dev/null +++ b/man/Makefile.am @@ -0,0 +1,34 @@ +# +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# 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 (including the next +# paragraph) 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 +# THE AUTHORS OR COPYRIGHT HOLDERS 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. +# + +appmandir = $(APP_MAN_DIR) +appman_PRE = sxpm.man cxpm.man +appman_DATA = $(appman_PRE:man=$(APP_MAN_SUFFIX)) + +EXTRA_DIST = $(appman_PRE) +CLEANFILES = $(appman_DATA) +SUFFIXES = .$(APP_MAN_SUFFIX) .man + +# String replacements in MAN_SUBSTS now come from xorg-macros.m4 via configure +.man.$(APP_MAN_SUFFIX): + $(AM_V_GEN)$(SED) $(MAN_SUBSTS) < $< > $@ diff --git a/man/cxpm.man b/man/cxpm.man new file mode 100644 index 0000000..bfc152f --- /dev/null +++ b/man/cxpm.man @@ -0,0 +1,49 @@ +.\"Copyright (C) 1998 Arnaud LE HORS +.\" +.\"Permission is hereby granted, free of charge, to any person obtaining a copy +.\"of this software and associated documentation files (the "Software"), to +.\"deal in the Software without restriction, including without limitation the +.\"rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +.\"sell copies of the Software, and to permit persons to whom the Software is +.\"furnished to do so, subject to the following conditions: +.\" +.\"The above copyright notice and this permission notice shall be included in +.\"all copies or substantial portions of the Software. +.\" +.\"THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +.\"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +.\"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +.\"Arnaud LE HORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +.\"IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +.\"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +.\" +.\"Except as contained in this notice, the name of Arnaud LE HORS shall not be +.\"used in advertising or otherwise to promote the sale, use or other dealings +.\"in this Software without prior written authorization from Arnaud LE HORS. +.\" +.nr )S 12 +.TH CXPM __appmansuffix__ __xorgversion__ +.PD +.ad b +.SH NAME +cxpm \- Check an XPM (X PixMap) file - XPM 1, 2, or 3. +.SH SYNOPSIS +\fBcxpm\fR +[\|\fIfilename\fP\|] +.SH DESCRIPTION +.PP +The \fBcxpm\fP program can be used to check the format of any XPM (version 1, 2, +or 3) file. On error, unlike \fBsxpm\fR, \fBcxpm\fR prints out an error message +indicating where the parser choked. This should help finding out what's wrong +with an XPM file but do not expect too much from it though. This is not even +close from being some kind of lint program for XPM. First, it stops at the +first error it encounters - so several fix and retry cycles may be necessary to +get your file to parse successfully. Second, \fBcxpm\fP only cares about +the format. If, for instance, your pixmap uses too many colors for your system +you still may experience difficulties displaying it. Be warned. +.PP +When no \fIfilename\fP is given \fBcxpm\fR reads from the standard input. +.SH AUTHOR +Arnaud Le Hors (lehors@sophia.inria.fr) +.br +Copyright (C) 1998 by Arnaud LE HORS. diff --git a/man/sxpm.man b/man/sxpm.man new file mode 100644 index 0000000..87d208c --- /dev/null +++ b/man/sxpm.man @@ -0,0 +1,131 @@ +.\"Copyright (C) 1989-95 GROUPE BULL +.\" +.\"Permission is hereby granted, free of charge, to any person obtaining a copy +.\"of this software and associated documentation files (the "Software"), to +.\"deal in the Software without restriction, including without limitation the +.\"rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +.\"sell copies of the Software, and to permit persons to whom the Software is +.\"furnished to do so, subject to the following conditions: +.\" +.\"The above copyright notice and this permission notice shall be included in +.\"all copies or substantial portions of the Software. +.\" +.\"THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +.\"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +.\"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +.\"GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +.\"AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +.\"CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +.\" +.\"Except as contained in this notice, the name of GROUPE BULL shall not be +.\"used in advertising or otherwise to promote the sale, use or other dealings +.\"in this Software without prior written authorization from GROUPE BULL. +.\" +.nr )S 12 +.TH SXPM __appmansuffix__ __xorgversion__ +.PD +.ad b +.SH NAME +sxpm \- Show an XPM (X PixMap) file and/or convert XPM 1 or 2 files to XPM 3. +.SH SYNOPSIS +\fBsxpm\fR +[\|\fB-d\fR displayname\|] +[\|\fB-g\fR geometry\|] +[\|\fB-hints\fR\|] +[\|\fB-icon\fR filename\|] +[\|\fB-plaid\| | \|\fRfilename\| | \|-\|] +[\|\fB-o\fR filename\| | \|\fB-o\fR -\|] +[\|\fB-pcmap\fR\|] +[\|\fB-closecolors\fR\|] +[\|\fB-nod\fR\|] +[\|\fB-nom\fR\|] +[\|\fB-mono | -grey4 | -grey | -color\fR\|] +[\|\fB-sc\fR symbol color\|] +[\|\fB-sp\fR symbol pixel\|] +[\|\fB-cp\fR color pixel\|] +[\|\fB-rgb\fR filename\|] +[\|\fB-v\fR\|] +.SH DESCRIPTION +.PP +The \fIsxpm\fP program can be used to view any XPM (version 1, 2, or 3) file +and/or to convert a file from XPM1 or XPM2 to XPM version 3. If \fIsxpm\fP is +run with any dummy option specified, the usage is displayed. If no geometry is +specified, the show window will have the size of the read pixmap. Pressing the +key Q in the window will quit the program. +.SH OPTIONS +.TP 8 +.B \-d \fIdisplay\fP +Specifies the display to connect to. +.TP 8 +.B \-g \fIgeom\fP +Window geometry (default is pixmap's size). +.TP 8 +.B \-hints +Set ResizeInc for window. +.TP 8 +.B \-icon \fIfilename\fP +Set icon to pixmap created from the file \fIfilename\fP. +.TP 8 +.B \-plaid +Show the plaid pixmap which is stored as data\fP. +.TP 8 +.B \fIfilename\fP +Read from the file \fIfilename\fP and from standard input if \fIfilename\fP is '-'. +If no input is specified sxpm reads from standard input. +.TP 8 +.B \-o \fIfilename\fP +Write to the file \fIfilename\fP (overwrite if it already exists) and to +standard output if \fIfilename\fP is '-'. +.TP 8 +.B \-mono +Use the colors specified for a monochrome visual. +.TP 8 +.B \-grey4 +Use the colors specified for a 4 color greyscale visual. +.TP 8 +.B \-grey +Use the colors specified for a greyscale visual. +.TP 8 +.B \-color +Use the colors specified for a color visual. +.TP 8 +.B \-pcmap +Use a private colormap. +.TP 8 +.B \-closecolors +Try to use "close colors" before reverting to other visuals. +.TP 8 +.B \-nod +Do not display the pixmap in a window. (Useful when using as converter) +.TP 8 +.B \-nom +Do not use the clipmask if there is any. +.TP 8 +.B \-sc \fIsymbol colorname\fP +Override default color to \fIsymbol\fP to \fIcolorname\fP. +.TP 8 +.B \-sp \fIsymbol pixelvalue\fP +Override default color to \fIsymbol\fP to \fIpixelvalue\fP. +.TP 8 +.B \-cp \fIcolorname pixelvalue\fP +Override default color to \fIcolorname\fP to \fIpixelvalue\fP. +.TP 8 +.B \-rgb \fIfilename\fP +Search color names in the file \fIfilename\fP and write them out instead of +the rgb values. +.TP 8 +.B \-v +Verbose - to print out extensions (stderr). + + +.SH KNOWN BUGS +Some window managers may not accept a pixmap which is not a bitmap as icon +because this does not respect ICCCM, many of the well known ones will accept +it though. + +.SH AUTHOR +Arnaud Le Hors (lehors@sophia.inria.fr) +.br +Bull Research France +.br +Copyright (C) 1989-95 by Groupe Bull. diff --git a/packaging/libXpm.spec b/packaging/libXpm.spec new file mode 100755 index 0000000..27ed86b --- /dev/null +++ b/packaging/libXpm.spec @@ -0,0 +1,69 @@ +Summary: X.Org X11 libXpm runtime library +Name: libXpm +Version: 3.5.10 +Release: 1 +License: MIT +Group: System Environment/Libraries +URL: http://www.x.org + +Source0: %{name}-%{version}.tar.gz + +BuildRequires: gettext +BuildRequires: pkgconfig(xext) pkgconfig(xt) pkgconfig(xau) +BuildRequires: pkgconfig(xorg-macros) +BuildRequires: pkgconfig(xproto) + +%description +X.Org X11 libXpm runtime library + +%package devel +Summary: X.Org X11 libXpm development package +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} +Provides: libxpm-devel + +%description devel +X.Org X11 libXpm development package + +%prep +%setup -q + +%build +%reconfigure --disable-static \ + LDFLAGS="${LDFLAGS} -Wl,--hash-style=both -Wl,--as-needed" +make %{?jobs:-j%jobs} + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p %{buildroot}/usr/share/license +cp -af COPYING %{buildroot}/usr/share/license/%{name} +make install DESTDIR=$RPM_BUILD_ROOT + +# We intentionally don't ship *.la files +rm -f $RPM_BUILD_ROOT%{_libdir}/*.la + +%remove_docs + +%clean +rm -rf $RPM_BUILD_ROOT + +%post -p /sbin/ldconfig +%postun -p /sbin/ldconfig + +%files +%defattr(-,root,root,-) +/usr/share/license/%{name} +%doc AUTHORS COPYING ChangeLog +%{_libdir}/libXpm.so.4 +%{_libdir}/libXpm.so.4.11.0 + +%files devel +%defattr(-,root,root,-) +%{_bindir}/cxpm +%{_bindir}/sxpm +%{_includedir}/X11/xpm.h +%{_libdir}/libXpm.so +%{_libdir}/pkgconfig/xpm.pc +#%dir %{_mandir}/man1x +#%{_mandir}/man1/*.1* +#%{_mandir}/man1/*.1x* diff --git a/src/Attrib.c b/src/Attrib.c new file mode 100644 index 0000000..1b38047 --- /dev/null +++ b/src/Attrib.c @@ -0,0 +1,308 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* Attrib.c: * +* * +* XPM library * +* Functions related to the XpmAttributes structure * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +/* 3.2 backward compatibility code */ +LFUNC(CreateOldColorTable, int, (XpmColor *ct, unsigned int ncolors, + XpmColor ***oldct)); + +LFUNC(FreeOldColorTable, void, (XpmColor **colorTable, unsigned int ncolors)); + +/* + * Create a colortable compatible with the old style colortable + */ +static int +CreateOldColorTable( + XpmColor *ct, + unsigned int ncolors, + XpmColor ***oldct) +{ + XpmColor **colorTable, **color; + unsigned int a; + + if (ncolors >= UINT_MAX / sizeof(XpmColor *)) + return XpmNoMemory; + + colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *)); + if (!colorTable) { + *oldct = NULL; + return (XpmNoMemory); + } + for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++) + *color = ct; + *oldct = colorTable; + return (XpmSuccess); +} + +static void +FreeOldColorTable( + XpmColor **colorTable, + unsigned int ncolors) +{ + unsigned int a, b; + XpmColor **color; + char **sptr; + + if (colorTable) { + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + for (b = 0, sptr = (char **) *color; b <= NKEYS; b++, sptr++) + if (*sptr) + XpmFree(*sptr); + } + XpmFree(*colorTable); + XpmFree(colorTable); + } +} + +/* end 3.2 bc */ + +/* + * Free the computed color table + */ +void +xpmFreeColorTable( + XpmColor *colorTable, + int ncolors) +{ + int a, b; + XpmColor *color; + char **sptr; + + if (colorTable) { + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + for (b = 0, sptr = (char **) color; b <= NKEYS; b++, sptr++) + if (*sptr) + XpmFree(*sptr); + } + XpmFree(colorTable); + } +} + +/* + * Free array of extensions + */ +void +XpmFreeExtensions( + XpmExtension *extensions, + int nextensions) +{ + unsigned int i, j, nlines; + XpmExtension *ext; + char **sptr; + + if (extensions && nextensions > 0) { + for (i = 0, ext = extensions; i < nextensions; i++, ext++) { + if (ext->name) + XpmFree(ext->name); + nlines = ext->nlines; + for (j = 0, sptr = ext->lines; j < nlines; j++, sptr++) + if (sptr && *sptr) + XpmFree(*sptr); + if (ext->lines) + XpmFree(ext->lines); + } + XpmFree(extensions); + } +} + +/* + * Return the XpmAttributes structure size + */ + +int +XpmAttributesSize(void) +{ + return sizeof(XpmAttributes); +} + +/* + * Init returned data to free safely later on + */ +void +xpmInitAttributes(XpmAttributes *attributes) +{ + if (attributes) { + attributes->pixels = NULL; + attributes->npixels = 0; + attributes->colorTable = NULL; + attributes->ncolors = 0; +/* 3.2 backward compatibility code */ + attributes->hints_cmt = NULL; + attributes->colors_cmt = NULL; + attributes->pixels_cmt = NULL; +/* end 3.2 bc */ + if (attributes->valuemask & XpmReturnExtensions) { + attributes->extensions = NULL; + attributes->nextensions = 0; + } + if (attributes->valuemask & XpmReturnAllocPixels) { + attributes->alloc_pixels = NULL; + attributes->nalloc_pixels = 0; + } + } +} + +/* + * Fill in the XpmAttributes with the XpmImage and the XpmInfo + */ +void +xpmSetAttributes( + XpmAttributes *attributes, + XpmImage *image, + XpmInfo *info) +{ + if (attributes->valuemask & XpmReturnColorTable) { + attributes->colorTable = image->colorTable; + attributes->ncolors = image->ncolors; + + /* avoid deletion of copied data */ + image->ncolors = 0; + image->colorTable = NULL; + } +/* 3.2 backward compatibility code */ + else if (attributes->valuemask & XpmReturnInfos) { + int ErrorStatus; + + ErrorStatus = CreateOldColorTable(image->colorTable, image->ncolors, + (XpmColor ***) + &attributes->colorTable); + + /* if error just say we can't return requested data */ + if (ErrorStatus != XpmSuccess) { + attributes->valuemask &= ~XpmReturnInfos; + if (!(attributes->valuemask & XpmReturnPixels)) { + XpmFree(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + attributes->ncolors = 0; + } else { + attributes->ncolors = image->ncolors; + attributes->hints_cmt = info->hints_cmt; + attributes->colors_cmt = info->colors_cmt; + attributes->pixels_cmt = info->pixels_cmt; + + /* avoid deletion of copied data */ + image->ncolors = 0; + image->colorTable = NULL; + info->hints_cmt = NULL; + info->colors_cmt = NULL; + info->pixels_cmt = NULL; + } + } +/* end 3.2 bc */ + if (attributes->valuemask & XpmReturnExtensions) { + attributes->extensions = info->extensions; + attributes->nextensions = info->nextensions; + + /* avoid deletion of copied data */ + info->extensions = NULL; + info->nextensions = 0; + } + if (info->valuemask & XpmHotspot) { + attributes->valuemask |= XpmHotspot; + attributes->x_hotspot = info->x_hotspot; + attributes->y_hotspot = info->y_hotspot; + } + attributes->valuemask |= XpmCharsPerPixel; + attributes->cpp = image->cpp; + attributes->valuemask |= XpmSize; + attributes->width = image->width; + attributes->height = image->height; +} + +/* + * Free the XpmAttributes structure members + * but the structure itself + */ +void +XpmFreeAttributes(XpmAttributes *attributes) +{ + if (attributes->valuemask & XpmReturnPixels && attributes->npixels) { + XpmFree(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + if (attributes->valuemask & XpmReturnColorTable) { + xpmFreeColorTable(attributes->colorTable, attributes->ncolors); + attributes->colorTable = NULL; + attributes->ncolors = 0; + } +/* 3.2 backward compatibility code */ + else if (attributes->valuemask & XpmInfos) { + if (attributes->colorTable) { + FreeOldColorTable((XpmColor **) attributes->colorTable, + attributes->ncolors); + attributes->colorTable = NULL; + attributes->ncolors = 0; + } + if (attributes->hints_cmt) { + XpmFree(attributes->hints_cmt); + attributes->hints_cmt = NULL; + } + if (attributes->colors_cmt) { + XpmFree(attributes->colors_cmt); + attributes->colors_cmt = NULL; + } + if (attributes->pixels_cmt) { + XpmFree(attributes->pixels_cmt); + attributes->pixels_cmt = NULL; + } + if (attributes->pixels) { + XpmFree(attributes->pixels); + attributes->pixels = NULL; + attributes->npixels = 0; + } + } +/* end 3.2 bc */ + if (attributes->valuemask & XpmReturnExtensions + && attributes->nextensions) { + XpmFreeExtensions(attributes->extensions, attributes->nextensions); + attributes->extensions = NULL; + attributes->nextensions = 0; + } + if (attributes->valuemask & XpmReturnAllocPixels + && attributes->nalloc_pixels) { + XpmFree(attributes->alloc_pixels); + attributes->alloc_pixels = NULL; + attributes->nalloc_pixels = 0; + } + attributes->valuemask = 0; +} diff --git a/src/CrBufFrI.c b/src/CrBufFrI.c new file mode 100644 index 0000000..398c645 --- /dev/null +++ b/src/CrBufFrI.c @@ -0,0 +1,449 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrBufFrI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM buffer * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +LFUNC(WriteColors, int, (char **dataptr, unsigned int *data_size, + unsigned int *used_size, XpmColor *colors, + unsigned int ncolors, unsigned int cpp)); + +LFUNC(WritePixels, void, (char *dataptr, unsigned int data_size, + unsigned int *used_size, + unsigned int width, unsigned int height, + unsigned int cpp, unsigned int *pixels, + XpmColor *colors)); + +LFUNC(WriteExtensions, void, (char *dataptr, unsigned int data_size, + unsigned int *used_size, + XpmExtension *ext, unsigned int num)); + +LFUNC(ExtensionsSize, unsigned int, (XpmExtension *ext, unsigned int num)); +LFUNC(CommentsSize, int, (XpmInfo *info)); + +int +XpmCreateBufferFromImage( + Display *display, + char **buffer_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes) +{ + XpmImage xpmimage; + XpmInfo info; + int ErrorStatus; + + /* initialize return value */ + if (buffer_return) + *buffer_return = NULL; + + /* create an XpmImage from the image */ + ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage, + &xpmimage, attributes); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the buffer from the XpmImage */ + if (attributes) { + xpmSetInfo(&info, attributes); + ErrorStatus = + XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, &info); + } else + ErrorStatus = + XpmCreateBufferFromXpmImage(buffer_return, &xpmimage, NULL); + + /* free the XpmImage */ + XpmFreeXpmImage(&xpmimage); + + return (ErrorStatus); +} + + +#undef RETURN +#define RETURN(status) \ +do \ +{ \ + ErrorStatus = status; \ + goto error; \ +}while(0) + +int +XpmCreateBufferFromXpmImage( + char **buffer_return, + XpmImage *image, + XpmInfo *info) +{ + /* calculation variables */ + int ErrorStatus; + char buf[BUFSIZ]; + unsigned int cmts, extensions, ext_size = 0; + unsigned int l, cmt_size = 0; + char *ptr = NULL, *p; + unsigned int ptr_size, used_size, tmp; + + *buffer_return = NULL; + + cmts = info && (info->valuemask & XpmComments); + extensions = info && (info->valuemask & XpmExtensions) + && info->nextensions; + + /* compute the extensions and comments size */ + if (extensions) + ext_size = ExtensionsSize(info->extensions, info->nextensions); + if (cmts) + cmt_size = CommentsSize(info); + + /* write the header line */ +#ifndef VOID_SPRINTF + used_size = +#endif + sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n"); +#ifdef VOID_SPRINTF + used_size = strlen(buf); +#endif + ptr_size = used_size + ext_size + cmt_size + 1; /* ptr_size can't be 0 */ + if(ptr_size <= used_size || + ptr_size <= ext_size || + ptr_size <= cmt_size) + { + return XpmNoMemory; + } + ptr = (char *) XpmMalloc(ptr_size); + if (!ptr) + return XpmNoMemory; + strcpy(ptr, buf); + + /* write the values line */ + if (cmts && info->hints_cmt) { +#ifndef VOID_SPRINTF + used_size += +#endif + snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->hints_cmt); +#ifdef VOID_SPRINTF + used_size += strlen(info->hints_cmt) + 5; +#endif + } +#ifndef VOID_SPRINTF + l = +#endif + sprintf(buf, "\"%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + + if (info && (info->valuemask & XpmHotspot)) { +#ifndef VOID_SPRINTF + l += +#endif + snprintf(buf + l, sizeof(buf)-l, " %d %d", info->x_hotspot, info->y_hotspot); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + } + if (extensions) { +#ifndef VOID_SPRINTF + l += +#endif + sprintf(buf + l, " XPMEXT"); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + } +#ifndef VOID_SPRINTF + l += +#endif + sprintf(buf + l, "\",\n"); +#ifdef VOID_SPRINTF + l = strlen(buf); +#endif + ptr_size += l; + if(ptr_size <= l) + RETURN(XpmNoMemory); + p = (char *) XpmRealloc(ptr, ptr_size); + if (!p) + RETURN(XpmNoMemory); + ptr = p; + strcpy(ptr + used_size, buf); + used_size += l; + + /* write colors */ + if (cmts && info->colors_cmt) { +#ifndef VOID_SPRINTF + used_size += +#endif + snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->colors_cmt); +#ifdef VOID_SPRINTF + used_size += strlen(info->colors_cmt) + 5; +#endif + } + ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size, + image->colorTable, image->ncolors, image->cpp); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * now we know the exact size we need, realloc the data + * 4 = 1 (for '"') + 3 (for '",\n') + * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n') + */ + if(image->width > UINT_MAX / image->cpp || + (tmp = image->width * image->cpp + 4) <= 4 || + image->height > UINT_MAX / tmp || + (tmp = image->height * tmp + 1) <= 1 || + (ptr_size += tmp) <= tmp) + RETURN(XpmNoMemory); + + p = (char *) XpmRealloc(ptr, ptr_size); + if (!p) + RETURN(XpmNoMemory); + ptr = p; + + /* print pixels */ + if (cmts && info->pixels_cmt) { +#ifndef VOID_SPRINTF + used_size += +#endif + snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->pixels_cmt); +#ifdef VOID_SPRINTF + used_size += strlen(info->pixels_cmt) + 5; +#endif + } + WritePixels(ptr + used_size, ptr_size - used_size, &used_size, image->width, image->height, + image->cpp, image->data, image->colorTable); + + /* print extensions */ + if (extensions) + WriteExtensions(ptr + used_size, ptr_size-used_size, &used_size, + info->extensions, info->nextensions); + + /* close the array */ + strcpy(ptr + used_size, "};\n"); + + *buffer_return = ptr; + + return (XpmSuccess); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (ptr) + XpmFree(ptr); + return (ErrorStatus); +} + + +static int +WriteColors( + char **dataptr, + unsigned int *data_size, + unsigned int *used_size, + XpmColor *colors, + unsigned int ncolors, + unsigned int cpp) +{ + char buf[BUFSIZ] = {0}; + unsigned int a, key, l; + char *s, *s2; + char **defaults; + + *buf = '"'; + for (a = 0; a < ncolors; a++, colors++) { + + defaults = (char **) colors; + s = buf + 1; + if(cpp > (sizeof(buf) - (s-buf))) + return(XpmNoMemory); + strncpy(s, *defaults++, cpp); + s += cpp; + + for (key = 1; key <= NKEYS; key++, defaults++) { + if ((s2 = *defaults)) { +#ifndef VOID_SPRINTF + s += +#endif + /* assume C99 compliance */ + snprintf(s, sizeof(buf) - (s-buf), "\t%s %s", xpmColorKeys[key - 1], s2); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + /* now let's check if s points out-of-bounds */ + if((s-buf) > sizeof(buf)) + return(XpmNoMemory); + } + } + if(sizeof(buf) - (s-buf) < 4) + return(XpmNoMemory); + strcpy(s, "\",\n"); + l = s + 3 - buf; + if( *data_size >= UINT_MAX-l || + *data_size + l <= *used_size || + (*data_size + l - *used_size) <= sizeof(buf)) + return(XpmNoMemory); + s = (char *) XpmRealloc(*dataptr, *data_size + l); + if (!s) + return (XpmNoMemory); + *data_size += l; + strcpy(s + *used_size, buf); + *used_size += l; + *dataptr = s; + } + return (XpmSuccess); +} + +static void +WritePixels( + char *dataptr, + unsigned int data_size, + unsigned int *used_size, + unsigned int width, + unsigned int height, + unsigned int cpp, + unsigned int *pixels, + XpmColor *colors) +{ + char *s = dataptr; + unsigned int x, y, h; + + if(height <= 1) + return; + + h = height - 1; + for (y = 0; y < h; y++) { + *s++ = '"'; + for (x = 0; x < width; x++, pixels++) { + if(cpp >= (data_size - (s-dataptr))) + return; + strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? :-\ */ + s += cpp; + } + if((data_size - (s-dataptr)) < 4) + return; + strcpy(s, "\",\n"); + s += 3; + } + /* duplicate some code to avoid a test in the loop */ + *s++ = '"'; + for (x = 0; x < width; x++, pixels++) { + if(cpp >= (data_size - (s-dataptr))) + return; + strncpy(s, colors[*pixels].string, cpp); /* how can we trust *pixels? */ + s += cpp; + } + *s++ = '"'; + *used_size += s - dataptr; +} + +static unsigned int +ExtensionsSize( + XpmExtension *ext, + unsigned int num) +{ + unsigned int x, y, a, size; + char **line; + + size = 0; + if(num == 0) + return(0); /* ok? */ + for (x = 0; x < num; x++, ext++) { + /* 11 = 10 (for ',\n"XPMEXT ') + 1 (for '"') */ + size += strlen(ext->name) + 11; + a = ext->nlines; /* how can we trust ext->nlines to be not out-of-bounds? */ + for (y = 0, line = ext->lines; y < a; y++, line++) + /* 4 = 3 (for ',\n"') + 1 (for '"') */ + size += strlen(*line) + 4; + } + /* 13 is for ',\n"XPMENDEXT"' */ + if(size > UINT_MAX - 13) /* unlikely */ + return(0); + return size + 13; +} + +static void +WriteExtensions( + char *dataptr, + unsigned int data_size, + unsigned int *used_size, + XpmExtension *ext, + unsigned int num) +{ + unsigned int x, y, a; + char **line; + char *s = dataptr; + + for (x = 0; x < num; x++, ext++) { +#ifndef VOID_SPRINTF + s += +#endif + snprintf(s, data_size - (s-dataptr), ",\n\"XPMEXT %s\"", ext->name); +#ifdef VOID_SPRINTF + s += strlen(ext->name) + 11; +#endif + a = ext->nlines; + for (y = 0, line = ext->lines; y < a; y++, line++) { +#ifndef VOID_SPRINTF + s += +#endif + snprintf(s, data_size - (s-dataptr), ",\n\"%s\"", *line); +#ifdef VOID_SPRINTF + s += strlen(*line) + 4; +#endif + } + } + strncpy(s, ",\n\"XPMENDEXT\"", data_size - (s-dataptr)-1); + *used_size += s - dataptr + 13; +} + +static int +CommentsSize(XpmInfo *info) +{ + int size = 0; + + /* 5 = 2 (for "/_*") + 3 (for "*_/\n") */ + /* wrap possible but *very* unlikely */ + if (info->hints_cmt) + size += 5 + strlen(info->hints_cmt); + + if (info->colors_cmt) + size += 5 + strlen(info->colors_cmt); + + if (info->pixels_cmt) + size += 5 + strlen(info->pixels_cmt); + + return size; +} diff --git a/src/CrBufFrP.c b/src/CrBufFrP.c new file mode 100644 index 0000000..de3e776 --- /dev/null +++ b/src/CrBufFrP.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrBufFrP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM buffer * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmCreateBufferFromPixmap( + Display *display, + char **buffer_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* create the buffer */ + ErrorStatus = XpmCreateBufferFromImage(display, buffer_return, ximage, + shapeimage, attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} diff --git a/src/CrDatFrI.c b/src/CrDatFrI.c new file mode 100644 index 0000000..0dacf51 --- /dev/null +++ b/src/CrDatFrI.c @@ -0,0 +1,403 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrDataFI.c: * +* * +* XPM library * +* Scan an image and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +LFUNC(CreateColors, int, (char **dataptr, unsigned int *data_size, + XpmColor *colors, unsigned int ncolors, + unsigned int cpp)); + +LFUNC(CreatePixels, void, (char **dataptr, unsigned int data_size, + unsigned int width, + unsigned int height, unsigned int cpp, + unsigned int *pixels, XpmColor *colors)); + +LFUNC(CountExtensions, void, (XpmExtension *ext, unsigned int num, + unsigned int *ext_size, + unsigned int *ext_nlines)); + +LFUNC(CreateExtensions, void, (char **dataptr, unsigned int data_size, + unsigned int offset, + XpmExtension *ext, unsigned int num, + unsigned int ext_nlines)); + +int +XpmCreateDataFromImage( + Display *display, + char ***data_return, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes) +{ + XpmImage xpmimage; + XpmInfo info; + int ErrorStatus; + + /* initialize return value */ + if (data_return) + *data_return = NULL; + + /* create an XpmImage from the image */ + ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage, + &xpmimage, attributes); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* create the data from the XpmImage */ + if (attributes) { + xpmSetInfo(&info, attributes); + ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, &info); + } else + ErrorStatus = XpmCreateDataFromXpmImage(data_return, &xpmimage, NULL); + + /* free the XpmImage */ + XpmFreeXpmImage(&xpmimage); + + return (ErrorStatus); +} + +#undef RETURN +#define RETURN(status) \ +do \ +{ \ + ErrorStatus = status; \ + goto exit; \ +} while(0) + +int +XpmCreateDataFromXpmImage( + char ***data_return, + XpmImage *image, + XpmInfo *info) +{ + /* calculation variables */ + int ErrorStatus; + char buf[BUFSIZ]; + char **header = NULL, **data, **sptr, **sptr2, *s; + unsigned int header_size, header_nlines; + unsigned int data_size, data_nlines; + unsigned int extensions = 0, ext_size = 0, ext_nlines = 0; + unsigned int offset, l, n; + + *data_return = NULL; + + extensions = info && (info->valuemask & XpmExtensions) + && info->nextensions; + + /* compute the number of extensions lines and size */ + if (extensions) + CountExtensions(info->extensions, info->nextensions, + &ext_size, &ext_nlines); + + /* + * alloc a temporary array of char pointer for the header section which + * is the hints line + the color table lines + */ + header_nlines = 1 + image->ncolors; /* this may wrap and/or become 0 */ + + /* 2nd check superfluous if we do not need header_nlines any further */ + if(header_nlines <= image->ncolors || + header_nlines >= UINT_MAX / sizeof(char *)) + return(XpmNoMemory); + + header_size = sizeof(char *) * header_nlines; + if (header_size >= UINT_MAX / sizeof(char *)) + return (XpmNoMemory); + header = (char **) XpmCalloc(header_size, sizeof(char *)); /* can we trust image->ncolors */ + if (!header) + return (XpmNoMemory); + + /* print the hints line */ + s = buf; +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, "%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + + if (info && (info->valuemask & XpmHotspot)) { +#ifndef VOID_SPRINTF + s += +#endif + sprintf(s, " %d %d", info->x_hotspot, info->y_hotspot); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + } + if (extensions) { + strcpy(s, " XPMEXT"); + s += 7; + } + l = s - buf + 1; + *header = (char *) XpmMalloc(l); + if (!*header) + RETURN(XpmNoMemory); + header_size += l; + strcpy(*header, buf); + + /* print colors */ + ErrorStatus = CreateColors(header + 1, &header_size, + image->colorTable, image->ncolors, image->cpp); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* now we know the size needed, alloc the data and copy the header lines */ + offset = image->width * image->cpp + 1; + + if(offset <= image->width || offset <= image->cpp) + RETURN(XpmNoMemory); + + if( (image->height + ext_nlines) >= UINT_MAX / sizeof(char *)) + RETURN(XpmNoMemory); + data_size = (image->height + ext_nlines) * sizeof(char *); + + if (image->height > UINT_MAX / offset || + image->height * offset > UINT_MAX - data_size) + RETURN(XpmNoMemory); + data_size += image->height * offset; + + if( (header_size + ext_size) >= (UINT_MAX - data_size) ) + RETURN(XpmNoMemory); + data_size += header_size + ext_size; + + data = (char **) XpmMalloc(data_size); + if (!data) + RETURN(XpmNoMemory); + + data_nlines = header_nlines + image->height + ext_nlines; + *data = (char *) (data + data_nlines); + + /* can header have less elements then n suggests? */ + n = image->ncolors; + for (l = 0, sptr = data, sptr2 = header; l <= n && sptr && sptr2; l++, sptr++, sptr2++) { + strcpy(*sptr, *sptr2); + *(sptr + 1) = *sptr + strlen(*sptr2) + 1; + } + + /* print pixels */ + data[header_nlines] = (char *) data + header_size + + (image->height + ext_nlines) * sizeof(char *); + + CreatePixels(data + header_nlines, data_size-header_nlines, image->width, image->height, + image->cpp, image->data, image->colorTable); + + /* print extensions */ + if (extensions) + CreateExtensions(data + header_nlines + image->height - 1, + data_size - header_nlines - image->height + 1, offset, + info->extensions, info->nextensions, + ext_nlines); + + *data_return = data; + ErrorStatus = XpmSuccess; + +/* exit point, free only locally allocated variables */ +exit: + if (header) { + for (l = 0; l < header_nlines; l++) + if (header[l]) + XpmFree(header[l]); + XpmFree(header); + } + return(ErrorStatus); +} + +static int +CreateColors( + char **dataptr, + unsigned int *data_size, + XpmColor *colors, + unsigned int ncolors, + unsigned int cpp) +{ + char buf[BUFSIZ]; + unsigned int a, key, l; + char *s, *s2; + char **defaults; + + /* can ncolors be trusted here? */ + for (a = 0; a < ncolors; a++, colors++, dataptr++) { + + defaults = (char **) colors; + if(sizeof(buf) <= cpp) + return(XpmNoMemory); + strncpy(buf, *defaults++, cpp); + s = buf + cpp; + + if(sizeof(buf) <= (s-buf)) + return XpmNoMemory; + + for (key = 1; key <= NKEYS; key++, defaults++) { + if ((s2 = *defaults)) { +#ifndef VOID_SPRINTF + s += +#endif + /* assume C99 compliance */ + snprintf(s, sizeof(buf)-(s-buf), "\t%s %s", xpmColorKeys[key - 1], s2); +#ifdef VOID_SPRINTF + s += strlen(s); +#endif + /* does s point out-of-bounds? */ + if(sizeof(buf) < (s-buf)) + return XpmNoMemory; + } + } + /* what about using strdup()? */ + l = s - buf + 1; + s = (char *) XpmMalloc(l); + if (!s) + return (XpmNoMemory); + *data_size += l; + *dataptr = strcpy(s, buf); + } + return (XpmSuccess); +} + +static void +CreatePixels( + char **dataptr, + unsigned int data_size, + unsigned int width, + unsigned int height, + unsigned int cpp, + unsigned int *pixels, + XpmColor *colors) +{ + char *s; + unsigned int x, y, h, offset; + + if(height <= 1) + return; + + h = height - 1; + + offset = width * cpp + 1; + + if(offset <= width || offset <= cpp) + return; + + /* why trust h? */ + for (y = 0; y < h; y++, dataptr++) { + s = *dataptr; + /* why trust width? */ + for (x = 0; x < width; x++, pixels++) { + if(cpp > (data_size - (s - *dataptr))) + return; + strncpy(s, colors[*pixels].string, cpp); /* why trust pixel? */ + s += cpp; + } + *s = '\0'; + if(offset > data_size) + return; + *(dataptr + 1) = *dataptr + offset; + } + /* duplicate some code to avoid a test in the loop */ + s = *dataptr; + /* why trust width? */ + for (x = 0; x < width; x++, pixels++) { + if(cpp > data_size - (s - *dataptr)) + return; + strncpy(s, colors[*pixels].string, cpp); /* why should we trust *pixel? */ + s += cpp; + } + *s = '\0'; +} + +static void +CountExtensions( + XpmExtension *ext, + unsigned int num, + unsigned int *ext_size, + unsigned int *ext_nlines) +{ + unsigned int x, y, a, size, nlines; + char **line; + + size = 0; + nlines = 0; + for (x = 0; x < num; x++, ext++) { + /* 1 for the name */ + nlines += ext->nlines + 1; + /* 8 = 7 (for "XPMEXT ") + 1 (for 0) */ + size += strlen(ext->name) + 8; + a = ext->nlines; + for (y = 0, line = ext->lines; y < a; y++, line++) + size += strlen(*line) + 1; + } + /* 10 and 1 are for the ending "XPMENDEXT" */ + *ext_size = size + 10; + *ext_nlines = nlines + 1; +} + +static void +CreateExtensions( + char **dataptr, + unsigned int data_size, + unsigned int offset, + XpmExtension *ext, + unsigned int num, + unsigned int ext_nlines) +{ + unsigned int x, y, a, b; + char **line; + + *(dataptr + 1) = *dataptr + offset; + dataptr++; + a = 0; + for (x = 0; x < num; x++, ext++) { + snprintf(*dataptr, data_size, "XPMEXT %s", ext->name); + a++; + if (a < ext_nlines) + *(dataptr + 1) = *dataptr + strlen(ext->name) + 8; + dataptr++; + b = ext->nlines; /* can we trust these values? */ + for (y = 0, line = ext->lines; y < b; y++, line++) { + strcpy(*dataptr, *line); + a++; + if (a < ext_nlines) + *(dataptr + 1) = *dataptr + strlen(*line) + 1; + dataptr++; + } + } + strcpy(*dataptr, "XPMENDEXT"); +} diff --git a/src/CrDatFrP.c b/src/CrDatFrP.c new file mode 100644 index 0000000..0e17fee --- /dev/null +++ b/src/CrDatFrP.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrDataFP.c: * +* * +* XPM library * +* Scan a pixmap and possibly its mask and create an XPM array * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmCreateDataFromPixmap( + Display *display, + char ***data_return, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* create the data */ + ErrorStatus = XpmCreateDataFromImage(display, data_return, ximage, + shapeimage, attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} diff --git a/src/CrIFrBuf.c b/src/CrIFrBuf.c new file mode 100644 index 0000000..b6b12ca --- /dev/null +++ b/src/CrIFrBuf.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrIFrBuf.c: * +* * +* XPM library * +* Parse an Xpm buffer (file in memory) and create the image and possibly its * +* mask * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +LFUNC(OpenBuffer, void, (char *buffer, xpmData *mdata)); + +int +XpmCreateImageFromBuffer( + Display *display, + char *buffer, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + xpmData mdata; + + xpmInitXpmImage(&image); + xpmInitXpmInfo(&info); + + /* open buffer to read */ + OpenBuffer(buffer, &mdata); + + /* create the XImage from the XpmData */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, &info, attributes); + } else + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, NULL, attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmCreateXpmImageFromBuffer( + char *buffer, + XpmImage *image, + XpmInfo *info) +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open buffer to read */ + OpenBuffer(buffer, &mdata); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + return (ErrorStatus); +} + +/* + * open the given buffer to be read or written as an xpmData which is returned + */ +static void +OpenBuffer( + char *buffer, + xpmData *mdata) +{ + mdata->type = XPMBUFFER; + mdata->cptr = buffer; + mdata->CommentLength = 0; +} diff --git a/src/CrIFrDat.c b/src/CrIFrDat.c new file mode 100644 index 0000000..9ef1557 --- /dev/null +++ b/src/CrIFrDat.c @@ -0,0 +1,122 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrIFrData.c: * +* * +* XPM library * +* Parse an Xpm array and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +LFUNC(OpenArray, void, (char **data, xpmData *mdata)); + +int +XpmCreateImageFromData( + Display *display, + char **data, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + xpmData mdata; + + xpmInitXpmImage(&image); + xpmInitXpmInfo(&info); + + /* open data */ + OpenArray(data, &mdata); + + /* create an XpmImage from the file */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, &info, attributes); + } else + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, NULL, attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmCreateXpmImageFromData( + char **data, + XpmImage *image, + XpmInfo *info) +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open data */ + OpenArray(data, &mdata); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + return (ErrorStatus); +} + +/* + * open the given array to be read or written as an xpmData which is returned + */ +static void +OpenArray( + char **data, + xpmData *mdata) +{ + mdata->type = XPMARRAY; + mdata->stream.data = data; + mdata->cptr = *data; + mdata->line = 0; + mdata->CommentLength = 0; + mdata->Bcmt = mdata->Ecmt = NULL; + mdata->Bos = mdata->Eos = '\0'; + mdata->format = 0; /* this can only be Xpm 2 or 3 */ +} diff --git a/src/CrIFrP.c b/src/CrIFrP.c new file mode 100644 index 0000000..79c4c49 --- /dev/null +++ b/src/CrIFrP.c @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrIFrP.c: * +* * +* XPM library * +* Create the XImage related to the given Pixmap. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +void +xpmCreateImageFromPixmap( + Display *display, + Pixmap pixmap, + XImage **ximage_return, + unsigned int *width, + unsigned int *height) +{ + unsigned int dum; + int dummy; + Window win; + + if (*width == 0 && *height == 0) + XGetGeometry(display, pixmap, &win, &dummy, &dummy, + width, height, &dum, &dum); + + *ximage_return = XGetImage(display, pixmap, 0, 0, *width, *height, + AllPlanes, ZPixmap); +} diff --git a/src/CrPFrBuf.c b/src/CrPFrBuf.c new file mode 100644 index 0000000..2c28a41 --- /dev/null +++ b/src/CrPFrBuf.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrPFrBuf.c: * +* * +* XPM library * +* Parse an Xpm buffer and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmCreatePixmapFromBuffer( + Display *display, + Drawable d, + char *buffer, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the images */ + ErrorStatus = XpmCreateImageFromBuffer(display, buffer, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? + &shapeimage : NULL), + attributes); + + if (ErrorStatus < 0) /* fatal error */ + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} diff --git a/src/CrPFrDat.c b/src/CrPFrDat.c new file mode 100644 index 0000000..b65771d --- /dev/null +++ b/src/CrPFrDat.c @@ -0,0 +1,81 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrPFrData.c: * +* * +* XPM library * +* Parse an Xpm array and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmCreatePixmapFromData( + Display *display, + Drawable d, + char **data, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the images */ + ErrorStatus = XpmCreateImageFromData(display, data, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? + &shapeimage : NULL), + attributes); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + if (ErrorStatus < 0) /* fatal error */ + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} diff --git a/src/CrPFrI.c b/src/CrPFrI.c new file mode 100644 index 0000000..8f6f4aa --- /dev/null +++ b/src/CrPFrI.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* CrPFrI.c: * +* * +* XPM library * +* Create the Pixmap related to the given XImage. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +void +xpmCreatePixmapFromImage( + Display *display, + Drawable d, + XImage *ximage, + Pixmap *pixmap_return) +{ + GC gc; + XGCValues values; + + *pixmap_return = XCreatePixmap(display, d, ximage->width, + ximage->height, ximage->depth); + /* set fg and bg in case we have an XYBitmap */ + values.foreground = 1; + values.background = 0; + gc = XCreateGC(display, *pixmap_return, + GCForeground | GCBackground, &values); + + XPutImage(display, *pixmap_return, gc, ximage, 0, 0, 0, 0, + ximage->width, ximage->height); + + XFreeGC(display, gc); +} diff --git a/src/Image.c b/src/Image.c new file mode 100644 index 0000000..e0223cc --- /dev/null +++ b/src/Image.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* Image.c: * +* * +* XPM library * +* Functions to init and free the XpmImage structure. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +/* + * Init returned data to free safely later on + */ +void +xpmInitXpmImage(XpmImage *image) +{ + image->ncolors = 0; + image->colorTable = NULL; + image->data = NULL; +} + +/* + * Free the XpmImage data which have been allocated + */ +void +XpmFreeXpmImage(XpmImage *image) +{ + if (image->colorTable) + xpmFreeColorTable(image->colorTable, image->ncolors); + if (image->data) + XpmFree(image->data); + image->data = NULL; +} diff --git a/src/Info.c b/src/Info.c new file mode 100644 index 0000000..e975a6d --- /dev/null +++ b/src/Info.c @@ -0,0 +1,125 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* Info.c: * +* * +* XPM library * +* Functions related to the XpmInfo structure. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +/* + * Init returned data to free safely later on + */ +void +xpmInitXpmInfo(XpmInfo *info) +{ + if (info) { + info->hints_cmt = NULL; + info->colors_cmt = NULL; + info->pixels_cmt = NULL; + info->extensions = NULL; + info->nextensions = 0; + } +} + +/* + * Free the XpmInfo data which have been allocated + */ +void +XpmFreeXpmInfo(XpmInfo *info) +{ + if (info) { + if (info->valuemask & XpmComments) { + if (info->hints_cmt) { + XpmFree(info->hints_cmt); + info->hints_cmt = NULL; + } + if (info->colors_cmt) { + XpmFree(info->colors_cmt); + info->colors_cmt = NULL; + } + if (info->pixels_cmt) { + XpmFree(info->pixels_cmt); + info->pixels_cmt = NULL; + } + } + if (info->valuemask & XpmReturnExtensions && info->nextensions) { + XpmFreeExtensions(info->extensions, info->nextensions); + info->extensions = NULL; + info->nextensions = 0; + } + info->valuemask = 0; + } +} + +/* + * Set the XpmInfo valuemask to retrieve required info + */ +void +xpmSetInfoMask( + XpmInfo *info, + XpmAttributes *attributes) +{ + info->valuemask = 0; + if (attributes->valuemask & XpmReturnInfos) + info->valuemask |= XpmReturnComments; + if (attributes->valuemask & XpmReturnExtensions) + info->valuemask |= XpmReturnExtensions; +} + +/* + * Fill in the XpmInfo with the XpmAttributes + */ +void +xpmSetInfo( + XpmInfo *info, + XpmAttributes *attributes) +{ + info->valuemask = 0; + if (attributes->valuemask & XpmInfos) { + info->valuemask |= XpmComments | XpmColorTable; + info->hints_cmt = attributes->hints_cmt; + info->colors_cmt = attributes->colors_cmt; + info->pixels_cmt = attributes->pixels_cmt; + } + if (attributes->valuemask & XpmExtensions) { + info->valuemask |= XpmExtensions; + info->extensions = attributes->extensions; + info->nextensions = attributes->nextensions; + } + if (attributes->valuemask & XpmHotspot) { + info->valuemask |= XpmHotspot; + info->x_hotspot = attributes->x_hotspot; + info->y_hotspot = attributes->y_hotspot; + } +} diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..297d310 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,43 @@ +# Daniel Stone disowns all copyright on this file. + +lib_LTLIBRARIES=libXpm.la + +AM_CPPFLAGS = -I$(top_srcdir)/include/X11/ +AM_CFLAGS = $(CWARNFLAGS) $(XPM_CFLAGS) + +libXpm_la_LDFLAGS = -version-number 4:11:0 -no-undefined +libXpm_la_LIBADD = $(XPM_LIBS) + +libXpm_la_SOURCES = \ + Attrib.c \ + CrBufFrI.c \ + CrBufFrP.c \ + CrDatFrI.c \ + CrDatFrP.c \ + CrIFrBuf.c \ + CrIFrDat.c \ + CrIFrP.c \ + CrPFrBuf.c \ + CrPFrDat.c \ + CrPFrI.c \ + Image.c \ + Info.c \ + RdFToBuf.c \ + RdFToDat.c \ + RdFToI.c \ + RdFToP.c \ + WrFFrBuf.c \ + WrFFrDat.c \ + WrFFrI.c \ + WrFFrP.c \ + XpmI.h \ + create.c \ + data.c \ + hashtab.c \ + misc.c \ + parse.c \ + rgb.c \ + rgbtab.h \ + scan.c + +EXTRA_DIST = amigax.c amigax.h simx.c simx.h diff --git a/src/RdFToBuf.c b/src/RdFToBuf.c new file mode 100644 index 0000000..8501d23 --- /dev/null +++ b/src/RdFToBuf.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* RdFToBuf.c: * +* * +* XPM library * +* Copy a file to a malloc'ed buffer, provided as a convenience. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#include +#if !defined(FOR_MSW) && !defined(WIN32) +#include +#endif +#ifndef VAX11C +#include +#endif +#if defined(FOR_MSW) || defined(WIN32) +#include +#define stat _stat +#define fstat _fstat +#define fdopen _fdopen +#define O_RDONLY _O_RDONLY +#endif + +int +XpmReadFileToBuffer( + char *filename, + char **buffer_return) +{ + int fd, fcheck; + off_t len; + char *ptr; + struct stat stats; + FILE *fp; + + *buffer_return = NULL; + +#ifndef VAX11C + fd = open(filename, O_RDONLY); +#else + fd = open(filename, O_RDONLY, NULL); +#endif + if (fd < 0) + return XpmOpenFailed; + + if (fstat(fd, &stats)) { + close(fd); + return XpmOpenFailed; + } + fp = fdopen(fd, "r"); + if (!fp) { + close(fd); + return XpmOpenFailed; + } + len = stats.st_size; + ptr = (char *) XpmMalloc(len + 1); + if (!ptr) { + fclose(fp); + return XpmNoMemory; + } + fcheck = fread(ptr, 1, len, fp); + fclose(fp); +#ifdef VMS + /* VMS often stores text files in a variable-length record format, + where there are two bytes of size followed by the record. fread + converts this so it looks like a record followed by a newline. + Unfortunately, the size reported by fstat() (and fseek/ftell) + counts the two bytes for the record terminator, while fread() + counts only one. So, fread() sees fewer bytes in the file (size + minus # of records) and thus when asked to read the amount + returned by stat(), it fails. + The best solution, suggested by DEC, seems to consider the length + returned from fstat() as an upper bound and call fread() with + a record length of 1. Then don't check the return value. + We'll check for 0 for gross error that's all. + */ + len = fcheck; + if (fcheck == 0) { +#else + if (fcheck != len) { +#endif + XpmFree(ptr); + return XpmOpenFailed; + } + ptr[len] = '\0'; + *buffer_return = ptr; + return XpmSuccess; +} diff --git a/src/RdFToDat.c b/src/RdFToDat.c new file mode 100644 index 0000000..87f7f1e --- /dev/null +++ b/src/RdFToDat.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* RdFToDat.c: * +* * +* XPM library * +* Parse an XPM file and create an array of strings corresponding to it. * +* * +* Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmReadFileToData( + char *filename, + char ***data_return) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + info.valuemask = XpmReturnComments | XpmReturnExtensions; + + /* + * initialize return value + */ + if (data_return) + *data_return = NULL; + + ErrorStatus = XpmReadFileToXpmImage(filename, &image, &info); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + ErrorStatus = + XpmCreateDataFromXpmImage(data_return, &image, &info); + + XpmFreeXpmImage(&image); + XpmFreeXpmInfo(&info); + + return (ErrorStatus); +} diff --git a/src/RdFToI.c b/src/RdFToI.c new file mode 100644 index 0000000..e56e3f8 --- /dev/null +++ b/src/RdFToI.c @@ -0,0 +1,273 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* RdFToI.c: * +* * +* XPM library * +* Parse an XPM file and create the image and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#ifndef NO_ZPIPE +#include +#include +#include +#include +#else +#ifdef FOR_MSW +#include +#endif +#endif + +LFUNC(OpenReadFile, int, (char *filename, xpmData *mdata)); +LFUNC(xpmDataClose, void, (xpmData *mdata)); + +FUNC(xpmPipeThrough, FILE*, (int fd, + const char *cmd, + const char *arg1, + const char *mode)); + +#ifndef CXPMPROG +int +XpmReadFileToImage( + Display *display, + char *filename, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + xpmData mdata; + + xpmInitXpmImage(&image); + xpmInitXpmInfo(&info); + + /* open file to read */ + if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* create the XImage from the XpmData */ + if (attributes) { + xpmInitAttributes(attributes); + xpmSetInfoMask(&info, attributes); + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, &info, attributes); + } else + ErrorStatus = xpmParseDataAndCreate(display, &mdata, + image_return, shapeimage_return, + &image, NULL, attributes); + if (attributes) { + if (ErrorStatus >= 0) /* no fatal error */ + xpmSetAttributes(attributes, &image, &info); + XpmFreeXpmInfo(&info); + } + + xpmDataClose(&mdata); + /* free the XpmImage */ + XpmFreeXpmImage(&image); + + return (ErrorStatus); +} + +int +XpmReadFileToXpmImage( + char *filename, + XpmImage *image, + XpmInfo *info) +{ + xpmData mdata; + int ErrorStatus; + + /* init returned values */ + xpmInitXpmImage(image); + xpmInitXpmInfo(info); + + /* open file to read */ + if ((ErrorStatus = OpenReadFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* create the XpmImage from the XpmData */ + ErrorStatus = xpmParseData(&mdata, image, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} +#endif /* CXPMPROG */ + +#ifndef NO_ZPIPE +/* Do not depend on errno after read_through */ +FILE* +xpmPipeThrough( + int fd, + const char *cmd, + const char *arg1, + const char *mode) +{ + FILE* fp; + int status, fds[2], in = 0, out = 1; + pid_t pid; + if ( 'w' == *mode ) + out = 0, in = 1; + if ( pipe(fds) < 0 ) + return NULL; + pid = fork(); + if ( pid < 0 ) + goto fail1; + if ( 0 == pid ) + { + close(fds[in]); + if ( dup2(fds[out], out) < 0 ) + goto err; + close(fds[out]); + if ( dup2(fd, in) < 0 ) + goto err; + close(fd); + pid = fork(); + if ( pid < 0 ) + goto err; + if ( 0 == pid ) + { + execlp(cmd, cmd, arg1, (char *)NULL); + perror(cmd); + goto err; + } + _exit(0); + err: + _exit(1); + } + close(fds[out]); + /* calling process: wait for first child */ + while ( waitpid(pid, &status, 0) < 0 && EINTR == errno ) + ; + if ( WIFSIGNALED(status) || + (WIFEXITED(status) && WEXITSTATUS(status) != 0) ) + goto fail2; + fp = fdopen(fds[in], mode); + if ( !fp ) + goto fail2; + close(fd); /* still open in 2nd child */ + return fp; +fail1: + close(fds[out]); +fail2: + close(fds[in]); + return NULL; +} +#endif + +/* + * open the given file to be read as an xpmData which is returned. + */ +static int +OpenReadFile( + char *filename, + xpmData *mdata) +{ + if (!filename) { + mdata->stream.file = (stdin); + mdata->type = XPMFILE; + } else { + int fd = open(filename, O_RDONLY); +#if defined(NO_ZPIPE) + if ( fd < 0 ) + return XpmOpenFailed; +#else + const char* ext = NULL; + if ( fd >= 0 ) + ext = strrchr(filename, '.'); +#ifdef STAT_ZFILE /* searching for z-files if the given name not found */ + else + { + size_t len = strlen(filename); + char *compressfile = (char *) XpmMalloc(len + 4); + if ( !compressfile ) + return (XpmNoMemory); + strcpy(compressfile, filename); + strcpy(compressfile + len, ext = ".Z"); + fd = open(compressfile, O_RDONLY); + if ( fd < 0 ) + { + strcpy(compressfile + len, ext = ".gz"); + fd = open(compressfile, O_RDONLY); + if ( fd < 0 ) + { + XpmFree(compressfile); + return XpmOpenFailed; + } + } + XpmFree(compressfile); + } +#endif + if ( ext && !strcmp(ext, ".Z") ) + { + mdata->type = XPMPIPE; + mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r"); + } + else if ( ext && !strcmp(ext, ".gz") ) + { + mdata->type = XPMPIPE; + mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r"); + } + else +#endif /* z-files */ + { + mdata->type = XPMFILE; + mdata->stream.file = fdopen(fd, "r"); + } + if (!mdata->stream.file) + { + close(fd); + return (XpmOpenFailed); + } + } + mdata->CommentLength = 0; +#ifdef CXPMPROG + mdata->lineNum = 0; + mdata->charNum = 0; +#endif + return (XpmSuccess); +} + +/* + * close the file related to the xpmData if any + */ +static void +xpmDataClose(xpmData *mdata) +{ + if (mdata->stream.file != (stdin)) + fclose(mdata->stream.file); +} diff --git a/src/RdFToP.c b/src/RdFToP.c new file mode 100644 index 0000000..bacedda --- /dev/null +++ b/src/RdFToP.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* RdFToP.c: * +* * +* XPM library * +* Parse an XPM file and create the pixmap and possibly its mask * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmReadFileToPixmap( + Display *display, + Drawable d, + char *filename, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the images */ + ErrorStatus = XpmReadFileToImage(display, filename, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? &shapeimage : NULL), + attributes); + + if (ErrorStatus < 0) /* fatal error */ + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} diff --git a/src/WrFFrBuf.c b/src/WrFFrBuf.c new file mode 100644 index 0000000..bd1c45b --- /dev/null +++ b/src/WrFFrBuf.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* WrFFrBuf.c: * +* * +* XPM library * +* Write a memory buffer to a file, provided as a convenience. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmWriteFileFromBuffer( + char *filename, + char *buffer) +{ + int fcheck, len; + FILE *fp = fopen(filename, "w"); + + if (!fp) + return XpmOpenFailed; + + len = strlen(buffer); + fcheck = fwrite(buffer, len, 1, fp); + fclose(fp); + if (fcheck != 1) + return XpmOpenFailed; /* maybe use a better return value */ + + return XpmSuccess; +} diff --git a/src/WrFFrDat.c b/src/WrFFrDat.c new file mode 100644 index 0000000..dc738b9 --- /dev/null +++ b/src/WrFFrDat.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* WrFFrData.c: * +* * +* XPM library * +* Parse an Xpm array and write a file that corresponds to it. * +* * +* Developed by Dan Greening dgreen@cs.ucla.edu / dgreen@sti.com * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmWriteFileFromData( + char *filename, + char **data) +{ + XpmImage image; + XpmInfo info; + int ErrorStatus; + + info.valuemask = XpmReturnComments | XpmReturnExtensions; + + ErrorStatus = XpmCreateXpmImageFromData(data, &image, &info); + + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + ErrorStatus = XpmWriteFileFromXpmImage(filename, &image, &info); + + XpmFreeXpmImage(&image); + XpmFreeXpmInfo(&info); + + return (ErrorStatus); +} diff --git a/src/WrFFrI.c b/src/WrFFrI.c new file mode 100644 index 0000000..b592fa1 --- /dev/null +++ b/src/WrFFrI.c @@ -0,0 +1,364 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* WrFFrI.c: * +* * +* XPM library * +* Write an image and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +#ifndef NO_ZPIPE +#include "sys/wait.h" +#include "sys/types.h" +#include "fcntl.h" +#include "unistd.h" +#include "errno.h" +#endif + +/* MS Windows define a function called WriteFile @#%#&!!! */ +LFUNC(xpmWriteFile, int, (FILE *file, XpmImage *image, const char *name, + XpmInfo *info)); + +LFUNC(WriteColors, void, (FILE *file, XpmColor *colors, unsigned int ncolors)); + +LFUNC(WritePixels, int, (FILE *file, unsigned int width, unsigned int height, + unsigned int cpp, unsigned int *pixels, + XpmColor *colors)); + +LFUNC(WriteExtensions, void, (FILE *file, XpmExtension *ext, + unsigned int num)); + +LFUNC(OpenWriteFile, int, (char *filename, xpmData *mdata)); +LFUNC(xpmDataClose, void, (xpmData *mdata)); + +int +XpmWriteFileFromImage( + Display *display, + char *filename, + XImage *image, + XImage *shapeimage, + XpmAttributes *attributes) +{ + XpmImage xpmimage; + XpmInfo info; + int ErrorStatus; + + /* create an XpmImage from the image */ + ErrorStatus = XpmCreateXpmImageFromImage(display, image, shapeimage, + &xpmimage, attributes); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* write the file from the XpmImage */ + if (attributes) { + xpmSetInfo(&info, attributes); + ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, &info); + } else + ErrorStatus = XpmWriteFileFromXpmImage(filename, &xpmimage, NULL); + + /* free the XpmImage */ + XpmFreeXpmImage(&xpmimage); + + return (ErrorStatus); +} + +int +XpmWriteFileFromXpmImage( + char *filename, + XpmImage *image, + XpmInfo *info) +{ + xpmData mdata; + const char *name; + char *dot, *s, new_name[BUFSIZ] = {0}; + int ErrorStatus; + + /* open file to write */ + if ((ErrorStatus = OpenWriteFile(filename, &mdata)) != XpmSuccess) + return (ErrorStatus); + + /* figure out a name */ + if (filename) { +#ifdef VMS + name = filename; +#else + if (!(name = strrchr(filename, '/')) +#ifdef AMIGA + && !(name = strrchr(filename, ':')) +#endif + ) + name = filename; + else + name++; +#endif + /* let's try to make a valid C syntax name */ + if (strchr(name, '.')) { + strncpy(new_name, name, sizeof(new_name)); + new_name[sizeof(new_name)-1] = '\0'; + /* change '.' to '_' */ + name = s = new_name; + while ((dot = strchr(s, '.'))) { + *dot = '_'; + s = dot; + } + } + if (strchr(name, '-')) { + if (name != new_name) { + strncpy(new_name, name, sizeof(new_name)); + new_name[sizeof(new_name)-1] = '\0'; + name = new_name; + } + /* change '-' to '_' */ + s = new_name; + while ((dot = strchr(s, '-'))) { + *dot = '_'; + s = dot; + } + } + } else + name = "image_name"; + + /* write the XpmData from the XpmImage */ + if (ErrorStatus == XpmSuccess) + ErrorStatus = xpmWriteFile(mdata.stream.file, image, name, info); + + xpmDataClose(&mdata); + + return (ErrorStatus); +} + +static int +xpmWriteFile( + FILE *file, + XpmImage *image, + const char *name, + XpmInfo *info) +{ + /* calculation variables */ + unsigned int cmts, extensions; + int ErrorStatus; + + cmts = info && (info->valuemask & XpmComments); + extensions = info && (info->valuemask & XpmExtensions) + && info->nextensions; + + /* print the header line */ + fprintf(file, "/* XPM */\nstatic char * %s[] = {\n", name); + + /* print the hints line */ + if (cmts && info->hints_cmt) + fprintf(file, "/*%s*/\n", info->hints_cmt); + + fprintf(file, "\"%d %d %d %d", image->width, image->height, + image->ncolors, image->cpp); + + if (info && (info->valuemask & XpmHotspot)) + fprintf(file, " %d %d", info->x_hotspot, info->y_hotspot); + + if (extensions) + fprintf(file, " XPMEXT"); + + fprintf(file, "\",\n"); + + /* print colors */ + if (cmts && info->colors_cmt) + fprintf(file, "/*%s*/\n", info->colors_cmt); + + WriteColors(file, image->colorTable, image->ncolors); + + /* print pixels */ + if (cmts && info->pixels_cmt) + fprintf(file, "/*%s*/\n", info->pixels_cmt); + + ErrorStatus = WritePixels(file, image->width, image->height, image->cpp, + image->data, image->colorTable); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* print extensions */ + if (extensions) + WriteExtensions(file, info->extensions, info->nextensions); + + /* close the array */ + fprintf(file, "};\n"); + + return (XpmSuccess); +} + +static void +WriteColors( + FILE *file, + XpmColor *colors, + unsigned int ncolors) +{ + unsigned int a, key; + char *s; + char **defaults; + + for (a = 0; a < ncolors; a++, colors++) { + + defaults = (char **) colors; + fprintf(file, "\"%s", *defaults++); + + for (key = 1; key <= NKEYS; key++, defaults++) { + if ((s = *defaults)) + fprintf(file, "\t%s %s", xpmColorKeys[key - 1], s); + } + fprintf(file, "\",\n"); + } +} + + +static int +WritePixels( + FILE *file, + unsigned int width, + unsigned int height, + unsigned int cpp, + unsigned int *pixels, + XpmColor *colors) +{ + char *s, *p, *buf; + unsigned int x, y, h; + + h = height - 1; + if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) + return XpmNoMemory; + p = buf = (char *) XpmMalloc(width * cpp + 3); + if (!buf) + return (XpmNoMemory); + *buf = '"'; + p++; + for (y = 0; y < h; y++) { + s = p; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s++ = '"'; + *s = '\0'; + fprintf(file, "%s,\n", buf); + } + /* duplicate some code to avoid a test in the loop */ + s = p; + for (x = 0; x < width; x++, pixels++) { + strncpy(s, colors[*pixels].string, cpp); + s += cpp; + } + *s++ = '"'; + *s = '\0'; + fprintf(file, "%s", buf); + + XpmFree(buf); + return (XpmSuccess); +} + +static void +WriteExtensions( + FILE *file, + XpmExtension *ext, + unsigned int num) +{ + unsigned int x, y, n; + char **line; + + for (x = 0; x < num; x++, ext++) { + fprintf(file, ",\n\"XPMEXT %s\"", ext->name); + n = ext->nlines; + for (y = 0, line = ext->lines; y < n; y++, line++) + fprintf(file, ",\n\"%s\"", *line); + } + fprintf(file, ",\n\"XPMENDEXT\""); +} + + +#ifndef NO_ZPIPE +FUNC(xpmPipeThrough, FILE*, (int fd, + const char* cmd, + const char* arg1, + const char* mode)); +#endif + +/* + * open the given file to be written as an xpmData which is returned + */ +static int +OpenWriteFile( + char *filename, + xpmData *mdata) +{ + if (!filename) { + mdata->stream.file = (stdout); + mdata->type = XPMFILE; + } else { +#ifndef NO_ZPIPE + size_t len; +#endif + int fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644); + if ( fd < 0 ) + return(XpmOpenFailed); +#ifndef NO_ZPIPE + len = strlen(filename); + if (len > 2 && !strcmp(".Z", filename + (len - 2))) { + mdata->stream.file = xpmPipeThrough(fd, "compress", NULL, "w"); + mdata->type = XPMPIPE; + } else if (len > 3 && !strcmp(".gz", filename + (len - 3))) { + mdata->stream.file = xpmPipeThrough(fd, "gzip", "-q", "w"); + mdata->type = XPMPIPE; + } else +#endif + { + mdata->stream.file = fdopen(fd, "w"); + mdata->type = XPMFILE; + } + if (!mdata->stream.file) + return (XpmOpenFailed); + } + return (XpmSuccess); +} + +/* + * close the file related to the xpmData if any + */ +static void +xpmDataClose(xpmData *mdata) +{ + if (mdata->stream.file != (stdout)) + fclose(mdata->stream.file); +} + diff --git a/src/WrFFrP.c b/src/WrFFrP.c new file mode 100644 index 0000000..497ba56 --- /dev/null +++ b/src/WrFFrP.c @@ -0,0 +1,77 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* WrFFrP.c: * +* * +* XPM library * +* Write a pixmap and possibly its mask to an XPM file * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +int +XpmWriteFileFromPixmap( + Display *display, + char *filename, + Pixmap pixmap, + Pixmap shapemask, + XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* write to the file */ + ErrorStatus = XpmWriteFileFromImage(display, filename, ximage, shapeimage, + attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} diff --git a/src/XpmI.h b/src/XpmI.h new file mode 100644 index 0000000..122aea5 --- /dev/null +++ b/src/XpmI.h @@ -0,0 +1,329 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* XpmI.h: * +* * +* XPM library * +* Internal Include file * +* * +* ** Everything defined here is subject to changes any time. ** * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +#ifndef XPMI_h +#define XPMI_h + +#include "xpm.h" + +/* + * lets try to solve include files + */ + +#include +#include +#include +#include +/* stdio.h doesn't declare popen on a Sequent DYNIX OS */ +#ifdef sequent +extern FILE *popen(); +#endif + +#ifdef FOR_MSW +#include "simx.h" +#else +#include +#include +#include +#endif + +#ifdef VMS +#include +#include +#endif + +/* The following should help people wanting to use their own memory allocation + * functions. To avoid the overhead of a function call when the standard + * functions are used these are all macros, even the XpmFree function which + * needs to be a real function for the outside world though. + * So if change these be sure to change the XpmFree function in misc.c + * accordingly. + */ +#define XpmFree(ptr) free(ptr) + +#ifndef FOR_MSW +#define XpmMalloc(size) malloc((size)) +#define XpmRealloc(ptr, size) realloc((ptr), (size)) +#define XpmCalloc(nelem, elsize) calloc((nelem), (elsize)) +#else +/* checks for mallocs bigger than 64K */ +#define XpmMalloc(size) boundCheckingMalloc((long)(size))/* in simx.[ch] */ +#define XpmRealloc(ptr, size) boundCheckingRealloc((ptr),(long)(size)) +#define XpmCalloc(nelem, elsize) \ + boundCheckingCalloc((long)(nelem),(long) (elsize)) +#endif + +#if defined(SCO) || defined(__USLC__) +#include /* For SIZE_MAX */ +#endif +#include +#ifndef SIZE_MAX +# ifdef ULONG_MAX +# define SIZE_MAX ULONG_MAX +# else +# define SIZE_MAX UINT_MAX +# endif +#endif + +#define XPMMAXCMTLEN BUFSIZ +typedef struct { + unsigned int type; + union { + FILE *file; + char **data; + } stream; + char *cptr; + unsigned int line; + int CommentLength; + char Comment[XPMMAXCMTLEN]; + const char *Bcmt, *Ecmt; + char 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 { + const char *type; /* key word */ + const char *Bcmt; /* string beginning comments */ + const char *Ecmt; /* string ending comments */ + char Bos; /* character beginning strings */ + char Eos; /* character ending strings */ + const char *Strs; /* strings separator */ + const char *Dec; /* data declaration string */ + const char *Boa; /* string beginning assignment */ + const 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 const char *xpmColorKeys[]; + +#define TRANSPARENT_COLOR "None" /* this must be a string! */ + +/* number of xpmColorKeys */ +#define NKEYS 5 + +/* XPM internal routines */ + +FUNC(xpmParseData, int, (xpmData *data, XpmImage *image, XpmInfo *info)); +FUNC(xpmParseDataAndCreate, int, (Display *display, xpmData *data, + XImage **image_return, + XImage **shapeimage_return, + XpmImage *image, XpmInfo *info, + XpmAttributes *attributes)); + +FUNC(xpmFreeColorTable, void, (XpmColor *colorTable, int ncolors)); + +FUNC(xpmInitAttributes, void, (XpmAttributes *attributes)); + +FUNC(xpmInitXpmImage, void, (XpmImage *image)); + +FUNC(xpmInitXpmInfo, void, (XpmInfo *info)); + +FUNC(xpmSetInfoMask, void, (XpmInfo *info, XpmAttributes *attributes)); +FUNC(xpmSetInfo, void, (XpmInfo *info, XpmAttributes *attributes)); +FUNC(xpmSetAttributes, void, (XpmAttributes *attributes, XpmImage *image, + XpmInfo *info)); + +#if !defined(FOR_MSW) && !defined(AMIGA) +FUNC(xpmCreatePixmapFromImage, void, (Display *display, Drawable d, + XImage *ximage, Pixmap *pixmap_return)); + +FUNC(xpmCreateImageFromPixmap, void, (Display *display, Pixmap pixmap, + XImage **ximage_return, + unsigned int *width, + unsigned int *height)); +#endif + +/* structures and functions related to hastable code */ + +typedef struct _xpmHashAtom { + char *name; + void *data; +} *xpmHashAtom; + +typedef struct { + unsigned int size; + unsigned int limit; + unsigned int used; + xpmHashAtom *atomTable; +} xpmHashTable; + +FUNC(xpmHashTableInit, int, (xpmHashTable *table)); +FUNC(xpmHashTableFree, void, (xpmHashTable *table)); +FUNC(xpmHashSlot, xpmHashAtom *, (xpmHashTable *table, char *s)); +FUNC(xpmHashIntern, int, (xpmHashTable *table, char *tag, void *data)); + +#define HashAtomData(i) ((void *)(long)i) +#define HashColorIndex(slot) ((unsigned long)((*slot)->data)) +#define USE_HASHTABLE (cpp > 2 && ncolors > 4) + +/* I/O utility */ + +FUNC(xpmNextString, int, (xpmData *mdata)); +FUNC(xpmNextUI, int, (xpmData *mdata, unsigned int *ui_return)); +FUNC(xpmGetString, int, (xpmData *mdata, char **sptr, unsigned int *l)); + +#define xpmGetC(mdata) \ + ((!mdata->type || mdata->type == XPMBUFFER) ? \ + (*mdata->cptr++) : (getc(mdata->stream.file))) + +FUNC(xpmNextWord, unsigned int, + (xpmData *mdata, char *buf, unsigned int buflen)); +FUNC(xpmGetCmt, int, (xpmData *mdata, char **cmt)); +FUNC(xpmParseHeader, int, (xpmData *mdata)); +FUNC(xpmParseValues, int, (xpmData *data, unsigned int *width, + unsigned int *height, unsigned int *ncolors, + unsigned int *cpp, unsigned int *x_hotspot, + unsigned int *y_hotspot, unsigned int *hotspot, + unsigned int *extensions)); + +FUNC(xpmParseColors, int, (xpmData *data, unsigned int ncolors, + unsigned int cpp, XpmColor **colorTablePtr, + xpmHashTable *hashtable)); + +FUNC(xpmParseExtensions, int, (xpmData *data, XpmExtension **extensions, + unsigned int *nextensions)); + +/* RGB utility */ + +FUNC(xpmReadRgbNames, int, (char *rgb_fname, xpmRgbName *rgbn)); +FUNC(xpmGetRgbName, char *, (xpmRgbName *rgbn, int rgbn_max, + int red, int green, int blue)); +FUNC(xpmFreeRgbNames, void, (xpmRgbName *rgbn, int rgbn_max)); +#ifdef FOR_MSW +FUNC(xpmGetRGBfromName,int, (char *name, int *r, int *g, int *b)); +#endif + +#ifndef AMIGA +FUNC(xpm_xynormalizeimagebits, void, (register unsigned char *bp, + register XImage *img)); +FUNC(xpm_znormalizeimagebits, void, (register unsigned char *bp, + register XImage *img)); + +/* + * Macros + * + * The XYNORMALIZE macro determines whether XY format data requires + * normalization and calls a routine to do so if needed. The logic in + * this module is designed for LSBFirst byte and bit order, so + * normalization is done as required to present the data in this order. + * + * The ZNORMALIZE macro performs byte and nibble order normalization if + * required for Z format data. + * + * The XYINDEX macro computes the index to the starting byte (char) boundary + * for a bitmap_unit containing a pixel with coordinates x and y for image + * data in XY format. + * + * The ZINDEX* macros compute the index to the starting byte (char) boundary + * for a pixel with coordinates x and y for image data in ZPixmap format. + * + */ + +#define XYNORMALIZE(bp, img) \ + if ((img->byte_order == MSBFirst) || (img->bitmap_bit_order == MSBFirst)) \ + xpm_xynormalizeimagebits((unsigned char *)(bp), img) + +#define ZNORMALIZE(bp, img) \ + if (img->byte_order == MSBFirst) \ + xpm_znormalizeimagebits((unsigned char *)(bp), img) + +#define XYINDEX(x, y, img) \ + ((y) * img->bytes_per_line) + \ + (((x) + img->xoffset) / img->bitmap_unit) * (img->bitmap_unit >> 3) + +#define ZINDEX(x, y, img) ((y) * img->bytes_per_line) + \ + (((x) * img->bits_per_pixel) >> 3) + +#define ZINDEX32(x, y, img) ((y) * img->bytes_per_line) + ((x) << 2) + +#define ZINDEX16(x, y, img) ((y) * img->bytes_per_line) + ((x) << 1) + +#define ZINDEX8(x, y, img) ((y) * img->bytes_per_line) + (x) + +#define ZINDEX1(x, y, img) ((y) * img->bytes_per_line) + ((x) >> 3) +#endif /* not AMIGA */ + +#ifdef NEED_STRDUP +FUNC(xpmstrdup, char *, (char *s1)); +#else +#undef xpmstrdup +#define xpmstrdup strdup +#include +#endif + +#ifdef NEED_STRCASECMP +FUNC(xpmstrcasecmp, int, (char *s1, char *s2)); +#else +#undef xpmstrcasecmp +#define xpmstrcasecmp strcasecmp +#include +#endif + +FUNC(xpmatoui, unsigned int, + (char *p, unsigned int l, unsigned int *ui_return)); + +#endif diff --git a/src/amigax.c b/src/amigax.c new file mode 100644 index 0000000..f163960 --- /dev/null +++ b/src/amigax.c @@ -0,0 +1,385 @@ +/* + * Copyright (C) 19896 Lorens Younes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Lorens Younes shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Lorens Younes. + */ + +/*****************************************************************************\ +* amigax.c: * +* * +* XPM library * +* Emulates some Xlib functionality for Amiga. * +* * +* Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 * +* Revised 4/96 * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#include "amigax.h" + +#include +#include + +#include + + +static struct RastPort * +AllocRastPort (unsigned int, unsigned int, unsigned int); +static void +FreeRastPort (struct RastPort *, unsigned int,unsigned int); + + +static struct RastPort * +AllocRastPort ( + unsigned int width, + unsigned int height, + unsigned int depth) +{ + struct RastPort *rp; + + rp = XpmMalloc (sizeof (*rp)); + if (rp != NULL) + { + InitRastPort (rp); + if (GfxBase->LibNode.lib_Version >= 39) + { + rp->BitMap = AllocBitMap (width, height, depth, BMF_CLEAR, NULL); + if (rp->BitMap == NULL) + { + FreeRastPort (rp, width, height); + return NULL; + } + } + else + { + unsigned int i; + + rp->BitMap = XpmMalloc (sizeof (*rp->BitMap)); + if (rp->BitMap == NULL) + { + FreeRastPort (rp, width, height); + return NULL; + } + + InitBitMap (rp->BitMap, depth, width, height); + for (i = 0; i < depth; ++i) + rp->BitMap->Planes[i] = NULL; + for (i = 0; i < depth; ++i) + { + rp->BitMap->Planes[i] = (PLANEPTR)AllocRaster (width, height); + if (rp->BitMap->Planes[i] == NULL) + { + FreeRastPort (rp, width, height); + return NULL; + } + } + } + } + + return rp; +} + + +static void +FreeRastPort ( + struct RastPort *rp, + unsigned int width, + unsigned int height) +{ + if (rp != NULL) + { + if (rp->BitMap != NULL) + { + WaitBlit (); + if (GfxBase->LibNode.lib_Version >= 39) + FreeBitMap (rp->BitMap); + else + { + unsigned int i; + + for (i = 0; i < rp->BitMap->Depth; ++i) + { + if (rp->BitMap->Planes[i] != NULL) + FreeRaster (rp->BitMap->Planes[i], width, height); + } + XpmFree (rp->BitMap); + } + } + XpmFree (rp); + } +} + + +XImage * +AllocXImage ( + unsigned int width, + unsigned int height, + unsigned int depth) +{ + XImage *img; + + img = XpmMalloc (sizeof (*img)); + if (img != NULL) + { + img->width = width; + img->height = height; + img->rp = AllocRastPort (img->width, img->height, depth); + if (img->rp == NULL) + { + FreeXImage (img); + return NULL; + } + } + + return img; +} + + +int +FreeXImage ( + XImage *ximage) +{ + if (ximage != NULL) + { + FreeRastPort (ximage->rp, ximage->width, ximage->height); + XpmFree (ximage); + } + + return Success; +} + + +int +XPutPixel ( + XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + SetAPen (ximage->rp, pixel); + WritePixel (ximage->rp, x, y); + + return Success; +} + + +Status +AllocBestPen ( + Colormap colormap, + XColor *screen_in_out, + unsigned long precision, + Bool fail_if_bad) +{ + if (GfxBase->LibNode.lib_Version >= 39) + { + unsigned long r, g, b; + + r = screen_in_out->red * 0x00010001; + g = screen_in_out->green * 0x00010001; + b = screen_in_out->blue * 0x00010001; + screen_in_out->pixel = ObtainBestPen (colormap, r, g, b, + OBP_Precision, precision, + OBP_FailIfBad, fail_if_bad, + TAG_DONE); + if (screen_in_out->pixel == -1) + return False; + + QueryColor (colormap, screen_in_out); + } + else + { + XColor nearest, trial; + long nearest_delta, trial_delta; + int num_cells, i; + + num_cells = colormap->Count; + nearest.pixel = 0; + QueryColor (colormap, &nearest); + nearest_delta = ((((screen_in_out->red >> 8) - (nearest.red >> 8)) + * ((screen_in_out->red >> 8) - (nearest.red >> 8))) + + + (((screen_in_out->green >> 8) - (nearest.green >> 8)) + * ((screen_in_out->green >> 8) - (nearest.green >> 8))) + + + (((screen_in_out->blue >> 8) - (nearest.blue >> 8)) + * ((screen_in_out->blue >> 8) - (nearest.blue >> 8)))); + for (i = 1; i < num_cells; i++) + { + /* precision and fail_if_bad is ignored under pre V39 */ + trial.pixel = i; + QueryColor (colormap, &trial); + trial_delta = ((((screen_in_out->red >> 8) - (trial.red >> 8)) + * ((screen_in_out->red >> 8) - (trial.red >> 8))) + + + (((screen_in_out->green >> 8) - (trial.green >> 8)) + * ((screen_in_out->green >> 8) - (trial.green >> 8))) + + + (((screen_in_out->blue >> 8) - (trial.blue >> 8)) + * ((screen_in_out->blue >> 8) - (trial.blue >> 8)))); + if (trial_delta < nearest_delta) + { + nearest = trial; + nearest_delta = trial_delta; + } + } + screen_in_out->pixel = nearest.pixel; + screen_in_out->red = nearest.red; + screen_in_out->green = nearest.green; + screen_in_out->blue = nearest.blue; + } + + return True; +} + + +int +FreePens ( + Colormap colormap, + unsigned long *pixels, + int npixels) +{ + if (GfxBase->LibNode.lib_Version >= 39) + { + int i; + + for (i = 0; i < npixels; i++) + ReleasePen (colormap, pixels[i]); + } + + return Success; +} + + +Status +ParseColor ( + char *spec, + XColor *exact_def_return) +{ + int spec_length; + + if (spec == 0) + return False; + + spec_length = strlen(spec); + if (spec[0] == '#') + { + int hexlen; + char hexstr[10]; + + hexlen = (spec_length - 1) / 3; + if (hexlen < 1 || hexlen > 4 || hexlen * 3 != spec_length - 1) + return False; + + hexstr[hexlen] = '\0'; + strncpy (hexstr, spec + 1, hexlen); + exact_def_return->red = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); + strncpy (hexstr, spec + 1 + hexlen, hexlen); + exact_def_return->green = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); + strncpy (hexstr, spec + 1 + 2 * hexlen, hexlen); + exact_def_return->blue = strtoul (hexstr, NULL, 16) << (16 - 4*hexlen); + + return True; + } + else + { + FILE *rgbf; + int items, red, green, blue; + char line[512], name[512]; + Bool success = False; + + rgbf = fopen ("LIBS:rgb.txt", "r"); + if (rgbf == NULL) + return False; + + while (fgets(line, sizeof (line), rgbf) && !success) + { + items = sscanf (line, "%d %d %d %[^\n]\n", + &red, &green, &blue, name); + if (items != 4) + continue; + + if (red < 0 || red > 0xFF + || green < 0 || green > 0xFF + || blue < 0 || blue > 0xFF) + { + continue; + } + + if (0 == xpmstrcasecmp (spec, name)) + { + exact_def_return->red = red * 0x0101; + exact_def_return->green = green * 0x0101; + exact_def_return->blue = blue * 0x0101; + success = True; + } + } + fclose (rgbf); + + return success; + } +} + + +int +QueryColor ( + Colormap colormap, + XColor *def_in_out) +{ + if (GfxBase->LibNode.lib_Version >= 39) + { + unsigned long rgb[3]; + + GetRGB32 (colormap, def_in_out->pixel, 1, rgb); + def_in_out->red = rgb[0] >> 16; + def_in_out->green = rgb[1] >> 16; + def_in_out->blue = rgb[2] >> 16; + } + else + { + unsigned short rgb; + + rgb = GetRGB4 (colormap, def_in_out->pixel); + def_in_out->red = ((rgb >> 8) & 0xF) * 0x1111; + def_in_out->green = ((rgb >> 4) & 0xF) * 0x1111; + def_in_out->blue = (rgb & 0xF) * 0x1111; + } + + return Success; +} + + +int +QueryColors ( + Colormap colormap, + XColor *defs_in_out, + int ncolors) +{ + int i; + + for (i = 0; i < ncolors; i++) + QueryColor (colormap, &defs_in_out[i]); + + return Success; +} diff --git a/src/amigax.h b/src/amigax.h new file mode 100644 index 0000000..213ed76 --- /dev/null +++ b/src/amigax.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 1996 Lorens Younes + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * Lorens Younes BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of Lorens Younes shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from Lorens Younes. + */ + +/*****************************************************************************\ +* amigax.h: * +* * +* XPM library * +* Emulates some Xlib functionality for Amiga. * +* * +* Developed by Lorens Younes (d93-hyo@nada.kth.se) 7/95 * +* Revised 4/96 * +\*****************************************************************************/ + +#ifndef AMIGA_X +#define AMIGA_X + + +#include + +#include +#include + + +#define Success 0 + +/* really never used */ +#define ZPixmap 2 + +#define Bool int +#define Status int +#define True 1 +#define False 0 + +typedef struct ColorMap *Colormap; + +typedef void *Visual; + +typedef struct { + int width, height; + struct RastPort *rp; +} XImage; + +typedef struct { + unsigned long pixel; + unsigned short red, green, blue; +} XColor; + +typedef struct Screen Display; + + +#define XGrabServer(dpy) (Forbid ()) +#define XUngrabServer(dpy) (Permit ()) + +#define XDefaultScreen(dpy) (0) +#define XDefaultVisual(dpy, scr) (NULL) +#define XDefaultColormap(dpy, scr) (dpy->ViewPort.ColorMap) +#define XDefaultDepth(dpy, scr) (dpy->RastPort.BitMap->Depth) + +#define XCreateImage(dpy, vi, depth, format, offset, data, width, height, pad, bpl) \ + (AllocXImage (width, height, depth)) +#define XDestroyImage(img) (FreeXImage (img)) + +#define XAllocColor(dpy, cm, xc) \ + (AllocBestPen (cm, xc, PRECISION_EXACT, True)) +#define XFreeColors(dpy, cm, pixels, npixels, planes) \ + (FreePens (cm, pixels, npixels)) +#define XParseColor(dpy, cm, spec, exact_def_return) \ + (ParseColor (spec, exact_def_return)) +#define XQueryColor(dpy, cm, def_in_out) \ + (QueryColor(cm, def_in_out)) +#define XQueryColors(dpy, cm, defs_in_out, ncolors) \ + (QueryColors(cm, defs_in_out, ncolors)) + + +XImage * +AllocXImage ( + unsigned int width, + unsigned int height, + unsigned int depth); + + +int +FreeXImage ( + XImage *ximage); + + +int +XPutPixel ( + XImage *ximage, + int x, + int y, + unsigned long pixel); + + +Status +AllocBestPen ( + Colormap colormap, + XColor *screen_in_out, + unsigned long precision, + Bool fail_if_bad); + + +int +FreePens ( + Colormap colormap, + unsigned long *pixels, + int npixels); + + +Status +ParseColor ( + char *spec, + XColor *exact_def_return); + + +int +QueryColor ( + Colormap colormap, + XColor *def_in_out); + + +int +QueryColors ( + Colormap colormap, + XColor *defs_in_out, + int ncolors); + + +#endif /* AMIGA_X */ diff --git a/src/create.c b/src/create.c new file mode 100644 index 0000000..98678d8 --- /dev/null +++ b/src/create.c @@ -0,0 +1,2517 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* create.c: * +* * +* XPM library * +* Create an X image and possibly its related shape mask * +* from the given XpmImage. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#include + +LFUNC(xpmVisualType, int, (Visual *visual)); + +LFUNC(AllocColor, int, (Display *display, Colormap colormap, + char *colorname, XColor *xcolor, void *closure)); +LFUNC(FreeColors, int, (Display *display, Colormap colormap, + Pixel *pixels, int n, void *closure)); + +#ifndef FOR_MSW +LFUNC(SetCloseColor, int, (Display *display, Colormap colormap, + Visual *visual, XColor *col, + Pixel *image_pixel, Pixel *mask_pixel, + Pixel *alloc_pixels, unsigned int *nalloc_pixels, + XpmAttributes *attributes, XColor *cols, int ncols, + XpmAllocColorFunc allocColor, void *closure)); +#else +/* let the window system take care of close colors */ +#endif + +LFUNC(SetColor, int, (Display *display, Colormap colormap, Visual *visual, + char *colorname, unsigned int color_index, + Pixel *image_pixel, Pixel *mask_pixel, + unsigned int *mask_pixel_index, + Pixel *alloc_pixels, unsigned int *nalloc_pixels, + Pixel *used_pixels, unsigned int *nused_pixels, + XpmAttributes *attributes, XColor *cols, int ncols, + XpmAllocColorFunc allocColor, void *closure)); + +LFUNC(CreateXImage, int, (Display *display, Visual *visual, + unsigned int depth, int format, unsigned int width, + unsigned int height, XImage **image_return)); + +LFUNC(CreateColors, int, (Display *display, XpmAttributes *attributes, + XpmColor *colors, unsigned int ncolors, + Pixel *image_pixels, Pixel *mask_pixels, + unsigned int *mask_pixel_index, + Pixel *alloc_pixels, unsigned int *nalloc_pixels, + Pixel *used_pixels, unsigned int *nused_pixels)); + +#ifndef FOR_MSW +LFUNC(ParseAndPutPixels, int, (xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, + XImage *image, Pixel *image_pixels, + XImage *mask, Pixel *mask_pixels)); +#else /* FOR_MSW */ +LFUNC(ParseAndPutPixels, int, (Display *dc, xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, + XImage *image, Pixel *image_pixels, + XImage *mask, Pixel *mask_pixels)); +#endif + +#ifndef FOR_MSW +# ifndef AMIGA +/* XImage pixel routines */ +LFUNC(PutImagePixels, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels32, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels16, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels8, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutImagePixels1, void, (XImage *image, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); + +LFUNC(PutPixel1, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel, int, (XImage *ximage, int x, int y, unsigned long pixel)); +#if !defined(WORD64) && !defined(LONG64) +LFUNC(PutPixel32, int, (XImage *ximage, int x, int y, unsigned long pixel)); +#endif +LFUNC(PutPixel32MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel32LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel16MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel16LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel8, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel1MSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); +LFUNC(PutPixel1LSB, int, (XImage *ximage, int x, int y, unsigned long pixel)); + +# else /* AMIGA */ +LFUNC(APutImagePixels, void, (XImage *ximage, unsigned int width, + unsigned int height, unsigned int *pixelindex, + Pixel *pixels)); +# endif/* AMIGA */ +#else /* FOR_MSW */ +/* FOR_MSW pixel routine */ +LFUNC(MSWPutImagePixels, void, (Display *dc, XImage *image, + unsigned int width, unsigned int height, + unsigned int *pixelindex, Pixel *pixels)); +#endif /* FOR_MSW */ + +#ifdef NEED_STRCASECMP +FUNC(xpmstrcasecmp, int, (char *s1, char *s2)); + +/* + * in case strcasecmp is not provided by the system here is one + * which does the trick + */ +int +xpmstrcasecmp( + register char *s1, + register char *s2) +{ + register int c1, c2; + + while (*s1 && *s2) { + c1 = tolower(*s1); + c2 = tolower(*s2); + if (c1 != c2) + return (c1 - c2); + s1++; + s2++; + } + return (int) (*s1 - *s2); +} + +#endif + +/* + * return the default color key related to the given visual + */ +static int +xpmVisualType(Visual *visual) +{ +#ifndef FOR_MSW +# ifndef AMIGA + switch (visual->class) { + case StaticGray: + case GrayScale: + switch (visual->map_entries) { + case 2: + return (XPM_MONO); + case 4: + return (XPM_GRAY4); + default: + return (XPM_GRAY); + } + default: + return (XPM_COLOR); + } +# else + /* set the key explicitly in the XpmAttributes to override this */ + return (XPM_COLOR); +# endif +#else + /* there should be a similar switch for MSW */ + return (XPM_COLOR); +#endif +} + + +typedef struct { + int cols_index; + long closeness; +} CloseColor; + +static int +closeness_cmp(const void *a, const void *b) +{ + const CloseColor *x = (const CloseColor *) a, *y = (const CloseColor *) b; + + /* cast to int as qsort requires */ + return (int) (x->closeness - y->closeness); +} + + +/* default AllocColor function: + * call XParseColor if colorname is given, return negative value if failure + * call XAllocColor and return 0 if failure, positive otherwise + */ +static int +AllocColor( + Display *display, + Colormap colormap, + char *colorname, + XColor *xcolor, + void *closure) /* not used */ +{ + int status; + if (colorname) + if (!XParseColor(display, colormap, colorname, xcolor)) + return -1; + status = XAllocColor(display, colormap, xcolor); + return status != 0 ? 1 : 0; +} + + +#ifndef FOR_MSW +/* + * set a close color in case the exact one can't be set + * return 0 if success, 1 otherwise. + */ + +static int +SetCloseColor( + Display *display, + Colormap colormap, + Visual *visual, + XColor *col, + Pixel *image_pixel, + Pixel *mask_pixel, + Pixel *alloc_pixels, + unsigned int *nalloc_pixels, + XpmAttributes *attributes, + XColor *cols, + int ncols, + XpmAllocColorFunc allocColor, + void *closure) +{ + + /* + * Allocation failed, so try close colors. To get here the visual must + * be GreyScale, PseudoColor or DirectColor (or perhaps StaticColor? + * What about sharing systems like QDSS?). Beware: we have to treat + * DirectColor differently. + */ + + + long int red_closeness, green_closeness, blue_closeness; + int n; + Bool alloc_color; + + if (attributes && (attributes->valuemask & XpmCloseness)) + red_closeness = green_closeness = blue_closeness = + attributes->closeness; + else { + red_closeness = attributes->red_closeness; + green_closeness = attributes->green_closeness; + blue_closeness = attributes->blue_closeness; + } + if (attributes && (attributes->valuemask & XpmAllocCloseColors)) + alloc_color = attributes->alloc_close_colors; + else + alloc_color = True; + + /* + * We sort the colormap by closeness and try to allocate the color + * closest to the target. If the allocation of this close color fails, + * which almost never happens, then one of two scenarios is possible. + * Either the colormap must have changed (since the last close color + * allocation or possibly while we were sorting the colormap), or the + * color is allocated as Read/Write by some other client. (Note: X + * _should_ allow clients to check if a particular color is Read/Write, + * but it doesn't! :-( ). We cannot determine which of these scenarios + * occurred, so we try the next closest color, and so on, until no more + * colors are within closeness of the target. If we knew that the + * colormap had changed, we could skip this sequence. + * + * If _none_ of the colors within closeness of the target can be allocated, + * then we can finally be pretty sure that the colormap has actually + * changed. In this case we try to allocate the original color (again), + * then try the closecolor stuff (again)... + * + * In theory it would be possible for an infinite loop to occur if another + * process kept changing the colormap every time we sorted it, so we set + * a maximum on the number of iterations. After this many tries, we use + * XGrabServer() to ensure that the colormap remains unchanged. + * + * This approach gives particularly bad worst case performance - as many as + * colormap reads and sorts may be needed, and as + * many as * attempted allocations + * may fail. On an 8-bit system, this means as many as 3 colormap reads, + * 3 sorts and 768 failed allocations per execution of this code! + * Luckily, my experiments show that in general use in a typical 8-bit + * color environment only about 1 in every 10000 allocations fails to + * succeed in the fastest possible time. So virtually every time what + * actually happens is a single sort followed by a successful allocate. + * The very first allocation also costs a colormap read, but no further + * reads are usually necessary. + */ + +#define ITERATIONS 2 /* more than one is almost never + * necessary */ + + for (n = 0; n <= ITERATIONS; ++n) { + CloseColor *closenesses = + (CloseColor *) XpmCalloc(ncols, sizeof(CloseColor)); + int i, c; + + for (i = 0; i < ncols; ++i) { /* build & sort closenesses table */ +#define COLOR_FACTOR 3 +#define BRIGHTNESS_FACTOR 1 + + closenesses[i].cols_index = i; + closenesses[i].closeness = + COLOR_FACTOR * (abs((long) col->red - (long) cols[i].red) + + abs((long) col->green - (long) cols[i].green) + + abs((long) col->blue - (long) cols[i].blue)) + + BRIGHTNESS_FACTOR * abs(((long) col->red + + (long) col->green + + (long) col->blue) + - ((long) cols[i].red + + (long) cols[i].green + + (long) cols[i].blue)); + } + qsort(closenesses, ncols, sizeof(CloseColor), closeness_cmp); + + i = 0; + c = closenesses[i].cols_index; + while ((long) cols[c].red >= (long) col->red - red_closeness && + (long) cols[c].red <= (long) col->red + red_closeness && + (long) cols[c].green >= (long) col->green - green_closeness && + (long) cols[c].green <= (long) col->green + green_closeness && + (long) cols[c].blue >= (long) col->blue - blue_closeness && + (long) cols[c].blue <= (long) col->blue + blue_closeness) { + if (alloc_color) { + if ((*allocColor)(display, colormap, NULL, &cols[c], closure)){ + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + *image_pixel = cols[c].pixel; + *mask_pixel = 1; + alloc_pixels[(*nalloc_pixels)++] = cols[c].pixel; + return (0); + } else { + ++i; + if (i == ncols) + break; + c = closenesses[i].cols_index; + } + } else { + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + *image_pixel = cols[c].pixel; + *mask_pixel = 1; + return (0); + } + } + + /* Couldn't allocate _any_ of the close colors! */ + + if (n == ITERATIONS) + XUngrabServer(display); + XpmFree(closenesses); + + if (i == 0 || i == ncols) /* no color close enough or cannot */ + return (1); /* alloc any color (full of r/w's) */ + + if ((*allocColor)(display, colormap, NULL, col, closure)) { + *image_pixel = col->pixel; + *mask_pixel = 1; + alloc_pixels[(*nalloc_pixels)++] = col->pixel; + return (0); + } else { /* colormap has probably changed, so + * re-read... */ + if (n == ITERATIONS - 1) + XGrabServer(display); + +#if 0 + if (visual->class == DirectColor) { + /* TODO */ + } else +#endif + XQueryColors(display, colormap, cols, ncols); + } + } + return (1); +} + +#define USE_CLOSECOLOR attributes && \ +(((attributes->valuemask & XpmCloseness) && attributes->closeness != 0) \ + || ((attributes->valuemask & XpmRGBCloseness) && \ + (attributes->red_closeness != 0 \ + || attributes->green_closeness != 0 \ + || attributes->blue_closeness != 0))) + +#else + /* FOR_MSW part */ + /* nothing to do here, the window system does it */ +#endif + +/* + * set the color pixel related to the given colorname, + * return 0 if success, 1 otherwise. + */ + +static int +SetColor( + Display *display, + Colormap colormap, + Visual *visual, + char *colorname, + unsigned int color_index, + Pixel *image_pixel, + Pixel *mask_pixel, + unsigned int *mask_pixel_index, + Pixel *alloc_pixels, + unsigned int *nalloc_pixels, + Pixel *used_pixels, + unsigned int *nused_pixels, + XpmAttributes *attributes, + XColor *cols, + int ncols, + XpmAllocColorFunc allocColor, + void *closure) +{ + XColor xcolor; + int status; + + if (xpmstrcasecmp(colorname, TRANSPARENT_COLOR)) { + status = (*allocColor)(display, colormap, colorname, &xcolor, closure); + if (status < 0) /* parse color failed */ + return (1); + + if (status == 0) { +#ifndef FOR_MSW + if (USE_CLOSECOLOR) + return (SetCloseColor(display, colormap, visual, &xcolor, + image_pixel, mask_pixel, + alloc_pixels, nalloc_pixels, + attributes, cols, ncols, + allocColor, closure)); + else +#endif /* ndef FOR_MSW */ + return (1); + } else + alloc_pixels[(*nalloc_pixels)++] = xcolor.pixel; + *image_pixel = xcolor.pixel; +#ifndef FOR_MSW + *mask_pixel = 1; +#else + *mask_pixel = RGB(0,0,0); +#endif + used_pixels[(*nused_pixels)++] = xcolor.pixel; + } else { + *image_pixel = 0; +#ifndef FOR_MSW + *mask_pixel = 0; +#else + *mask_pixel = RGB(255,255,255); +#endif + /* store the color table index */ + *mask_pixel_index = color_index; + } + return (0); +} + + +static int +CreateColors( + Display *display, + XpmAttributes *attributes, + XpmColor *colors, + unsigned int ncolors, + Pixel *image_pixels, + Pixel *mask_pixels, + unsigned int *mask_pixel_index, + Pixel *alloc_pixels, + unsigned int *nalloc_pixels, + Pixel *used_pixels, + unsigned int *nused_pixels) +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + XpmColorSymbol *colorsymbols = NULL; + unsigned int numsymbols; + XpmAllocColorFunc allocColor; + void *closure; + + char *colorname; + unsigned int color, key; + Bool pixel_defined; + XpmColorSymbol *symbol = NULL; + char **defaults; + int ErrorStatus = XpmSuccess; + char *s; + int default_index; + + XColor *cols = NULL; + unsigned int ncols = 0; + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && attributes->valuemask & XpmColorSymbols) { + colorsymbols = attributes->colorsymbols; + numsymbols = attributes->numsymbols; + } else + numsymbols = 0; + + if (attributes && attributes->valuemask & XpmVisual) + visual = attributes->visual; + else + visual = XDefaultVisual(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmColormap)) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmColorKey)) + key = attributes->color_key; + else + key = xpmVisualType(visual); + + if (attributes && (attributes->valuemask & XpmAllocColor)) + allocColor = attributes->alloc_color; + else + allocColor = AllocColor; + if (attributes && (attributes->valuemask & XpmColorClosure)) + closure = attributes->color_closure; + else + closure = NULL; + +#ifndef FOR_MSW + if (USE_CLOSECOLOR) { + /* originally from SetCloseColor */ +#if 0 + if (visual->class == DirectColor) { + + /* + * TODO: Implement close colors for DirectColor visuals. This is + * difficult situation. Chances are that we will never get here, + * because any machine that supports DirectColor will probably + * also support TrueColor (and probably PseudoColor). Also, + * DirectColor colormaps can be very large, so looking for close + * colors may be too slow. + */ + } else { +#endif + unsigned int i; + +#ifndef AMIGA + ncols = visual->map_entries; +#else + ncols = colormap->Count; +#endif + cols = (XColor *) XpmCalloc(ncols, sizeof(XColor)); + for (i = 0; i < ncols; ++i) + cols[i].pixel = i; + XQueryColors(display, colormap, cols, ncols); +#if 0 + } +#endif + } +#endif /* ndef FOR_MSW */ + + switch (key) { + case XPM_MONO: + default_index = 2; + break; + case XPM_GRAY4: + default_index = 3; + break; + case XPM_GRAY: + default_index = 4; + break; + case XPM_COLOR: + default: + default_index = 5; + break; + } + + for (color = 0; color < ncolors; color++, colors++, + image_pixels++, mask_pixels++) { + colorname = NULL; + pixel_defined = False; + defaults = (char **) colors; + + /* + * look for a defined symbol + */ + if (numsymbols) { + + unsigned int n; + + s = defaults[1]; + for (n = 0, symbol = colorsymbols; n < numsymbols; n++, symbol++) { + if (symbol->name && s && !strcmp(symbol->name, s)) + /* override name */ + break; + if (!symbol->name && symbol->value) { /* override value */ + int def_index = default_index; + + while (defaults[def_index] == NULL) /* find defined + * colorname */ + --def_index; + if (def_index < 2) {/* nothing towards mono, so try + * towards color */ + def_index = default_index + 1; + while (def_index <= 5 && defaults[def_index] == NULL) + ++def_index; + } + if (def_index >= 2 && defaults[def_index] != NULL && + !xpmstrcasecmp(symbol->value, defaults[def_index])) + break; + } + } + if (n != numsymbols) { + if (symbol->name && symbol->value) + colorname = symbol->value; + else + pixel_defined = True; + } + } + if (!pixel_defined) { /* pixel not given as symbol value */ + + unsigned int k; + + if (colorname) { /* colorname given as symbol value */ + if (!SetColor(display, colormap, visual, colorname, color, + image_pixels, mask_pixels, mask_pixel_index, + alloc_pixels, nalloc_pixels, used_pixels, + nused_pixels, attributes, cols, ncols, + allocColor, closure)) + pixel_defined = True; + else + ErrorStatus = XpmColorError; + } + k = key; + while (!pixel_defined && k > 1) { + if (defaults[k]) { + if (!SetColor(display, colormap, visual, defaults[k], + color, image_pixels, mask_pixels, + mask_pixel_index, alloc_pixels, + nalloc_pixels, used_pixels, nused_pixels, + attributes, cols, ncols, + allocColor, closure)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + k--; + } + k = key + 1; + while (!pixel_defined && k < NKEYS + 1) { + if (defaults[k]) { + if (!SetColor(display, colormap, visual, defaults[k], + color, image_pixels, mask_pixels, + mask_pixel_index, alloc_pixels, + nalloc_pixels, used_pixels, nused_pixels, + attributes, cols, ncols, + allocColor, closure)) { + pixel_defined = True; + break; + } else + ErrorStatus = XpmColorError; + } + k++; + } + if (!pixel_defined) { + if (cols) + XpmFree(cols); + return (XpmColorFailed); + } + } else { + /* simply use the given pixel */ + *image_pixels = symbol->pixel; + /* the following makes the mask to be built even if none + is given a particular pixel */ + if (symbol->value + && !xpmstrcasecmp(symbol->value, TRANSPARENT_COLOR)) { + *mask_pixels = 0; + *mask_pixel_index = color; + } else + *mask_pixels = 1; + used_pixels[(*nused_pixels)++] = *image_pixels; + } + } + if (cols) + XpmFree(cols); + return (ErrorStatus); +} + + +/* default FreeColors function, simply call XFreeColors */ +static int +FreeColors( + Display *display, + Colormap colormap, + Pixel *pixels, + int n, + void *closure) /* not used */ +{ + return XFreeColors(display, colormap, pixels, n, 0); +} + + +/* function call in case of error */ + +#undef RETURN +#define RETURN(status) \ +do \ +{ \ + ErrorStatus = status; \ + goto error; \ +} while(0) + +int +XpmCreateImageFromXpmImage( + Display *display, + XpmImage *image, + XImage **image_return, + XImage **shapeimage_return, + XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + unsigned int depth; + int bitmap_format; + XpmFreeColorsFunc freeColors; + + /* variables to return */ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int mask_pixel_index = XpmUndefPixel; + int ErrorStatus; + + /* calculation variables */ + Pixel *image_pixels = NULL; + Pixel *mask_pixels = NULL; + Pixel *alloc_pixels = NULL; + Pixel *used_pixels = NULL; + unsigned int nalloc_pixels = 0; + unsigned int nused_pixels = 0; + + /* initialize return values */ + if (image_return) + *image_return = NULL; + if (shapeimage_return) + *shapeimage_return = NULL; + + /* retrieve information from the XpmAttributes */ + if (attributes && (attributes->valuemask & XpmVisual)) + visual = attributes->visual; + else + visual = XDefaultVisual(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmColormap)) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmDepth)) + depth = attributes->depth; + else + depth = XDefaultDepth(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmBitmapFormat)) + bitmap_format = attributes->bitmap_format; + else + bitmap_format = ZPixmap; + + if (attributes && (attributes->valuemask & XpmFreeColors)) + freeColors = attributes->free_colors; + else + freeColors = FreeColors; + + ErrorStatus = XpmSuccess; + + if (image->ncolors >= UINT_MAX / sizeof(Pixel)) + return (XpmNoMemory); + + /* malloc pixels index tables */ + image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!image_pixels) + return (XpmNoMemory); + + mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!mask_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!alloc_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * image->ncolors); + if (!used_pixels) + RETURN(XpmNoMemory); + + /* get pixel colors, store them in index tables */ + ErrorStatus = CreateColors(display, attributes, image->colorTable, + image->ncolors, image_pixels, mask_pixels, + &mask_pixel_index, alloc_pixels, &nalloc_pixels, + used_pixels, &nused_pixels); + + if (ErrorStatus != XpmSuccess + && (ErrorStatus < 0 || (attributes + && (attributes->valuemask & XpmExactColors) + && attributes->exactColors))) + RETURN(ErrorStatus); + + /* create the ximage */ + if (image_return) { + ErrorStatus = CreateXImage(display, visual, depth, + (depth == 1 ? bitmap_format : ZPixmap), + image->width, image->height, &ximage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#ifndef FOR_MSW +# ifndef AMIGA + + /* + * set the ximage data using optimized functions for ZPixmap + */ + + if (ximage->bits_per_pixel == 8) + PutImagePixels8(ximage, image->width, image->height, + image->data, image_pixels); + else if (((ximage->bits_per_pixel | ximage->depth) == 1) && + (ximage->byte_order == ximage->bitmap_bit_order)) + PutImagePixels1(ximage, image->width, image->height, + image->data, image_pixels); + else if (ximage->bits_per_pixel == 16) + PutImagePixels16(ximage, image->width, image->height, + image->data, image_pixels); + else if (ximage->bits_per_pixel == 32) + PutImagePixels32(ximage, image->width, image->height, + image->data, image_pixels); + else + PutImagePixels(ximage, image->width, image->height, + image->data, image_pixels); +# else /* AMIGA */ + APutImagePixels(ximage, image->width, image->height, + image->data, image_pixels); +# endif +#else /* FOR_MSW */ + MSWPutImagePixels(display, ximage, image->width, image->height, + image->data, image_pixels); +#endif + } + /* create the shape mask image */ + if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { + ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, + image->width, image->height, &shapeimage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#ifndef FOR_MSW +# ifndef AMIGA + PutImagePixels1(shapeimage, image->width, image->height, + image->data, mask_pixels); +# else /* AMIGA */ + APutImagePixels(shapeimage, image->width, image->height, + image->data, mask_pixels); +# endif +#else /* FOR_MSW */ + MSWPutImagePixels(display, shapeimage, image->width, image->height, + image->data, mask_pixels); +#endif + + } + XpmFree(image_pixels); + XpmFree(mask_pixels); + + /* if requested return used pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnPixels || +/* 3.2 backward compatibility code */ + attributes->valuemask & XpmReturnInfos)) { +/* end 3.2 bc */ + attributes->pixels = used_pixels; + attributes->npixels = nused_pixels; + attributes->mask_pixel = mask_pixel_index; + } else + XpmFree(used_pixels); + + /* if requested return alloc'ed pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { + attributes->alloc_pixels = alloc_pixels; + attributes->nalloc_pixels = nalloc_pixels; + } else + XpmFree(alloc_pixels); + + /* return created images */ + if (image_return) + *image_return = ximage; + if (shapeimage_return) + *shapeimage_return = shapeimage; + + return (ErrorStatus); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + if (image_pixels) + XpmFree(image_pixels); + if (mask_pixels) + XpmFree(mask_pixels); + if (nalloc_pixels) + (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); + if (alloc_pixels) + XpmFree(alloc_pixels); + if (used_pixels) + XpmFree(used_pixels); + + return (ErrorStatus); +} + + +/* + * Create an XImage with its data + */ +static int +CreateXImage( + Display *display, + Visual *visual, + unsigned int depth, + int format, + unsigned int width, + unsigned int height, + XImage **image_return) +{ + int bitmap_pad; + + /* first get bitmap_pad */ + if (depth > 16) + bitmap_pad = 32; + else if (depth > 8) + bitmap_pad = 16; + else + bitmap_pad = 8; + + /* then create the XImage with data = NULL and bytes_per_line = 0 */ + *image_return = XCreateImage(display, visual, depth, format, 0, 0, + width, height, bitmap_pad, 0); + if (!*image_return) + return (XpmNoMemory); + +#if !defined(FOR_MSW) && !defined(AMIGA) + if (height != 0 && (*image_return)->bytes_per_line >= INT_MAX / height) { + XDestroyImage(*image_return); + return XpmNoMemory; + } + /* now that bytes_per_line must have been set properly alloc data */ + if((*image_return)->bytes_per_line == 0 || height == 0) + return XpmNoMemory; + (*image_return)->data = + (char *) XpmMalloc((*image_return)->bytes_per_line * height); + + if (!(*image_return)->data) { + XDestroyImage(*image_return); + *image_return = NULL; + return (XpmNoMemory); + } +#else + /* under FOR_MSW and AMIGA XCreateImage has done it all */ +#endif + return (XpmSuccess); +} + +#ifndef FOR_MSW +# ifndef AMIGA +/* + * The functions below are written from X11R5 MIT's code (XImUtil.c) + * + * The idea is to have faster functions than the standard XPutPixel function + * to build the image data. Indeed we can speed up things by suppressing tests + * performed for each pixel. We do the same tests but at the image level. + * We also assume that we use only ZPixmap images with null offsets. + */ + +LFUNC(_putbits, void, (register char *src, int dstoffset, + register int numbits, register char *dst)); + +LFUNC(_XReverse_Bytes, int, (register unsigned char *bpt, register unsigned int nb)); + +static unsigned char const _reverse_byte[0x100] = { + 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, + 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, + 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, + 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, + 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, + 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, + 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, + 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, + 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, + 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, + 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, + 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, + 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, + 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, + 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, + 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, + 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, + 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, + 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, + 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, + 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, + 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, + 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, + 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, + 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, + 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, + 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, + 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, + 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, + 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, + 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, + 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff +}; + +static int +_XReverse_Bytes( + register unsigned char *bpt, + register unsigned int nb) +{ + do { + *bpt = _reverse_byte[*bpt]; + bpt++; + } while (--nb > 0); /* is nb user-controled? */ + return 0; +} + + +void +xpm_xynormalizeimagebits( + register unsigned char *bp, + register XImage *img) +{ + register unsigned char c; + + if (img->byte_order != img->bitmap_bit_order) { + switch (img->bitmap_unit) { + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } + } + if (img->bitmap_bit_order == MSBFirst) + _XReverse_Bytes(bp, img->bitmap_unit >> 3); +} + +void +xpm_znormalizeimagebits( + register unsigned char *bp, + register XImage *img) +{ + register unsigned char c; + + switch (img->bits_per_pixel) { + + case 2: + _XReverse_Bytes(bp, 1); + break; + + case 4: + *bp = ((*bp >> 4) & 0xF) | ((*bp << 4) & ~0xF); + break; + + case 16: + c = *bp; + *bp = *(bp + 1); + *(bp + 1) = c; + break; + + case 24: + c = *(bp + 2); + *(bp + 2) = *bp; + *bp = c; + break; + + case 32: + c = *(bp + 3); + *(bp + 3) = *bp; + *bp = c; + c = *(bp + 2); + *(bp + 2) = *(bp + 1); + *(bp + 1) = c; + break; + } +} + +static unsigned char const _lomask[0x09] = { +0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff}; +static unsigned char const _himask[0x09] = { +0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00}; + +static void +_putbits( + register char *src, /* address of source bit string */ + int dstoffset, /* bit offset into destination; + * range is 0-31 */ + register int numbits, /* number of bits to copy to + * destination */ + register char *dst) /* address of destination bit string */ +{ + register unsigned char chlo, chhi; + int hibits; + + dst = dst + (dstoffset >> 3); + dstoffset = dstoffset & 7; + hibits = 8 - dstoffset; + chlo = *dst & _lomask[dstoffset]; + for (;;) { + chhi = (*src << dstoffset) & _himask[dstoffset]; + if (numbits <= hibits) { + chhi = chhi & _lomask[dstoffset + numbits]; + *dst = (*dst & _himask[dstoffset + numbits]) | chlo | chhi; + break; + } + *dst = chhi | chlo; + dst++; + numbits = numbits - hibits; + chlo = (unsigned char) (*src & _himask[hibits]) >> hibits; + src++; + if (numbits <= dstoffset) { + chlo = chlo & _lomask[numbits]; + *dst = (*dst & _himask[numbits]) | chlo; + break; + } + numbits = numbits - dstoffset; + } +} + +/* + * Default method to write pixels into a Z image data structure. + * The algorithm used is: + * + * copy the destination bitmap_unit or Zpixel to temp + * normalize temp if needed + * copy the pixel bits into the temp + * renormalize temp if needed + * copy the temp back into the destination image data + */ + +static void +PutImagePixels( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + register char *src; + register char *dst; + register unsigned int *iptr; + register unsigned int x, y; + register char *data; + Pixel pixel, px; + int nbytes, depth, ibu, ibpp, i; + + data = image->data; + iptr = pixelindex; + depth = image->depth; + if (depth == 1) { + ibu = image->bitmap_unit; + for (y = 0; y < height; y++) /* how can we trust height */ + for (x = 0; x < width; x++, iptr++) { /* how can we trust width */ + pixel = pixels[*iptr]; + for (i = 0, px = pixel; i < sizeof(unsigned long); + i++, px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &data[XYINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + nbytes = ibu >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + XYNORMALIZE(&px, image); + _putbits((char *) &pixel, (x % ibu), 1, (char *) &px); + XYNORMALIZE(&px, image); + src = (char *) &px; + dst = &data[XYINDEX(x, y, image)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + } + } else { + ibpp = image->bits_per_pixel; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = pixels[*iptr]; + if (depth == 4) + pixel &= 0xf; + for (i = 0, px = pixel; i < sizeof(unsigned long); i++, + px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &data[ZINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + nbytes = (ibpp + 7) >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, image); + _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); + ZNORMALIZE(&px, image); + src = (char *) &px; + dst = &data[ZINDEX(x, y, image)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + } + } +} + +/* + * write pixels into a 32-bits Z image data structure + */ + +#if !defined(WORD64) && !defined(LONG64) +/* this item is static but deterministic so let it slide; doesn't + * hurt re-entrancy of this library. Note if it is actually const then would + * be OK under rules of ANSI-C but probably not C++ which may not + * want to allocate space for it. + */ +static unsigned long byteorderpixel = MSBFirst << 24; + +#endif + +/* + WITHOUT_SPEEDUPS is a flag to be turned on if you wish to use the original + 3.2e code - by default you get the speeded-up version. +*/ + +static void +PutImagePixels32( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + unsigned char *data; + unsigned int *iptr; + unsigned int y; + Pixel pixel; + +#ifdef WITHOUT_SPEEDUPS + + unsigned int x; + unsigned char *addr; + + data = (unsigned char *) image->data; + iptr = pixelindex; +#if !defined(WORD64) && !defined(LONG64) + if (*((char *) &byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + *((unsigned long *) addr) = pixels[*iptr]; + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = pixels[*iptr]; + addr[0] = pixel >> 24; + addr[1] = pixel >> 16; + addr[2] = pixel >> 8; + addr[3] = pixel; + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = pixels[*iptr]; + addr[0] = pixel; + addr[1] = pixel >> 8; + addr[2] = pixel >> 16; + addr[3] = pixel >> 24; + } + +#else /* WITHOUT_SPEEDUPS */ + + unsigned int bpl = image->bytes_per_line; + unsigned char *data_ptr, *max_data; + + data = (unsigned char *) image->data; + iptr = pixelindex; +#if !defined(WORD64) && !defined(LONG64) + if (*((char *) &byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 2); + + while (data_ptr < max_data) { + *((unsigned long *) data_ptr) = pixels[*(iptr++)]; + data_ptr += (1 << 2); + } + data += bpl; + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 2); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + *data_ptr++ = pixel >> 24; + *data_ptr++ = pixel >> 16; + *data_ptr++ = pixel >> 8; + *data_ptr++ = pixel; + + } + data += bpl; + } + else + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 2); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + *data_ptr++ = pixel; + *data_ptr++ = pixel >> 8; + *data_ptr++ = pixel >> 16; + *data_ptr++ = pixel >> 24; + } + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ +} + +/* + * write pixels into a 16-bits Z image data structure + */ + +static void +PutImagePixels16( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + unsigned char *data; + unsigned int *iptr; + unsigned int y; + +#ifdef WITHOUT_SPEEDUPS + + unsigned int x; + unsigned char *addr; + + data = (unsigned char *) image->data; + iptr = pixelindex; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + addr[0] = pixels[*iptr] >> 8; + addr[1] = pixels[*iptr]; + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + addr[0] = pixels[*iptr]; + addr[1] = pixels[*iptr] >> 8; + } + +#else /* WITHOUT_SPEEDUPS */ + + Pixel pixel; + + unsigned int bpl = image->bytes_per_line; + unsigned char *data_ptr, *max_data; + + data = (unsigned char *) image->data; + iptr = pixelindex; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 1); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + data_ptr[0] = pixel >> 8; + data_ptr[1] = pixel; + + data_ptr += (1 << 1); + } + data += bpl; + } + else + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + (width << 1); + + while (data_ptr < max_data) { + pixel = pixels[*(iptr++)]; + + data_ptr[0] = pixel; + data_ptr[1] = pixel >> 8; + + data_ptr += (1 << 1); + } + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ +} + +/* + * write pixels into a 8-bits Z image data structure + */ + +static void +PutImagePixels8( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + char *data; + unsigned int *iptr; + unsigned int y; + +#ifdef WITHOUT_SPEEDUPS + + unsigned int x; + + data = image->data; + iptr = pixelindex; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) + data[ZINDEX8(x, y, image)] = pixels[*iptr]; + +#else /* WITHOUT_SPEEDUPS */ + + unsigned int bpl = image->bytes_per_line; + char *data_ptr, *max_data; + + data = image->data; + iptr = pixelindex; + + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + width; + + while (data_ptr < max_data) + *(data_ptr++) = pixels[*(iptr++)]; + + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ +} + +/* + * write pixels into a 1-bit depth image data structure and **offset null** + */ + +static void +PutImagePixels1( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + if (image->byte_order != image->bitmap_bit_order) + PutImagePixels(image, width, height, pixelindex, pixels); + else { + unsigned int *iptr; + unsigned int y; + char *data; + +#ifdef WITHOUT_SPEEDUPS + + unsigned int x; + + data = image->data; + iptr = pixelindex; + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + if (pixels[*iptr] & 1) + data[ZINDEX1(x, y, image)] |= 0x80 >> (x & 7); + else + data[ZINDEX1(x, y, image)] &= ~(0x80 >> (x & 7)); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + if (pixels[*iptr] & 1) + data[ZINDEX1(x, y, image)] |= 1 << (x & 7); + else + data[ZINDEX1(x, y, image)] &= ~(1 << (x & 7)); + } + +#else /* WITHOUT_SPEEDUPS */ + + char value; + char *data_ptr, *max_data; + int bpl = image->bytes_per_line; + int diff, count; + + data = image->data; + iptr = pixelindex; + + diff = width & 7; + width >>= 3; + + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + width; + while (data_ptr < max_data) { + value = 0; + + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + value = (value << 1) | (pixels[*(iptr++)] & 1); + + *(data_ptr++) = value; + } + if (diff) { + value = 0; + for (count = 0; count < diff; count++) { + if (pixels[*(iptr++)] & 1) + value |= (0x80 >> count); + } + *(data_ptr) = value; + } + data += bpl; + } + else + for (y = 0; y < height; y++) { + data_ptr = data; + max_data = data_ptr + width; + while (data_ptr < max_data) { + value = 0; + iptr += 8; + + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + value = (value << 1) | (pixels[*(--iptr)] & 1); + + iptr += 8; + *(data_ptr++) = value; + } + if (diff) { + value = 0; + for (count = 0; count < diff; count++) { + if (pixels[*(iptr++)] & 1) + value |= (1 << count); + } + *(data_ptr) = value; + } + data += bpl; + } + +#endif /* WITHOUT_SPEEDUPS */ + } +} + +int +XpmCreatePixmapFromXpmImage( + Display *display, + Drawable d, + XpmImage *image, + Pixmap *pixmap_return, + Pixmap *shapemask_return, + XpmAttributes *attributes) +{ + XImage *ximage, *shapeimage; + int ErrorStatus; + + /* initialize return values */ + if (pixmap_return) + *pixmap_return = 0; + if (shapemask_return) + *shapemask_return = 0; + + /* create the ximages */ + ErrorStatus = XpmCreateImageFromXpmImage(display, image, + (pixmap_return ? &ximage : NULL), + (shapemask_return ? + &shapeimage : NULL), + attributes); + if (ErrorStatus < 0) + return (ErrorStatus); + + /* create the pixmaps and destroy images */ + if (pixmap_return && ximage) { + xpmCreatePixmapFromImage(display, d, ximage, pixmap_return); + XDestroyImage(ximage); + } + if (shapemask_return && shapeimage) { + xpmCreatePixmapFromImage(display, d, shapeimage, shapemask_return); + XDestroyImage(shapeimage); + } + return (ErrorStatus); +} + +# else /* AMIGA */ + +static void +APutImagePixels ( + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + unsigned int *data = pixelindex; + unsigned int x, y; + unsigned char *array; + XImage *tmp_img; + BOOL success = FALSE; + + array = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*array)); + if (array != NULL) + { + tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, + image->rp->BitMap->Depth); + if (tmp_img != NULL) + { + for (y = 0; y < height; ++y) + { + for (x = 0; x < width; ++x) + array[x] = pixels[*(data++)]; + WritePixelLine8 (image->rp, 0, y, width, array, tmp_img->rp); + } + FreeXImage (tmp_img); + success = TRUE; + } + XpmFree (array); + } + + if (!success) + { + for (y = 0; y < height; ++y) + for (x = 0; x < width; ++x) + XPutPixel (image, x, y, pixels[*(data++)]); + } +} + +# endif/* AMIGA */ +#else /* FOR_MSW part follows */ +static void +MSWPutImagePixels( + Display *dc, + XImage *image, + unsigned int width, + unsigned int height, + unsigned int *pixelindex, + Pixel *pixels) +{ + unsigned int *data = pixelindex; + unsigned int x, y; + HBITMAP obm; + + obm = SelectObject(*dc, image->bitmap); + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + SetPixel(*dc, x, y, pixels[*(data++)]); /* data is [x+y*width] */ + } + } + SelectObject(*dc, obm); +} + +#endif /* FOR_MSW */ + + + +#if !defined(FOR_MSW) && !defined(AMIGA) + +static int +PutPixel1( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + register char *src; + register char *dst; + register int i; + Pixel px; + int nbytes; + + if(x < 0 || y < 0) + return 0; + + for (i=0, px=pixel; i>=8) + ((unsigned char *)&pixel)[i] = px; + src = &ximage->data[XYINDEX(x, y, ximage)]; + dst = (char *)&px; + px = 0; + nbytes = ximage->bitmap_unit >> 3; + for (i = nbytes; --i >= 0; ) *dst++ = *src++; + XYNORMALIZE(&px, ximage); + i = ((x + ximage->xoffset) % ximage->bitmap_unit); + _putbits ((char *)&pixel, i, 1, (char *)&px); + XYNORMALIZE(&px, ximage); + src = (char *) &px; + dst = &ximage->data[XYINDEX(x, y, ximage)]; + for (i = nbytes; --i >= 0; ) + *dst++ = *src++; + + return 1; +} + +static int +PutPixel( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + register char *src; + register char *dst; + register int i; + Pixel px; + unsigned int nbytes, ibpp; + + if(x < 0 || y < 0) + return 0; + + ibpp = ximage->bits_per_pixel; + if (ximage->depth == 4) + pixel &= 0xf; + for (i = 0, px = pixel; i < sizeof(unsigned long); i++, px >>= 8) + ((unsigned char *) &pixel)[i] = px; + src = &ximage->data[ZINDEX(x, y, ximage)]; + dst = (char *) &px; + px = 0; + nbytes = (ibpp + 7) >> 3; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, ximage); + _putbits((char *) &pixel, (x * ibpp) & 7, ibpp, (char *) &px); + ZNORMALIZE(&px, ximage); + src = (char *) &px; + dst = &ximage->data[ZINDEX(x, y, ximage)]; + for (i = nbytes; --i >= 0;) + *dst++ = *src++; + + return 1; +} + +#if !defined(WORD64) && !defined(LONG64) +static int +PutPixel32( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + unsigned char *addr; + + if(x < 0 || y < 0) + return 0; + + addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; + *((unsigned long *)addr) = pixel; + return 1; +} +#endif + +static int +PutPixel32MSB( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + unsigned char *addr; + + if(x < 0 || y < 0) + return 0; + + addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; + addr[0] = pixel >> 24; + addr[1] = pixel >> 16; + addr[2] = pixel >> 8; + addr[3] = pixel; + return 1; +} + +static int +PutPixel32LSB( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + unsigned char *addr; + + if(x < 0 || y < 0) + return 0; + + addr = &((unsigned char *)ximage->data) [ZINDEX32(x, y, ximage)]; + addr[3] = pixel >> 24; + addr[2] = pixel >> 16; + addr[1] = pixel >> 8; + addr[0] = pixel; + return 1; +} + +static int +PutPixel16MSB( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + unsigned char *addr; + + if(x < 0 || y < 0) + return 0; + + addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; + addr[0] = pixel >> 8; + addr[1] = pixel; + return 1; +} + +static int +PutPixel16LSB( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + unsigned char *addr; + + if(x < 0 || y < 0) + return 0; + + addr = &((unsigned char *)ximage->data) [ZINDEX16(x, y, ximage)]; + addr[1] = pixel >> 8; + addr[0] = pixel; + return 1; +} + +static int +PutPixel8( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + if(x < 0 || y < 0) + return 0; + + ximage->data[ZINDEX8(x, y, ximage)] = pixel; + return 1; +} + +static int +PutPixel1MSB( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + if(x < 0 || y < 0) + return 0; + + if (pixel & 1) + ximage->data[ZINDEX1(x, y, ximage)] |= 0x80 >> (x & 7); + else + ximage->data[ZINDEX1(x, y, ximage)] &= ~(0x80 >> (x & 7)); + return 1; +} + +static int +PutPixel1LSB( + register XImage *ximage, + int x, + int y, + unsigned long pixel) +{ + if(x < 0 || y < 0) + return 0; + + if (pixel & 1) + ximage->data[ZINDEX1(x, y, ximage)] |= 1 << (x & 7); + else + ximage->data[ZINDEX1(x, y, ximage)] &= ~(1 << (x & 7)); + return 1; +} + +#endif /* not FOR_MSW && not AMIGA */ + +/* + * This function parses an Xpm file or data and directly create an XImage + */ +int +xpmParseDataAndCreate( + Display *display, + xpmData *data, + XImage **image_return, + XImage **shapeimage_return, + XpmImage *image, + XpmInfo *info, + XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + Visual *visual; + Colormap colormap; + unsigned int depth; + int bitmap_format; + XpmFreeColorsFunc freeColors; + + /* variables to return */ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int mask_pixel_index = XpmUndefPixel; + + /* calculation variables */ + Pixel *image_pixels = NULL; + Pixel *mask_pixels = NULL; + Pixel *alloc_pixels = NULL; + Pixel *used_pixels = NULL; + unsigned int nalloc_pixels = 0; + unsigned int nused_pixels = 0; + unsigned int width, height, ncolors, cpp; + unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; + XpmColor *colorTable = NULL; + char *hints_cmt = NULL; + char *colors_cmt = NULL; + char *pixels_cmt = NULL; + + unsigned int cmts; + int ErrorStatus; + xpmHashTable hashtable; + + + /* initialize return values */ + if (image_return) + *image_return = NULL; + if (shapeimage_return) + *shapeimage_return = NULL; + + + /* retrieve information from the XpmAttributes */ + if (attributes && (attributes->valuemask & XpmVisual)) + visual = attributes->visual; + else + visual = XDefaultVisual(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmColormap)) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmDepth)) + depth = attributes->depth; + else + depth = XDefaultDepth(display, XDefaultScreen(display)); + + if (attributes && (attributes->valuemask & XpmBitmapFormat)) + bitmap_format = attributes->bitmap_format; + else + bitmap_format = ZPixmap; + + if (attributes && (attributes->valuemask & XpmFreeColors)) + freeColors = attributes->free_colors; + else + freeColors = FreeColors; + + cmts = info && (info->valuemask & XpmReturnComments); + + /* + * parse the header + */ + ErrorStatus = xpmParseHeader(data); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * read values + */ + ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp, + &x_hotspot, &y_hotspot, &hotspot, + &extensions); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * store the hints comment line + */ + if (cmts) + xpmGetCmt(data, &hints_cmt); + + /* + * init the hashtable + */ + if (USE_HASHTABLE) { + ErrorStatus = xpmHashTableInit(&hashtable); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * read colors + */ + ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the colors comment line + */ + if (cmts) + xpmGetCmt(data, &colors_cmt); + + /* malloc pixels index tables */ + if (ncolors >= UINT_MAX / sizeof(Pixel)) + RETURN(XpmNoMemory); + + image_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!image_pixels) + RETURN(XpmNoMemory); + + mask_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!mask_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + alloc_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!alloc_pixels) + RETURN(XpmNoMemory); + + /* maximum of allocated pixels will be the number of colors */ + used_pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * ncolors); + if (!used_pixels) + RETURN(XpmNoMemory); + + /* get pixel colors, store them in index tables */ + ErrorStatus = CreateColors(display, attributes, colorTable, ncolors, + image_pixels, mask_pixels, &mask_pixel_index, + alloc_pixels, &nalloc_pixels, used_pixels, + &nused_pixels); + + if (ErrorStatus != XpmSuccess + && (ErrorStatus < 0 || (attributes + && (attributes->valuemask & XpmExactColors) + && attributes->exactColors))) + RETURN(ErrorStatus); + + /* now create the ximage */ + if (image_return) { + ErrorStatus = CreateXImage(display, visual, depth, + (depth == 1 ? bitmap_format : ZPixmap), + width, height, &ximage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#if !defined(FOR_MSW) && !defined(AMIGA) + + /* + * set the XImage pointer function, to be used with XPutPixel, + * to an internal optimized function + */ + + if (ximage->bits_per_pixel == 8) + ximage->f.put_pixel = PutPixel8; + else if (((ximage->bits_per_pixel | ximage->depth) == 1) && + (ximage->byte_order == ximage->bitmap_bit_order)) + if (ximage->bitmap_bit_order == MSBFirst) + ximage->f.put_pixel = PutPixel1MSB; + else + ximage->f.put_pixel = PutPixel1LSB; + else if (ximage->bits_per_pixel == 16) + if (ximage->bitmap_bit_order == MSBFirst) + ximage->f.put_pixel = PutPixel16MSB; + else + ximage->f.put_pixel = PutPixel16LSB; + else if (ximage->bits_per_pixel == 32) +#if !defined(WORD64) && !defined(LONG64) + if (*((char *)&byteorderpixel) == ximage->byte_order) + ximage->f.put_pixel = PutPixel32; + else +#endif + if (ximage->bitmap_bit_order == MSBFirst) + ximage->f.put_pixel = PutPixel32MSB; + else + ximage->f.put_pixel = PutPixel32LSB; + else if ((ximage->bits_per_pixel | ximage->depth) == 1) + ximage->f.put_pixel = PutPixel1; + else + ximage->f.put_pixel = PutPixel; +#endif /* not FOR_MSW && not AMIGA */ + } + + /* create the shape mask image */ + if (mask_pixel_index != XpmUndefPixel && shapeimage_return) { + ErrorStatus = CreateXImage(display, visual, 1, bitmap_format, + width, height, &shapeimage); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + +#if !defined(FOR_MSW) && !defined(AMIGA) + if (shapeimage->bitmap_bit_order == MSBFirst) + shapeimage->f.put_pixel = PutPixel1MSB; + else + shapeimage->f.put_pixel = PutPixel1LSB; +#endif + } + + /* + * read pixels and put them in the XImage + */ + ErrorStatus = ParseAndPutPixels( +#ifdef FOR_MSW + display, +#endif + data, width, height, ncolors, cpp, + colorTable, &hashtable, + ximage, image_pixels, + shapeimage, mask_pixels); + XpmFree(image_pixels); + image_pixels = NULL; + XpmFree(mask_pixels); + mask_pixels = NULL; + + /* + * free the hastable + */ + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + else if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + + /* + * store the pixels comment line + */ + if (cmts) + xpmGetCmt(data, &pixels_cmt); + + /* + * parse extensions + */ + if (info && (info->valuemask & XpmReturnExtensions)) { + if (extensions) { + ErrorStatus = xpmParseExtensions(data, &info->extensions, + &info->nextensions); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } else { + info->extensions = NULL; + info->nextensions = 0; + } + } + /* + * store found informations in the XpmImage structure + */ + image->width = width; + image->height = height; + image->cpp = cpp; + image->ncolors = ncolors; + image->colorTable = colorTable; + image->data = NULL; + + if (info) { + if (cmts) { + info->hints_cmt = hints_cmt; + info->colors_cmt = colors_cmt; + info->pixels_cmt = pixels_cmt; + } + if (hotspot) { + info->x_hotspot = x_hotspot; + info->y_hotspot = y_hotspot; + info->valuemask |= XpmHotspot; + } + } + /* if requested return used pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnPixels || +/* 3.2 backward compatibility code */ + attributes->valuemask & XpmReturnInfos)) { +/* end 3.2 bc */ + attributes->pixels = used_pixels; + attributes->npixels = nused_pixels; + attributes->mask_pixel = mask_pixel_index; + } else + XpmFree(used_pixels); + + /* if requested return alloc'ed pixels in the XpmAttributes structure */ + if (attributes && (attributes->valuemask & XpmReturnAllocPixels)) { + attributes->alloc_pixels = alloc_pixels; + attributes->nalloc_pixels = nalloc_pixels; + } else + XpmFree(alloc_pixels); + + /* return created images */ + if (image_return) + *image_return = ximage; + if (shapeimage_return) + *shapeimage_return = shapeimage; + + return (XpmSuccess); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + if (colorTable) + xpmFreeColorTable(colorTable, ncolors); + if (hints_cmt) + XpmFree(hints_cmt); + if (colors_cmt) + XpmFree(colors_cmt); + if (pixels_cmt) + XpmFree(pixels_cmt); + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + if (image_pixels) + XpmFree(image_pixels); + if (mask_pixels) + XpmFree(mask_pixels); + if (nalloc_pixels) + (*freeColors)(display, colormap, alloc_pixels, nalloc_pixels, NULL); + if (alloc_pixels) + XpmFree(alloc_pixels); + if (used_pixels) + XpmFree(used_pixels); + + return (ErrorStatus); +} + +static int +ParseAndPutPixels( +#ifdef FOR_MSW + Display *dc, +#endif + xpmData *data, + unsigned int width, + unsigned int height, + unsigned int ncolors, + unsigned int cpp, + XpmColor *colorTable, + xpmHashTable *hashtable, + XImage *image, + Pixel *image_pixels, + XImage *shapeimage, + Pixel *shape_pixels) +{ + unsigned int a, x, y; + + switch (cpp) { + + case (1): /* Optimize for single character + * colors */ + { + unsigned short colidx[256]; +#ifdef FOR_MSW + HDC shapedc; + HBITMAP obm, sobm; + + if ( shapeimage ) { + shapedc = CreateCompatibleDC(*dc); + sobm = SelectObject(shapedc, shapeimage->bitmap); + } else { + shapedc = NULL; + } + obm = SelectObject(*dc, image->bitmap); +#endif + if (ncolors > 256) + return (XpmFileInvalid); + + bzero((char *)colidx, 256 * sizeof(short)); + for (a = 0; a < ncolors; a++) + colidx[(unsigned char)colorTable[a].string[0]] = a + 1; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + int c = xpmGetC(data); + + if (c > 0 && c < 256 && colidx[c] != 0) { +#ifndef FOR_MSW + XPutPixel(image, x, y, image_pixels[colidx[c] - 1]); + if (shapeimage) + XPutPixel(shapeimage, x, y, + shape_pixels[colidx[c] - 1]); +#else + SetPixel(*dc, x, y, image_pixels[colidx[c] - 1]); + if (shapedc) { + SetPixel(shapedc, x, y, shape_pixels[colidx[c] - 1]); + } +#endif + } else + return (XpmFileInvalid); + } + } +#ifdef FOR_MSW + if ( shapedc ) { + SelectObject(shapedc, sobm); + DeleteDC(shapedc); + } + SelectObject(*dc, obm); +#endif + } + break; + + case (2): /* Optimize for double character + * colors */ + { + +/* free all allocated pointers at all exits */ +#define FREE_CIDX {int f; for (f = 0; f < 256; f++) \ +if (cidx[f]) XpmFree(cidx[f]);} + + /* array of pointers malloced by need */ + unsigned short *cidx[256]; + unsigned int char1; + + bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ + for (a = 0; a < ncolors; a++) { + char1 = (unsigned char) colorTable[a].string[0]; + if (cidx[char1] == NULL) { /* get new memory */ + cidx[char1] = (unsigned short *) + XpmCalloc(256, sizeof(unsigned short)); + if (cidx[char1] == NULL) { /* new block failed */ + FREE_CIDX; + return (XpmNoMemory); + } + } + cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1; + } + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + int cc1 = xpmGetC(data); + if (cc1 > 0 && cc1 < 256) { + int cc2 = xpmGetC(data); + if (cc2 > 0 && cc2 < 256 && + cidx[cc1] && cidx[cc1][cc2] != 0) { +#ifndef FOR_MSW + XPutPixel(image, x, y, + image_pixels[cidx[cc1][cc2] - 1]); + if (shapeimage) + XPutPixel(shapeimage, x, y, + shape_pixels[cidx[cc1][cc2] - 1]); +#else + SelectObject(*dc, image->bitmap); + SetPixel(*dc, x, y, image_pixels[cidx[cc1][cc2] - 1]); + if (shapeimage) { + SelectObject(*dc, shapeimage->bitmap); + SetPixel(*dc, x, y, + shape_pixels[cidx[cc1][cc2] - 1]); + } +#endif + } else { + FREE_CIDX; + return (XpmFileInvalid); + } + } else { + FREE_CIDX; + return (XpmFileInvalid); + } + } + } + FREE_CIDX; + } + break; + + default: /* Non-optimized case of long color + * names */ + { + char *s; + char buf[BUFSIZ]; + + if (cpp >= sizeof(buf)) + return (XpmFileInvalid); + + buf[cpp] = '\0'; + if (USE_HASHTABLE) { + xpmHashAtom *slot; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + slot = xpmHashSlot(hashtable, buf); + if (!*slot) /* no color matches */ + return (XpmFileInvalid); +#ifndef FOR_MSW + XPutPixel(image, x, y, + image_pixels[HashColorIndex(slot)]); + if (shapeimage) + XPutPixel(shapeimage, x, y, + shape_pixels[HashColorIndex(slot)]); +#else + SelectObject(*dc, image->bitmap); + SetPixel(*dc, x, y, + image_pixels[HashColorIndex(slot)]); + if (shapeimage) { + SelectObject(*dc, shapeimage->bitmap); + SetPixel(*dc, x, y, + shape_pixels[HashColorIndex(slot)]); + } +#endif + } + } + } else { + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); + for (a = 0; a < ncolors; a++) + if (!strcmp(colorTable[a].string, buf)) + break; + if (a == ncolors) /* no color matches */ + return (XpmFileInvalid); +#ifndef FOR_MSW + XPutPixel(image, x, y, image_pixels[a]); + if (shapeimage) + XPutPixel(shapeimage, x, y, shape_pixels[a]); +#else + SelectObject(*dc, image->bitmap); + SetPixel(*dc, x, y, image_pixels[a]); + if (shapeimage) { + SelectObject(*dc, shapeimage->bitmap); + SetPixel(*dc, x, y, shape_pixels[a]); + } +#endif + } + } + } + } + break; + } + return (XpmSuccess); +} diff --git a/src/data.c b/src/data.c new file mode 100644 index 0000000..898889c --- /dev/null +++ b/src/data.c @@ -0,0 +1,481 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* data.c: * +* * +* XPM library * +* IO utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* October 2004, source code review by Thomas Biege */ + +#ifndef CXPMPROG +#if 0 +/* Official version number */ +static char *RCS_Version = "$XpmVersion: 3.4k $"; + +/* Internal version number */ +static char *RCS_Id = "Id: xpm.shar,v 3.71 1998/03/19 19:47:14 lehors Exp $"; +#endif +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#endif +#include + +#ifndef CXPMPROG +#define Getc(data, file) getc(file) +#define Ungetc(data, c, file) ungetc(c, file) +#endif + +static int +ParseComment(xpmData *data) +{ + if (data->type == XPMBUFFER) { + register char c; + register unsigned int n = 0; + unsigned int notend; + char *s; + const char *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; + const char *s2; + + s = data->Comment; + *s = data->Bcmt[0]; + + /* skip the string beginning comment */ + s2 = data->Bcmt; + do { + c = Getc(data, file); + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c != EOF); + + if (*s2 != '\0') { + /* this wasn't the beginning of a comment */ + /* put characters back in the order that we got them */ + for (a = n; a > 0; a--, s--) + Ungetc(data, *s, file); + return 0; + } + /* store comment */ + data->Comment[0] = *s; + s = data->Comment; + notend = 1; + n = 0; + while (notend) { + s2 = data->Ecmt; + while (*s != *s2 && c != EOF) { + c = Getc(data, file); + if (n == XPMMAXCMTLEN - 1) { /* forget it */ + s = data->Comment; + n = 0; + } + *++s = c; + n++; + } + data->CommentLength = n; + do { + c = Getc(data, file); + if (n == XPMMAXCMTLEN - 1) { /* forget it */ + s = data->Comment; + n = 0; + } + *++s = c; + n++; + s2++; + } while (c == *s2 && *s2 != '\0' && c != EOF); + if (*s2 == '\0') { + /* this is the end of the comment */ + notend = 0; + Ungetc(data, *s, file); + } + } + return 0; + } +} + +/* + * skip to the end of the current string and the beginning of the next one + */ +int +xpmNextString(xpmData *data) +{ + if (!data->type) + data->cptr = (data->stream.data)[++data->line]; + else if (data->type == XPMBUFFER) { + register char c; + + /* get to the end of the current string */ + if (data->Eos) + while ((c = *data->cptr++) && c != data->Eos); + + /* + * then get to the beginning of the next string looking for possible + * comment + */ + if (data->Bos) { + while ((c = *data->cptr++) && c != data->Bos) + if (data->Bcmt && c == data->Bcmt[0]) + ParseComment(data); + } else if (data->Bcmt) { /* XPM2 natural */ + while ((c = *data->cptr++) == data->Bcmt[0]) + ParseComment(data); + data->cptr--; + } + } else { + register int c; + FILE *file = data->stream.file; + + /* get to the end of the current string */ + if (data->Eos) + while ((c = Getc(data, file)) != data->Eos && c != EOF); + + /* + * then get to the beginning of the next string looking for possible + * comment + */ + if (data->Bos) { + while ((c = Getc(data, file)) != data->Bos && c != EOF) + if (data->Bcmt && c == data->Bcmt[0]) + ParseComment(data); + + } else if (data->Bcmt) { /* XPM2 natural */ + while ((c = Getc(data, file)) == data->Bcmt[0]) + ParseComment(data); + Ungetc(data, c, file); + } + } + return 0; +} + + +/* + * skip whitespace and return the following word + */ +unsigned int +xpmNextWord( + xpmData *data, + char *buf, + unsigned int buflen) +{ + register unsigned int n = 0; + int c; + + if (!data->type || data->type == XPMBUFFER) { + while (isspace(c = *data->cptr) && c != data->Eos) + data->cptr++; + do { + c = *data->cptr++; + *buf++ = c; + n++; + } while (!isspace(c) && c != data->Eos && n < buflen); + n--; + data->cptr--; + } else { + FILE *file = data->stream.file; + + while ((c = Getc(data, file)) != EOF && isspace(c) && c != data->Eos); + while (!isspace(c) && c != data->Eos && c != EOF && n < buflen) { + *buf++ = c; + n++; + c = Getc(data, file); + } + Ungetc(data, c, file); + } + return (n); /* this returns bytes read + 1 */ +} + +/* + * skip whitespace and compute the following unsigned int, + * returns 1 if one is found and 0 if not + */ +int +xpmNextUI( + xpmData *data, + unsigned int *ui_return) +{ + char buf[BUFSIZ]; + int l; + + l = xpmNextWord(data, buf, BUFSIZ); + return xpmatoui(buf, l, ui_return); +} + +/* + * return end of string - WARNING: malloc! + */ +int +xpmGetString( + xpmData *data, + char **sptr, + unsigned int *l) +{ + unsigned int i, n = 0; + int c; + char *p = NULL, *q, buf[BUFSIZ]; + + if (!data->type || data->type == XPMBUFFER) { + if (data->cptr) { + char *start = data->cptr; + while ((c = *data->cptr) && c != data->Eos) + data->cptr++; + n = data->cptr - start + 1; + p = (char *) XpmMalloc(n); + if (!p) + return (XpmNoMemory); + strncpy(p, start, n); + if (data->type) /* XPMBUFFER */ + p[n - 1] = '\0'; + } + } else { + FILE *file = data->stream.file; + + if ((c = Getc(data, file)) == EOF) + return (XpmFileInvalid); + + i = 0; + q = buf; + p = (char *) XpmMalloc(1); + while (c != data->Eos && c != EOF) { + if (i == BUFSIZ) { + /* get to the end of the buffer */ + /* malloc needed memory */ + q = (char *) XpmRealloc(p, n + i); + if (!q) { + XpmFree(p); + return (XpmNoMemory); + } + p = q; + q += n; + /* and copy what we already have */ + strncpy(q, buf, i); + n += i; + i = 0; + q = buf; + } + *q++ = c; + i++; + c = Getc(data, file); + } + if (c == EOF) { + XpmFree(p); + return (XpmFileInvalid); + } + if (n + i != 0) { + /* malloc needed memory */ + q = (char *) XpmRealloc(p, n + i + 1); + if (!q) { + XpmFree(p); + return (XpmNoMemory); + } + p = q; + q += n; + /* and copy the buffer */ + strncpy(q, buf, i); + n += i; + p[n++] = '\0'; + } else { + *p = '\0'; + n = 1; + } + Ungetc(data, c, file); + } + *sptr = p; + *l = n; + return (XpmSuccess); +} + +/* + * get the current comment line + */ +int +xpmGetCmt( + xpmData *data, + char **cmt) +{ + if (!data->type) + *cmt = NULL; + else if (data->CommentLength != 0 && data->CommentLength < UINT_MAX - 1) { + if( (*cmt = (char *) XpmMalloc(data->CommentLength + 1)) == NULL) + return XpmNoMemory; + strncpy(*cmt, data->Comment, data->CommentLength); + (*cmt)[data->CommentLength] = '\0'; + data->CommentLength = 0; + } else + *cmt = NULL; + return 0; +} + +xpmDataType xpmDataTypes[] = +{ + {"", "!", "\n", '\0', '\n', "", "", "", ""}, /* Natural type */ + {"C", "/*", "*/", '"', '"', ",\n", "static char *", "[] = {\n", "};\n"}, + {"Lisp", ";", "\n", '"', '"', "\n", "(setq ", " '(\n", "))\n"}, + {NULL, NULL, NULL, 0, 0, NULL, NULL, NULL, NULL} +}; + +/* + * parse xpm header + */ +int +xpmParseHeader(xpmData *data) +{ + char buf[BUFSIZ+1] = {0}; + int l, n = 0; + + if (data->type) { + data->Bos = '\0'; + data->Eos = '\n'; + data->Bcmt = data->Ecmt = NULL; + l = xpmNextWord(data, buf, BUFSIZ); + if (l == 7 && !strncmp("#define", buf, 7)) { + /* this maybe an XPM 1 file */ + char *ptr; + + l = xpmNextWord(data, buf, BUFSIZ); + if (!l) + return (XpmFileInvalid); + buf[l] = '\0'; + ptr = strrchr(buf, '_'); + if (!ptr || strncmp("_format", ptr, l - (ptr - buf))) + return XpmFileInvalid; + /* this is definitely an XPM 1 file */ + data->format = 1; + n = 1; /* handle XPM1 as mainly XPM2 C */ + } else { + + /* + * skip the first word, get the second one, and see if this is + * XPM 2 or 3 + */ + l = xpmNextWord(data, buf, BUFSIZ); + if ((l == 3 && !strncmp("XPM", buf, 3)) || + (l == 4 && !strncmp("XPM2", buf, 4))) { + if (l == 3) + n = 1; /* handle XPM as XPM2 C */ + else { + /* get the type key word */ + l = xpmNextWord(data, buf, BUFSIZ); + + /* + * get infos about this type + */ + while (xpmDataTypes[n].type + && strncmp(xpmDataTypes[n].type, buf, l)) + n++; + } + data->format = 0; + } else + /* nope this is not an XPM file */ + return XpmFileInvalid; + } + if (xpmDataTypes[n].type) { + if (n == 0) { /* natural type */ + data->Bcmt = xpmDataTypes[n].Bcmt; + data->Ecmt = xpmDataTypes[n].Ecmt; + xpmNextString(data); /* skip the end of the headerline */ + data->Bos = xpmDataTypes[n].Bos; + data->Eos = xpmDataTypes[n].Eos; + } else { + data->Bcmt = xpmDataTypes[n].Bcmt; + data->Ecmt = xpmDataTypes[n].Ecmt; + if (!data->format) { /* XPM 2 or 3 */ + data->Bos = xpmDataTypes[n].Bos; + data->Eos = '\0'; + /* get to the beginning of the first string */ + xpmNextString(data); + data->Eos = xpmDataTypes[n].Eos; + } else /* XPM 1 skip end of line */ + xpmNextString(data); + } + } else + /* we don't know about that type of XPM file... */ + return XpmFileInvalid; + } + return XpmSuccess; +} diff --git a/src/hashtab.c b/src/hashtab.c new file mode 100644 index 0000000..1bd4109 --- /dev/null +++ b/src/hashtab.c @@ -0,0 +1,239 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* hashtab.c: * +* * +* XPM library * +* * +* Developed by Arnaud Le Hors * +* this originaly comes from Colas Nahaboo as a part of Wool * +* * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +LFUNC(AtomMake, xpmHashAtom, (char *name, void *data)); +LFUNC(HashTableGrows, int, (xpmHashTable * table)); + +static xpmHashAtom +AtomMake( /* makes an atom */ + char *name, /* WARNING: is just pointed to */ + void *data) +{ + xpmHashAtom object = (xpmHashAtom) XpmMalloc(sizeof(struct _xpmHashAtom)); + + if (object) { + object->name = name; + object->data = data; + } + return object; +} + +/************************\ +* * +* hash table routines * +* * +\************************/ + +/* + * Hash function definition: + * HASH_FUNCTION: hash function, hash = hashcode, hp = pointer on char, + * hash2 = temporary for hashcode. + * INITIAL_TABLE_SIZE in slots + * HASH_TABLE_GROWS how hash table grows. + */ + +/* Mock lisp function */ +#define HASH_FUNCTION hash = (hash << 5) - hash + *hp++; +/* #define INITIAL_HASH_SIZE 2017 */ +#define INITIAL_HASH_SIZE 256 /* should be enough for colors */ +#define HASH_TABLE_GROWS size = size * 2; + +/* aho-sethi-ullman's HPJ (sizes should be primes)*/ +#ifdef notdef +#define HASH_FUNCTION hash <<= 4; hash += *hp++; \ + if(hash2 = hash & 0xf0000000) hash ^= (hash2 >> 24) ^ hash2; +#define INITIAL_HASH_SIZE 4095 /* should be 2^n - 1 */ +#define HASH_TABLE_GROWS size = size << 1 + 1; +#endif + +/* GNU emacs function */ +/* +#define HASH_FUNCTION hash = (hash << 3) + (hash >> 28) + *hp++; +#define INITIAL_HASH_SIZE 2017 +#define HASH_TABLE_GROWS size = size * 2; +*/ + +/* end of hash functions */ + +/* + * The hash table is used to store atoms via their NAME: + * + * NAME --hash--> ATOM |--name--> "foo" + * |--data--> any value which has to be stored + * + */ + +/* + * xpmHashSlot gives the slot (pointer to xpmHashAtom) of a name + * (slot points to NULL if it is not defined) + * + */ + +xpmHashAtom * +xpmHashSlot( + xpmHashTable *table, + char *s) +{ + xpmHashAtom *atomTable = table->atomTable; + unsigned int hash; + xpmHashAtom *p; + char *hp = s; + char *ns; + + hash = 0; + while (*hp) { /* computes hash function */ + HASH_FUNCTION + } + p = atomTable + hash % table->size; + while (*p) { + ns = (*p)->name; + if (ns[0] == s[0] && strcmp(ns, s) == 0) + break; + p--; + if (p < atomTable) + p = atomTable + table->size - 1; + } + return p; +} + +static int +HashTableGrows(xpmHashTable *table) +{ + xpmHashAtom *atomTable = table->atomTable; + unsigned int size = table->size; + xpmHashAtom *t, *p; + int i; + unsigned int oldSize = size; + + t = atomTable; + HASH_TABLE_GROWS + table->size = size; + table->limit = size / 3; + if (size >= UINT_MAX / sizeof(*atomTable)) + return (XpmNoMemory); + atomTable = (xpmHashAtom *) XpmMalloc(size * sizeof(*atomTable)); + if (!atomTable) + return (XpmNoMemory); + table->atomTable = atomTable; + for (p = atomTable + size; p > atomTable;) + *--p = NULL; + for (i = 0, p = t; i < oldSize; i++, p++) + if (*p) { + xpmHashAtom *ps = xpmHashSlot(table, (*p)->name); + + *ps = *p; + } + XpmFree(t); + return (XpmSuccess); +} + +/* + * xpmHashIntern(table, name, data) + * an xpmHashAtom is created if name doesn't exist, with the given data. + */ + +int +xpmHashIntern( + xpmHashTable *table, + char *tag, + void *data) +{ + xpmHashAtom *slot; + + if (!*(slot = xpmHashSlot(table, tag))) { + /* undefined, make a new atom with the given data */ + if (!(*slot = AtomMake(tag, data))) + return (XpmNoMemory); + if (table->used >= table->limit) { + int ErrorStatus; + + if ((ErrorStatus = HashTableGrows(table)) != XpmSuccess) + return (ErrorStatus); + table->used++; + return (XpmSuccess); + } + table->used++; + } + return (XpmSuccess); +} + +/* + * must be called before allocating any atom + */ + +int +xpmHashTableInit(xpmHashTable *table) +{ + xpmHashAtom *p; + xpmHashAtom *atomTable; + + table->size = INITIAL_HASH_SIZE; + table->limit = table->size / 3; + table->used = 0; + table->atomTable = NULL; + if (table->size >= UINT_MAX / sizeof(*atomTable)) + return (XpmNoMemory); + atomTable = (xpmHashAtom *) XpmMalloc(table->size * sizeof(*atomTable)); + if (!atomTable) + return (XpmNoMemory); + for (p = atomTable + table->size; p > atomTable;) + *--p = NULL; + table->atomTable = atomTable; + return (XpmSuccess); +} + +/* + * frees a hashtable and all the stored atoms + */ + +void +xpmHashTableFree(xpmHashTable *table) +{ + xpmHashAtom *p; + xpmHashAtom *atomTable = table->atomTable; + + if (!atomTable) + return; + for (p = atomTable + table->size; p > atomTable;) + if (*--p) + XpmFree(*p); + XpmFree(atomTable); + table->atomTable = NULL; +} diff --git a/src/misc.c b/src/misc.c new file mode 100644 index 0000000..e5bc0f6 --- /dev/null +++ b/src/misc.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* misc.c: * +* * +* XPM library * +* Miscellaneous utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +#ifdef NEED_STRDUP +/* + * in case strdup is not provided by the system here is one + * which does the trick + */ +char * +xpmstrdup(char *s1) +{ + char *s2; + size_t l = strlen(s1) + 1; + + if (s2 = (char *) XpmMalloc(l)) + strcpy(s2, s1); + return s2; +} + +#endif + +unsigned int +xpmatoui( + register char *p, + unsigned int l, + unsigned int *ui_return) +{ + register unsigned int n, i; + + n = 0; + for (i = 0; i < l; i++) + if (*p >= '0' && *p <= '9') + n = n * 10 + *p++ - '0'; + else + break; + + if (i != 0 && i == l) { + *ui_return = n; + return 1; + } else + return 0; +} + +/* + * Function returning a character string related to an error code. + */ +char * +XpmGetErrorString(int errcode) +{ + switch (errcode) { + case XpmColorError: + return ("XpmColorError"); + case XpmSuccess: + return ("XpmSuccess"); + case XpmOpenFailed: + return ("XpmOpenFailed"); + case XpmFileInvalid: + return ("XpmFileInvalid"); + case XpmNoMemory: + return ("XpmNoMemory"); + case XpmColorFailed: + return ("XpmColorFailed"); + default: + return ("Invalid XpmError"); + } +} + +/* + * The following function provides a way to figure out if the linked library is + * newer or older than the one with which a program has been first compiled. + */ +int +XpmLibraryVersion(void) +{ + return XpmIncludeVersion; +} + + +/* The following should help people wanting to use their own functions */ +#ifdef XpmFree +#undef XpmFree +#endif + +void +XpmFree(void *ptr) +{ + free(ptr); +} diff --git a/src/parse.c b/src/parse.c new file mode 100644 index 0000000..ff23a47 --- /dev/null +++ b/src/parse.c @@ -0,0 +1,805 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* parse.c: * +* * +* XPM library * +* Parse an XPM file or array and store the found informations * +* in the given XpmImage structure. * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#include +#include + +#if defined(HAS_STRLCAT) || defined(HAVE_STRLCAT) +# define STRLCAT(dst, src, dstsize) do { \ + if (strlcat(dst, src, dstsize) >= (dstsize)) \ + return (XpmFileInvalid); } while(0) +# define STRLCPY(dst, src, dstsize) do { \ + if (strlcpy(dst, src, dstsize) >= (dstsize)) \ + return (XpmFileInvalid); } while(0) +#else +# define STRLCAT(dst, src, dstsize) do { \ + if ((strlen(dst) + strlen(src)) < (dstsize)) \ + strcat(dst, src); \ + else return (XpmFileInvalid); } while(0) +# define STRLCPY(dst, src, dstsize) do { \ + if (strlen(src) < (dstsize)) \ + strcpy(dst, src); \ + else return (XpmFileInvalid); } while(0) +#endif + +LFUNC(ParsePixels, int, (xpmData *data, unsigned int width, + unsigned int height, unsigned int ncolors, + unsigned int cpp, XpmColor *colorTable, + xpmHashTable *hashtable, unsigned int **pixels)); + +const char *xpmColorKeys[] = { + "s", /* key #1: symbol */ + "m", /* key #2: mono visual */ + "g4", /* key #3: 4 grays visual */ + "g", /* key #4: gray visual */ + "c", /* key #5: color visual */ +}; + +int +xpmParseValues( + xpmData *data, + unsigned int *width, + unsigned int *height, + unsigned int *ncolors, + unsigned int *cpp, + unsigned int *x_hotspot, + unsigned int *y_hotspot, + unsigned int *hotspot, + unsigned int *extensions) +{ + unsigned int l; + char buf[BUFSIZ + 1]; + + if (!data->format) { /* XPM 2 or 3 */ + + /* + * read values: width, height, ncolors, chars_per_pixel + */ + if (!(xpmNextUI(data, width) && xpmNextUI(data, height) + && xpmNextUI(data, ncolors) && xpmNextUI(data, cpp))) + return (XpmFileInvalid); + + /* + * read optional information (hotspot and/or XPMEXT) if any + */ + l = xpmNextWord(data, buf, BUFSIZ); + if (l) { + *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6)); + if (*extensions) + *hotspot = (xpmNextUI(data, x_hotspot) + && xpmNextUI(data, y_hotspot)); + else { + *hotspot = (xpmatoui(buf, l, x_hotspot) + && xpmNextUI(data, y_hotspot)); + l = xpmNextWord(data, buf, BUFSIZ); + *extensions = (l == 6 && !strncmp("XPMEXT", buf, 6)); + } + } + } else { + + /* + * XPM 1 file read values: width, height, ncolors, chars_per_pixel + */ + int i; + char *ptr; + Bool got_one, saw_width = False, saw_height = False; + Bool saw_ncolors = False, saw_chars_per_pixel = False; + + for (i = 0; i < 4; i++) { + l = xpmNextWord(data, buf, BUFSIZ); + if (l != 7 || strncmp("#define", buf, 7)) + return (XpmFileInvalid); + l = xpmNextWord(data, buf, BUFSIZ); + if (!l) + return (XpmFileInvalid); + buf[l] = '\0'; + ptr = buf; + got_one = False; + while (!got_one) { + ptr = strchr(ptr, '_'); + if (!ptr) + return (XpmFileInvalid); + switch (l - (ptr - buf)) { + case 6: + if (saw_width || strncmp("_width", ptr, 6) + || !xpmNextUI(data, width)) + return (XpmFileInvalid); + else + saw_width = True; + got_one = True; + break; + case 7: + if (saw_height || strncmp("_height", ptr, 7) + || !xpmNextUI(data, height)) + return (XpmFileInvalid); + else + saw_height = True; + got_one = True; + break; + case 8: + if (saw_ncolors || strncmp("_ncolors", ptr, 8) + || !xpmNextUI(data, ncolors)) + return (XpmFileInvalid); + else + saw_ncolors = True; + got_one = True; + break; + case 16: + if (saw_chars_per_pixel + || strncmp("_chars_per_pixel", ptr, 16) + || !xpmNextUI(data, cpp)) + return (XpmFileInvalid); + else + saw_chars_per_pixel = True; + got_one = True; + break; + default: + ptr++; + } + } + /* skip the end of line */ + xpmNextString(data); + } + if (!saw_width || !saw_height || !saw_ncolors || !saw_chars_per_pixel) + return (XpmFileInvalid); + + *hotspot = 0; + *extensions = 0; + } + return (XpmSuccess); +} + +int +xpmParseColors( + xpmData *data, + unsigned int ncolors, + unsigned int cpp, + XpmColor **colorTablePtr, + xpmHashTable *hashtable) +{ + unsigned int key = 0, l, a, b, len; + unsigned int curkey; /* current color key */ + unsigned int lastwaskey; /* key read */ + char buf[BUFSIZ+1]; + char curbuf[BUFSIZ]; /* current buffer */ + const char **sptr; + char *s; + XpmColor *color; + XpmColor *colorTable; + char **defaults; + int ErrorStatus; + + if (ncolors >= UINT_MAX / sizeof(XpmColor)) + return (XpmNoMemory); + colorTable = (XpmColor *) XpmCalloc(ncolors, sizeof(XpmColor)); + if (!colorTable) + return (XpmNoMemory); + + if (!data->format) { /* XPM 2 or 3 */ + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + xpmNextString(data); /* skip the line */ + + /* + * read pixel value + */ + if (cpp >= UINT_MAX - 1) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + color->string = (char *) XpmMalloc(cpp + 1); + if (!color->string) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + for (b = 0, s = color->string; b < cpp; b++, s++) + *s = xpmGetC(data); + *s = '\0'; + + /* + * store the string in the hashtable with its color index number + */ + if (USE_HASHTABLE) { + ErrorStatus = + xpmHashIntern(hashtable, color->string, HashAtomData(a)); + if (ErrorStatus != XpmSuccess) { + xpmFreeColorTable(colorTable, ncolors); + return (ErrorStatus); + } + } + + /* + * read color keys and values + */ + defaults = (char **) color; + curkey = 0; + lastwaskey = 0; + *curbuf = '\0'; /* init curbuf */ + while ((l = xpmNextWord(data, buf, BUFSIZ))) { + if (!lastwaskey) { + for (key = 0, sptr = xpmColorKeys; key < NKEYS; key++, + sptr++) + if ((strlen(*sptr) == l) && (!strncmp(*sptr, buf, l))) + break; + } + if (!lastwaskey && key < NKEYS) { /* open new key */ + if (curkey) { /* flush string */ + len = strlen(curbuf) + 1; + s = (char *) XpmMalloc(len); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + defaults[curkey] = s; + memcpy(s, curbuf, len); + } + curkey = key + 1; /* set new key */ + *curbuf = '\0'; /* reset curbuf */ + lastwaskey = 1; + } else { + if (!curkey) { /* key without value */ + xpmFreeColorTable(colorTable, ncolors); + return (XpmFileInvalid); + } + if (!lastwaskey) + STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */ + buf[l] = '\0'; + STRLCAT(curbuf, buf, sizeof(curbuf)); /* append buf */ + lastwaskey = 0; + } + } + if (!curkey) { /* key without value */ + xpmFreeColorTable(colorTable, ncolors); + return (XpmFileInvalid); + } + len = strlen(curbuf) + 1; /* integer overflow just theoretically possible */ + s = defaults[curkey] = (char *) XpmMalloc(len); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + memcpy(s, curbuf, len); + } + } else { /* XPM 1 */ + /* get to the beginning of the first string */ + data->Bos = '"'; + data->Eos = '\0'; + xpmNextString(data); + data->Eos = '"'; + for (a = 0, color = colorTable; a < ncolors; a++, color++) { + + /* + * read pixel value + */ + if (cpp >= UINT_MAX - 1) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + color->string = (char *) XpmMalloc(cpp + 1); + if (!color->string) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + for (b = 0, s = color->string; b < cpp; b++, s++) + *s = xpmGetC(data); + *s = '\0'; + + /* + * store the string in the hashtable with its color index number + */ + if (USE_HASHTABLE) { + ErrorStatus = + xpmHashIntern(hashtable, color->string, HashAtomData(a)); + if (ErrorStatus != XpmSuccess) { + xpmFreeColorTable(colorTable, ncolors); + return (ErrorStatus); + } + } + + /* + * read color values + */ + xpmNextString(data); /* get to the next string */ + *curbuf = '\0'; /* init curbuf */ + while ((l = xpmNextWord(data, buf, BUFSIZ))) { + if (*curbuf != '\0') + STRLCAT(curbuf, " ", sizeof(curbuf));/* append space */ + buf[l] = '\0'; + STRLCAT(curbuf, buf, sizeof(curbuf)); /* append buf */ + } + len = strlen(curbuf) + 1; + s = (char *) XpmMalloc(len); + if (!s) { + xpmFreeColorTable(colorTable, ncolors); + return (XpmNoMemory); + } + memcpy(s, curbuf, len); + color->c_color = s; + *curbuf = '\0'; /* reset curbuf */ + if (a < ncolors - 1) /* can we trust ncolors -> leave data's bounds */ + xpmNextString(data); /* get to the next string */ + } + } + *colorTablePtr = colorTable; + return (XpmSuccess); +} + +static int +ParsePixels( + xpmData *data, + unsigned int width, + unsigned int height, + unsigned int ncolors, + unsigned int cpp, + XpmColor *colorTable, + xpmHashTable *hashtable, + unsigned int **pixels) +{ + unsigned int *iptr, *iptr2 = NULL; /* found by Egbert Eich */ + unsigned int a, x, y; + + if ((height > 0 && width >= UINT_MAX / height) || + width * height >= UINT_MAX / sizeof(unsigned int)) + return XpmNoMemory; +#ifndef FOR_MSW + iptr2 = (unsigned int *) XpmMalloc(sizeof(unsigned int) * width * height); +#else + + /* + * special treatment to trick DOS malloc(size_t) where size_t is 16 bit!! + * XpmMalloc is defined to longMalloc(long) and checks the 16 bit boundary + */ + iptr2 = (unsigned int *) + XpmMalloc((long) sizeof(unsigned int) * (long) width * (long) height); +#endif + if (!iptr2) + return (XpmNoMemory); + + iptr = iptr2; + + switch (cpp) { + + case (1): /* Optimize for single character + * colors */ + { + unsigned short colidx[256]; + + if (ncolors > 256) { + XpmFree(iptr2); /* found by Egbert Eich */ + return (XpmFileInvalid); + } + + bzero((char *)colidx, 256 * sizeof(short)); + for (a = 0; a < ncolors; a++) + colidx[(unsigned char)colorTable[a].string[0]] = a + 1; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + int c = xpmGetC(data); + + if (c > 0 && c < 256 && colidx[c] != 0) + *iptr = colidx[c] - 1; + else { + XpmFree(iptr2); + return (XpmFileInvalid); + } + } + } + } + break; + + case (2): /* Optimize for double character + * colors */ + { + +/* free all allocated pointers at all exits */ +#define FREE_CIDX \ +do \ +{ \ + int f; for (f = 0; f < 256; f++) \ + if (cidx[f]) XpmFree(cidx[f]); \ +} while(0) + + /* array of pointers malloced by need */ + unsigned short *cidx[256]; + unsigned int char1; + + bzero((char *)cidx, 256 * sizeof(unsigned short *)); /* init */ + for (a = 0; a < ncolors; a++) { + char1 = (unsigned char) colorTable[a].string[0]; + if (cidx[char1] == NULL) { /* get new memory */ + cidx[char1] = (unsigned short *) + XpmCalloc(256, sizeof(unsigned short)); + if (cidx[char1] == NULL) { /* new block failed */ + FREE_CIDX; + XpmFree(iptr2); + return (XpmNoMemory); + } + } + cidx[char1][(unsigned char)colorTable[a].string[1]] = a + 1; + } + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + int cc1 = xpmGetC(data); + if (cc1 > 0 && cc1 < 256) { + int cc2 = xpmGetC(data); + if (cc2 > 0 && cc2 < 256 && + cidx[cc1] && cidx[cc1][cc2] != 0) + *iptr = cidx[cc1][cc2] - 1; + else { + FREE_CIDX; + XpmFree(iptr2); + return (XpmFileInvalid); + } + } else { + FREE_CIDX; + XpmFree(iptr2); + return (XpmFileInvalid); + } + } + } + FREE_CIDX; + } + break; + + default: /* Non-optimized case of long color + * names */ + { + char *s; + char buf[BUFSIZ]; + + if (cpp >= sizeof(buf)) { + XpmFree(iptr2); /* found by Egbert Eich */ + return (XpmFileInvalid); + } + + buf[cpp] = '\0'; + if (USE_HASHTABLE) { + xpmHashAtom *slot; + + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); /* int assigned to char, not a problem here */ + slot = xpmHashSlot(hashtable, buf); + if (!*slot) { /* no color matches */ + XpmFree(iptr2); + return (XpmFileInvalid); + } + *iptr = HashColorIndex(slot); + } + } + } else { + for (y = 0; y < height; y++) { + xpmNextString(data); + for (x = 0; x < width; x++, iptr++) { + for (a = 0, s = buf; a < cpp; a++, s++) + *s = xpmGetC(data); /* int assigned to char, not a problem here */ + for (a = 0; a < ncolors; a++) + if (!strcmp(colorTable[a].string, buf)) + break; + if (a == ncolors) { /* no color matches */ + XpmFree(iptr2); + return (XpmFileInvalid); + } + *iptr = a; + } + } + } + } + break; + } + *pixels = iptr2; + return (XpmSuccess); +} + +int +xpmParseExtensions( + xpmData *data, + XpmExtension **extensions, + unsigned int *nextensions) +{ + XpmExtension *exts = NULL, *ext; + unsigned int num = 0; + unsigned int nlines, a, l, notstart, notend = 0; + int status; + char *string, *s, *s2, **sp; + + xpmNextString(data); + exts = (XpmExtension *) XpmMalloc(sizeof(XpmExtension)); + /* get the whole string */ + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + XpmFree(exts); + return (status); + } + /* look for the key word XPMEXT, skip lines before this */ + while ((notstart = strncmp("XPMEXT", string, 6)) + && (notend = strncmp("XPMENDEXT", string, 9))) { + XpmFree(string); + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + XpmFree(exts); + return (status); + } + } + if (!notstart) + notend = strncmp("XPMENDEXT", string, 9); + while (!notstart && notend) { + /* there starts an extension */ + ext = (XpmExtension *) + XpmRealloc(exts, (num + 1) * sizeof(XpmExtension)); /* can the loop be forced to iterate often enough to make "(num + 1) * sizeof(XpmExtension)" wrapping? */ + if (!ext) { + XpmFree(string); + XpmFreeExtensions(exts, num); + return (XpmNoMemory); + } + exts = ext; + ext += num; + /* skip whitespace and store its name */ + s2 = s = string + 6; + while (isspace(*s2)) + s2++; + a = s2 - s; + ext->name = (char *) XpmMalloc(l - a - 6); + if (!ext->name) { + XpmFree(string); + ext->lines = NULL; + ext->nlines = 0; + XpmFreeExtensions(exts, num + 1); + return (XpmNoMemory); + } + strncpy(ext->name, s + a, l - a - 6); + XpmFree(string); + /* now store the related lines */ + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + ext->lines = NULL; + ext->nlines = 0; + XpmFreeExtensions(exts, num + 1); + return (status); + } + ext->lines = (char **) XpmMalloc(sizeof(char *)); + nlines = 0; + while ((notstart = strncmp("XPMEXT", string, 6)) + && (notend = strncmp("XPMENDEXT", string, 9))) { + sp = (char **) + XpmRealloc(ext->lines, (nlines + 1) * sizeof(char *)); /* can we iterate enough for a wrapping? */ + if (!sp) { + XpmFree(string); + ext->nlines = nlines; + XpmFreeExtensions(exts, num + 1); + return (XpmNoMemory); + } + ext->lines = sp; + ext->lines[nlines] = string; + nlines++; + xpmNextString(data); + status = xpmGetString(data, &string, &l); + if (status != XpmSuccess) { + ext->nlines = nlines; + XpmFreeExtensions(exts, num + 1); + return (status); + } + } + if (!nlines) { + XpmFree(ext->lines); + ext->lines = NULL; + } + ext->nlines = nlines; + num++; + } + if (!num) { + XpmFree(string); + XpmFree(exts); + exts = NULL; + } else if (!notend) + XpmFree(string); + *nextensions = num; + *extensions = exts; + return (XpmSuccess); +} + + +/* function call in case of error */ +#undef RETURN +#define RETURN(status) \ +do { \ + goto error; \ +} while(0) + +/* + * This function parses an Xpm file or data and store the found informations + * in an an XpmImage structure which is returned. + */ +int +xpmParseData( + xpmData *data, + XpmImage *image, + XpmInfo *info) +{ + /* variables to return */ + unsigned int width, height, ncolors, cpp; + unsigned int x_hotspot, y_hotspot, hotspot = 0, extensions = 0; + XpmColor *colorTable = NULL; + unsigned int *pixelindex = NULL; + char *hints_cmt = NULL; + char *colors_cmt = NULL; + char *pixels_cmt = NULL; + + unsigned int cmts; + int ErrorStatus; + xpmHashTable hashtable; + + cmts = info && (info->valuemask & XpmReturnComments); + + /* + * parse the header + */ + ErrorStatus = xpmParseHeader(data); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * read values + */ + ErrorStatus = xpmParseValues(data, &width, &height, &ncolors, &cpp, + &x_hotspot, &y_hotspot, &hotspot, + &extensions); + if (ErrorStatus != XpmSuccess) + return (ErrorStatus); + + /* + * store the hints comment line + */ + if (cmts) + xpmGetCmt(data, &hints_cmt); + + /* + * init the hashtable + */ + if (USE_HASHTABLE) { + ErrorStatus = xpmHashTableInit(&hashtable); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * read colors + */ + ErrorStatus = xpmParseColors(data, ncolors, cpp, &colorTable, &hashtable); + if (ErrorStatus != XpmSuccess) { + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + RETURN(ErrorStatus); + } + + /* + * store the colors comment line + */ + if (cmts) + xpmGetCmt(data, &colors_cmt); + + /* + * read pixels and index them on color number + */ + ErrorStatus = ParsePixels(data, width, height, ncolors, cpp, colorTable, + &hashtable, &pixelindex); + + /* + * free the hastable + */ + if (USE_HASHTABLE) + xpmHashTableFree(&hashtable); + + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store the pixels comment line + */ + if (cmts) + xpmGetCmt(data, &pixels_cmt); + + /* + * parse extensions + */ + if (info && (info->valuemask & XpmReturnExtensions)) { + if (extensions) { + ErrorStatus = xpmParseExtensions(data, &info->extensions, + &info->nextensions); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } else { + info->extensions = NULL; + info->nextensions = 0; + } + } + + /* + * store found informations in the XpmImage structure + */ + image->width = width; + image->height = height; + image->cpp = cpp; + image->ncolors = ncolors; + image->colorTable = colorTable; + image->data = pixelindex; + + if (info) { + if (cmts) { + info->hints_cmt = hints_cmt; + info->colors_cmt = colors_cmt; + info->pixels_cmt = pixels_cmt; + } + if (hotspot) { + info->x_hotspot = x_hotspot; + info->y_hotspot = y_hotspot; + info->valuemask |= XpmHotspot; + } + } + return (XpmSuccess); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (colorTable) + xpmFreeColorTable(colorTable, ncolors); + if (pixelindex) + XpmFree(pixelindex); + if (hints_cmt) + XpmFree(hints_cmt); + if (colors_cmt) + XpmFree(colors_cmt); + if (pixels_cmt) + XpmFree(pixels_cmt); + + return(ErrorStatus); +} diff --git a/src/rgb.c b/src/rgb.c new file mode 100644 index 0000000..729898d --- /dev/null +++ b/src/rgb.c @@ -0,0 +1,287 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* rgb.c: * +* * +* XPM library * +* Rgb file utilities * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * Part of this code has been taken from the ppmtoxpm.c file written by Mark + * W. Snitily but has been modified for my special need + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" +#include + +#ifndef FOR_MSW /* normal part first, MSW part at + * the end, (huge ifdef!) */ +/* + * Read a rgb text file. It stores the rgb values (0->65535) + * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the + * number of entries stored. + */ +int +xpmReadRgbNames( + char *rgb_fname, + xpmRgbName rgbn[]) +{ + FILE *rgbf; + int n, items, red, green, blue; + char line[512], name[512], *rgbname, *s1, *s2; + xpmRgbName *rgb; + + /* Open the rgb text file. Abort if error. */ + if ((rgbf = fopen(rgb_fname, "r")) == NULL) + return 0; + + /* Loop reading each line in the file. */ + n = 0; + rgb = rgbn; + /* Quit if rgb text file has too many entries. */ + while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) { + + /* Skip silently if line is bad. */ + items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); + if (items != 4) + continue; + + /* + * Make sure rgb values are within 0->255 range. Skip silently if + * bad. + */ + if (red < 0 || red > 0xFF || + green < 0 || green > 0xFF || + blue < 0 || blue > 0xFF) + continue; + + /* Allocate memory for ascii name. If error give up here. */ + if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1))) + break; + + /* Copy string to ascii name and lowercase it. */ + for (s1 = name, s2 = rgbname; *s1; s1++) + *s2++ = tolower(*s1); + *s2 = '\0'; + + /* Save the rgb values and ascii name in the array. */ + rgb->r = red * 257; /* 65535/255 = 257 */ + rgb->g = green * 257; + rgb->b = blue * 257; + rgb->name = rgbname; + rgb++; + n++; + } + + fclose(rgbf); + + /* Return the number of read rgb names. */ + return n < 0 ? 0 : n; +} + +/* + * Return the color name corresponding to the given rgb values + */ +char * +xpmGetRgbName( + xpmRgbName rgbn[], /* rgb mnemonics from rgb text file */ + int rgbn_max, /* number of rgb mnemonics in table */ + int red, /* rgb values */ + int green, + int blue) +{ + int i; + xpmRgbName *rgb; + + /* + * Just perform a dumb linear search over the rgb values of the color + * mnemonics. One could speed things up by sorting the rgb values and + * using a binary search, or building a hash table, etc... + */ + for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++) + if (red == rgb->r && green == rgb->g && blue == rgb->b) + return rgb->name; + + /* if not found return NULL */ + return NULL; +} + +/* + * Free the strings which have been malloc'ed in xpmReadRgbNames + */ +void +xpmFreeRgbNames( + xpmRgbName rgbn[], + int rgbn_max) +{ + int i; + xpmRgbName *rgb; + + for (i = 0, rgb = rgbn; i < rgbn_max; i++, rgb++) + XpmFree(rgb->name); +} + +#else /* here comes the MSW part, the + * second part of the huge ifdef */ + +#include "rgbtab.h" /* hard coded rgb.txt table */ + +int +xpmReadRgbNames( + char *rgb_fname, + xpmRgbName rgbn[]) +{ + /* + * check for consistency??? + * table has to be sorted for calls on strcasecmp + */ + return (numTheRGBRecords); +} + +/* + * MSW rgb values are made from 3 BYTEs, this is different from X XColor.red, + * which has something like #0303 for one color + */ +char * +xpmGetRgbName( + xpmRgbName rgbn[], /* rgb mnemonics from rgb text file + * not used */ + int rgbn_max, /* not used */ + int red, /* rgb values */ + int green, + int blue) + +{ + int i; + unsigned long rgbVal; + + i = 0; + while (i < numTheRGBRecords) { + rgbVal = theRGBRecords[i].rgb; + if (GetRValue(rgbVal) == red && + GetGValue(rgbVal) == green && + GetBValue(rgbVal) == blue) + return (theRGBRecords[i].name); + i++; + } + return (NULL); +} + +/* used in XParseColor in simx.c */ +int +xpmGetRGBfromName( + char *inname, + int *r, + int *g, + int *b) +{ + int left, right, middle; + int cmp; + unsigned long rgbVal; + char *name; + char *grey, *p; + + name = xpmstrdup(inname); + + /* + * the table in rgbtab.c has no names with spaces, and no grey, but a + * lot of gray + */ + /* so first extract ' ' */ + while (p = strchr(name, ' ')) { + while (*(p)) { /* till eof of string */ + *p = *(p + 1); /* copy to the left */ + p++; + } + } + /* fold to lower case */ + p = name; + while (*p) { + *p = tolower(*p); + p++; + } + + /* + * substitute Grey with Gray, else rgbtab.h would have more than 100 + * 'duplicate' entries + */ + if (grey = strstr(name, "grey")) + grey[2] = 'a'; + + /* binary search */ + left = 0; + right = numTheRGBRecords - 1; + do { + middle = (left + right) / 2; + cmp = xpmstrcasecmp(name, theRGBRecords[middle].name); + if (cmp == 0) { + rgbVal = theRGBRecords[middle].rgb; + *r = GetRValue(rgbVal); + *g = GetGValue(rgbVal); + *b = GetBValue(rgbVal); + free(name); + return (1); + } else if (cmp < 0) { + right = middle - 1; + } else { /* > 0 */ + left = middle + 1; + } + } while (left <= right); + + /* + * I don't like to run in a ColorInvalid error and to see no pixmap at + * all, so simply return a red pixel. Should be wrapped in an #ifdef + * HeDu + */ + + *r = 255; + *g = 0; + *b = 0; /* red error pixel */ + + free(name); + return (1); +} + +void +xpmFreeRgbNames( + xpmRgbName rgbn[], + int rgbn_max) +{ + /* nothing to do */ +} + +#endif /* MSW part */ diff --git a/src/rgbtab.h b/src/rgbtab.h new file mode 100644 index 0000000..3b75184 --- /dev/null +++ b/src/rgbtab.h @@ -0,0 +1,292 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* rgbtab.h * +* * +* A hard coded rgb.txt. To keep it short I removed all colornames with * +* trailing numbers, Blue3 etc, except the GrayXX. Sorry Grey-lovers I prefer * +* Gray ;-). But Grey is recognized on lookups, only on save Gray will be * +* used, maybe you want to do some substitue there too. * +* * +* To save memory the RGBs are coded in one long value, as done by the RGB * +* macro. * +* * +* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de) * +\*****************************************************************************/ + + +typedef struct { + char *name; + COLORREF rgb; /* it's unsigned long */ +} rgbRecord; + +/* +#define myRGB(r,g,b) \ + ((unsigned long)r<<16|(unsigned long)g<<8|(unsigned long)b) +*/ +#define myRGB(r,g,b) RGB(r,g,b) /* MSW has this macro */ + + +static rgbRecord theRGBRecords[] = +{ + {"AliceBlue", myRGB(240, 248, 255)}, + {"AntiqueWhite", myRGB(250, 235, 215)}, + {"Aquamarine", myRGB(50, 191, 193)}, + {"Azure", myRGB(240, 255, 255)}, + {"Beige", myRGB(245, 245, 220)}, + {"Bisque", myRGB(255, 228, 196)}, + {"Black", myRGB(0, 0, 0)}, + {"BlanchedAlmond", myRGB(255, 235, 205)}, + {"Blue", myRGB(0, 0, 255)}, + {"BlueViolet", myRGB(138, 43, 226)}, + {"Brown", myRGB(165, 42, 42)}, + {"burlywood", myRGB(222, 184, 135)}, + {"CadetBlue", myRGB(95, 146, 158)}, + {"chartreuse", myRGB(127, 255, 0)}, + {"chocolate", myRGB(210, 105, 30)}, + {"Coral", myRGB(255, 114, 86)}, + {"CornflowerBlue", myRGB(34, 34, 152)}, + {"cornsilk", myRGB(255, 248, 220)}, + {"Cyan", myRGB(0, 255, 255)}, + {"DarkGoldenrod", myRGB(184, 134, 11)}, + {"DarkGreen", myRGB(0, 86, 45)}, + {"DarkKhaki", myRGB(189, 183, 107)}, + {"DarkOliveGreen", myRGB(85, 86, 47)}, + {"DarkOrange", myRGB(255, 140, 0)}, + {"DarkOrchid", myRGB(139, 32, 139)}, + {"DarkSalmon", myRGB(233, 150, 122)}, + {"DarkSeaGreen", myRGB(143, 188, 143)}, + {"DarkSlateBlue", myRGB(56, 75, 102)}, + {"DarkSlateGray", myRGB(47, 79, 79)}, + {"DarkTurquoise", myRGB(0, 166, 166)}, + {"DarkViolet", myRGB(148, 0, 211)}, + {"DeepPink", myRGB(255, 20, 147)}, + {"DeepSkyBlue", myRGB(0, 191, 255)}, + {"DimGray", myRGB(84, 84, 84)}, + {"DodgerBlue", myRGB(30, 144, 255)}, + {"Firebrick", myRGB(142, 35, 35)}, + {"FloralWhite", myRGB(255, 250, 240)}, + {"ForestGreen", myRGB(80, 159, 105)}, + {"gainsboro", myRGB(220, 220, 220)}, + {"GhostWhite", myRGB(248, 248, 255)}, + {"Gold", myRGB(218, 170, 0)}, + {"Goldenrod", myRGB(239, 223, 132)}, + {"Gray", myRGB(126, 126, 126)}, + {"Gray0", myRGB(0, 0, 0)}, + {"Gray1", myRGB(3, 3, 3)}, + {"Gray10", myRGB(26, 26, 26)}, + {"Gray100", myRGB(255, 255, 255)}, + {"Gray11", myRGB(28, 28, 28)}, + {"Gray12", myRGB(31, 31, 31)}, + {"Gray13", myRGB(33, 33, 33)}, + {"Gray14", myRGB(36, 36, 36)}, + {"Gray15", myRGB(38, 38, 38)}, + {"Gray16", myRGB(41, 41, 41)}, + {"Gray17", myRGB(43, 43, 43)}, + {"Gray18", myRGB(46, 46, 46)}, + {"Gray19", myRGB(48, 48, 48)}, + {"Gray2", myRGB(5, 5, 5)}, + {"Gray20", myRGB(51, 51, 51)}, + {"Gray21", myRGB(54, 54, 54)}, + {"Gray22", myRGB(56, 56, 56)}, + {"Gray23", myRGB(59, 59, 59)}, + {"Gray24", myRGB(61, 61, 61)}, + {"Gray25", myRGB(64, 64, 64)}, + {"Gray26", myRGB(66, 66, 66)}, + {"Gray27", myRGB(69, 69, 69)}, + {"Gray28", myRGB(71, 71, 71)}, + {"Gray29", myRGB(74, 74, 74)}, + {"Gray3", myRGB(8, 8, 8)}, + {"Gray30", myRGB(77, 77, 77)}, + {"Gray31", myRGB(79, 79, 79)}, + {"Gray32", myRGB(82, 82, 82)}, + {"Gray33", myRGB(84, 84, 84)}, + {"Gray34", myRGB(87, 87, 87)}, + {"Gray35", myRGB(89, 89, 89)}, + {"Gray36", myRGB(92, 92, 92)}, + {"Gray37", myRGB(94, 94, 94)}, + {"Gray38", myRGB(97, 97, 97)}, + {"Gray39", myRGB(99, 99, 99)}, + {"Gray4", myRGB(10, 10, 10)}, + {"Gray40", myRGB(102, 102, 102)}, + {"Gray41", myRGB(105, 105, 105)}, + {"Gray42", myRGB(107, 107, 107)}, + {"Gray43", myRGB(110, 110, 110)}, + {"Gray44", myRGB(112, 112, 112)}, + {"Gray45", myRGB(115, 115, 115)}, + {"Gray46", myRGB(117, 117, 117)}, + {"Gray47", myRGB(120, 120, 120)}, + {"Gray48", myRGB(122, 122, 122)}, + {"Gray49", myRGB(125, 125, 125)}, + {"Gray5", myRGB(13, 13, 13)}, + {"Gray50", myRGB(127, 127, 127)}, + {"Gray51", myRGB(130, 130, 130)}, + {"Gray52", myRGB(133, 133, 133)}, + {"Gray53", myRGB(135, 135, 135)}, + {"Gray54", myRGB(138, 138, 138)}, + {"Gray55", myRGB(140, 140, 140)}, + {"Gray56", myRGB(143, 143, 143)}, + {"Gray57", myRGB(145, 145, 145)}, + {"Gray58", myRGB(148, 148, 148)}, + {"Gray59", myRGB(150, 150, 150)}, + {"Gray6", myRGB(15, 15, 15)}, + {"Gray60", myRGB(153, 153, 153)}, + {"Gray61", myRGB(156, 156, 156)}, + {"Gray62", myRGB(158, 158, 158)}, + {"Gray63", myRGB(161, 161, 161)}, + {"Gray64", myRGB(163, 163, 163)}, + {"Gray65", myRGB(166, 166, 166)}, + {"Gray66", myRGB(168, 168, 168)}, + {"Gray67", myRGB(171, 171, 171)}, + {"Gray68", myRGB(173, 173, 173)}, + {"Gray69", myRGB(176, 176, 176)}, + {"Gray7", myRGB(18, 18, 18)}, + {"Gray70", myRGB(179, 179, 179)}, + {"Gray71", myRGB(181, 181, 181)}, + {"Gray72", myRGB(184, 184, 184)}, + {"Gray73", myRGB(186, 186, 186)}, + {"Gray74", myRGB(189, 189, 189)}, + {"Gray75", myRGB(191, 191, 191)}, + {"Gray76", myRGB(194, 194, 194)}, + {"Gray77", myRGB(196, 196, 196)}, + {"Gray78", myRGB(199, 199, 199)}, + {"Gray79", myRGB(201, 201, 201)}, + {"Gray8", myRGB(20, 20, 20)}, + {"Gray80", myRGB(204, 204, 204)}, + {"Gray81", myRGB(207, 207, 207)}, + {"Gray82", myRGB(209, 209, 209)}, + {"Gray83", myRGB(212, 212, 212)}, + {"Gray84", myRGB(214, 214, 214)}, + {"Gray85", myRGB(217, 217, 217)}, + {"Gray86", myRGB(219, 219, 219)}, + {"Gray87", myRGB(222, 222, 222)}, + {"Gray88", myRGB(224, 224, 224)}, + {"Gray89", myRGB(227, 227, 227)}, + {"Gray9", myRGB(23, 23, 23)}, + {"Gray90", myRGB(229, 229, 229)}, + {"Gray91", myRGB(232, 232, 232)}, + {"Gray92", myRGB(235, 235, 235)}, + {"Gray93", myRGB(237, 237, 237)}, + {"Gray94", myRGB(240, 240, 240)}, + {"Gray95", myRGB(242, 242, 242)}, + {"Gray96", myRGB(245, 245, 245)}, + {"Gray97", myRGB(247, 247, 247)}, + {"Gray98", myRGB(250, 250, 250)}, + {"Gray99", myRGB(252, 252, 252)}, + {"Green", myRGB(0, 255, 0)}, + {"GreenYellow", myRGB(173, 255, 47)}, + {"honeydew", myRGB(240, 255, 240)}, + {"HotPink", myRGB(255, 105, 180)}, + {"IndianRed", myRGB(107, 57, 57)}, + {"ivory", myRGB(255, 255, 240)}, + {"Khaki", myRGB(179, 179, 126)}, + {"lavender", myRGB(230, 230, 250)}, + {"LavenderBlush", myRGB(255, 240, 245)}, + {"LawnGreen", myRGB(124, 252, 0)}, + {"LemonChiffon", myRGB(255, 250, 205)}, + {"LightBlue", myRGB(176, 226, 255)}, + {"LightCoral", myRGB(240, 128, 128)}, + {"LightCyan", myRGB(224, 255, 255)}, + {"LightGoldenrod", myRGB(238, 221, 130)}, + {"LightGoldenrodYellow", myRGB(250, 250, 210)}, + {"LightGray", myRGB(168, 168, 168)}, + {"LightPink", myRGB(255, 182, 193)}, + {"LightSalmon", myRGB(255, 160, 122)}, + {"LightSeaGreen", myRGB(32, 178, 170)}, + {"LightSkyBlue", myRGB(135, 206, 250)}, + {"LightSlateBlue", myRGB(132, 112, 255)}, + {"LightSlateGray", myRGB(119, 136, 153)}, + {"LightSteelBlue", myRGB(124, 152, 211)}, + {"LightYellow", myRGB(255, 255, 224)}, + {"LimeGreen", myRGB(0, 175, 20)}, + {"linen", myRGB(250, 240, 230)}, + {"Magenta", myRGB(255, 0, 255)}, + {"Maroon", myRGB(143, 0, 82)}, + {"MediumAquamarine", myRGB(0, 147, 143)}, + {"MediumBlue", myRGB(50, 50, 204)}, + {"MediumForestGreen", myRGB(50, 129, 75)}, + {"MediumGoldenrod", myRGB(209, 193, 102)}, + {"MediumOrchid", myRGB(189, 82, 189)}, + {"MediumPurple", myRGB(147, 112, 219)}, + {"MediumSeaGreen", myRGB(52, 119, 102)}, + {"MediumSlateBlue", myRGB(106, 106, 141)}, + {"MediumSpringGreen", myRGB(35, 142, 35)}, + {"MediumTurquoise", myRGB(0, 210, 210)}, + {"MediumVioletRed", myRGB(213, 32, 121)}, + {"MidnightBlue", myRGB(47, 47, 100)}, + {"MintCream", myRGB(245, 255, 250)}, + {"MistyRose", myRGB(255, 228, 225)}, + {"moccasin", myRGB(255, 228, 181)}, + {"NavajoWhite", myRGB(255, 222, 173)}, + {"Navy", myRGB(35, 35, 117)}, + {"NavyBlue", myRGB(35, 35, 117)}, + {"OldLace", myRGB(253, 245, 230)}, + {"OliveDrab", myRGB(107, 142, 35)}, + {"Orange", myRGB(255, 135, 0)}, + {"OrangeRed", myRGB(255, 69, 0)}, + {"Orchid", myRGB(239, 132, 239)}, + {"PaleGoldenrod", myRGB(238, 232, 170)}, + {"PaleGreen", myRGB(115, 222, 120)}, + {"PaleTurquoise", myRGB(175, 238, 238)}, + {"PaleVioletRed", myRGB(219, 112, 147)}, + {"PapayaWhip", myRGB(255, 239, 213)}, + {"PeachPuff", myRGB(255, 218, 185)}, + {"peru", myRGB(205, 133, 63)}, + {"Pink", myRGB(255, 181, 197)}, + {"Plum", myRGB(197, 72, 155)}, + {"PowderBlue", myRGB(176, 224, 230)}, + {"purple", myRGB(160, 32, 240)}, + {"Red", myRGB(255, 0, 0)}, + {"RosyBrown", myRGB(188, 143, 143)}, + {"RoyalBlue", myRGB(65, 105, 225)}, + {"SaddleBrown", myRGB(139, 69, 19)}, + {"Salmon", myRGB(233, 150, 122)}, + {"SandyBrown", myRGB(244, 164, 96)}, + {"SeaGreen", myRGB(82, 149, 132)}, + {"seashell", myRGB(255, 245, 238)}, + {"Sienna", myRGB(150, 82, 45)}, + {"SkyBlue", myRGB(114, 159, 255)}, + {"SlateBlue", myRGB(126, 136, 171)}, + {"SlateGray", myRGB(112, 128, 144)}, + {"snow", myRGB(255, 250, 250)}, + {"SpringGreen", myRGB(65, 172, 65)}, + {"SteelBlue", myRGB(84, 112, 170)}, + {"Tan", myRGB(222, 184, 135)}, + {"Thistle", myRGB(216, 191, 216)}, + {"tomato", myRGB(255, 99, 71)}, + {"Transparent", myRGB(0, 0, 1)}, + {"Turquoise", myRGB(25, 204, 223)}, + {"Violet", myRGB(156, 62, 206)}, + {"VioletRed", myRGB(243, 62, 150)}, + {"Wheat", myRGB(245, 222, 179)}, + {"White", myRGB(255, 255, 255)}, + {"WhiteSmoke", myRGB(245, 245, 245)}, + {"Yellow", myRGB(255, 255, 0)}, + {"YellowGreen", myRGB(50, 216, 56)}, + NULL +}; + +static int numTheRGBRecords = 234; diff --git a/src/scan.c b/src/scan.c new file mode 100644 index 0000000..54c8da5 --- /dev/null +++ b/src/scan.c @@ -0,0 +1,1024 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* scan.c: * +* * +* XPM library * +* Scanning utility for XPM file format * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +/* + * The code related to FOR_MSW has been added by + * HeDu (hedu@cul-ipn.uni-kiel.de) 4/94 + */ + +/* + * The code related to AMIGA has been added by + * Lorens Younes (d93-hyo@nada.kth.se) 4/96 + */ + +/* October 2004, source code review by Thomas Biege */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "XpmI.h" + +#define MAXPRINTABLE 92 /* number of printable ascii chars + * minus \ and " for string compat + * and ? to avoid ANSI trigraphs. */ + +static const char *printable = +" .XoO+@#$%&*=-;:>,<1234567890qwertyuipasdfghjklzxcvbnmMNBVCZ\ +ASDFGHJKLPIUYTREWQ!~^/()_`'][{}|"; + +/* + * printable begin with a space, so in most case, due to my algorithm, when + * the number of different colors is less than MAXPRINTABLE, it will give a + * char follow by "nothing" (a space) in the readable xpm file + */ + + +typedef struct { + Pixel *pixels; + unsigned int *pixelindex; + unsigned int size; + unsigned int ncolors; + unsigned int mask_pixel; /* whether there is or not */ +} PixelsMap; + +LFUNC(storePixel, int, (Pixel pixel, PixelsMap *pmap, + unsigned int *index_return)); + +LFUNC(storeMaskPixel, int, (Pixel pixel, PixelsMap *pmap, + unsigned int *index_return)); + +typedef int (*storeFuncPtr)(Pixel pixel, PixelsMap *pmap, + unsigned int *index_return); + +#ifndef FOR_MSW +# ifndef AMIGA +LFUNC(GetImagePixels, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels32, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels16, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels8, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap)); + +LFUNC(GetImagePixels1, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap, + storeFuncPtr storeFunc)); +# else /* AMIGA */ +LFUNC(AGetImagePixels, int, (XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap, + storeFuncPtr storeFunc)); +# endif/* AMIGA */ +#else /* ndef FOR_MSW */ +LFUNC(MSWGetImagePixels, int, (Display *d, XImage *image, unsigned int width, + unsigned int height, PixelsMap *pmap, + storeFuncPtr storeFunc)); +#endif +LFUNC(ScanTransparentColor, int, (XpmColor *color, unsigned int cpp, + XpmAttributes *attributes)); + +LFUNC(ScanOtherColors, int, (Display *display, XpmColor *colors, + unsigned int ncolors, + Pixel *pixels, unsigned int mask, + unsigned int cpp, XpmAttributes *attributes)); + +/* + * This function stores the given pixel in the given arrays which are grown + * if not large enough. + */ +static int +storePixel( + Pixel pixel, + PixelsMap *pmap, + unsigned int *index_return) +{ + unsigned int i; + Pixel *p; + unsigned int ncolors; + + if (*index_return) { /* this is a transparent pixel! */ + *index_return = 0; + return 0; + } + ncolors = pmap->ncolors; + p = pmap->pixels + pmap->mask_pixel; + for (i = pmap->mask_pixel; i < ncolors; i++, p++) + if (*p == pixel) + break; + if (i == ncolors) { + if (ncolors >= pmap->size) { + pmap->size *= 2; + p = (Pixel *) XpmRealloc(pmap->pixels, sizeof(Pixel) * pmap->size); + if (!p) + return (1); + pmap->pixels = p; + + } + (pmap->pixels)[ncolors] = pixel; + pmap->ncolors++; + } + *index_return = i; + return 0; +} + +static int +storeMaskPixel( + Pixel pixel, + PixelsMap *pmap, + unsigned int *index_return) +{ + if (!pixel) { + if (!pmap->ncolors) { + pmap->ncolors = 1; + (pmap->pixels)[0] = 0; + pmap->mask_pixel = 1; + } + *index_return = 1; + } else + *index_return = 0; + return 0; +} + +/* function call in case of error */ +#undef RETURN +#define RETURN(status) \ +do { \ + ErrorStatus = status; \ + goto error; \ +} while(0) + +/* + * This function scans the given image and stores the found informations in + * the given XpmImage structure. + */ +int +XpmCreateXpmImageFromImage( + Display *display, + XImage *image, + XImage *shapeimage, + XpmImage *xpmimage, + XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + unsigned int cpp; + + /* variables to return */ + PixelsMap pmap; + XpmColor *colorTable = NULL; + int ErrorStatus = 0; + + /* calculation variables */ + unsigned int width = 0; + unsigned int height = 0; + unsigned int cppm; /* minimum chars per pixel */ + unsigned int c; + + /* initialize pmap */ + pmap.pixels = NULL; + pmap.pixelindex = NULL; + pmap.size = 256; /* should be enough most of the time */ + pmap.ncolors = 0; + pmap.mask_pixel = 0; + + /* + * get geometry + */ + if (image) { + width = image->width; + height = image->height; + } else if (shapeimage) { + width = shapeimage->width; + height = shapeimage->height; + } + + /* + * retrieve information from the XpmAttributes + */ + if (attributes && (attributes->valuemask & XpmCharsPerPixel +/* 3.2 backward compatibility code */ + || attributes->valuemask & XpmInfos)) +/* end 3.2 bc */ + cpp = attributes->cpp; + else + cpp = 0; + + if ((height > 0 && width >= UINT_MAX / height) || + width * height >= UINT_MAX / sizeof(unsigned int)) + RETURN(XpmNoMemory); + pmap.pixelindex = + (unsigned int *) XpmCalloc(width * height, sizeof(unsigned int)); + if (!pmap.pixelindex) + RETURN(XpmNoMemory); + + if (pmap.size >= UINT_MAX / sizeof(Pixel)) + RETURN(XpmNoMemory); + + pmap.pixels = (Pixel *) XpmMalloc(sizeof(Pixel) * pmap.size); + if (!pmap.pixels) + RETURN(XpmNoMemory); + + /* + * scan shape mask if any + */ + if (shapeimage) { +#ifndef FOR_MSW +# ifndef AMIGA + ErrorStatus = GetImagePixels1(shapeimage, width, height, &pmap, + storeMaskPixel); +# else + ErrorStatus = AGetImagePixels(shapeimage, width, height, &pmap, + storeMaskPixel); +# endif +#else + ErrorStatus = MSWGetImagePixels(display, shapeimage, width, height, + &pmap, storeMaskPixel); +#endif + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * scan the image data + * + * In case depth is 1 or bits_per_pixel is 4, 6, 8, 24 or 32 use optimized + * functions, otherwise use slower but sure general one. + * + */ + + if (image) { +#ifndef FOR_MSW +# ifndef AMIGA + if (((image->bits_per_pixel | image->depth) == 1) && + (image->byte_order == image->bitmap_bit_order)) + ErrorStatus = GetImagePixels1(image, width, height, &pmap, + storePixel); + else if (image->format == ZPixmap) { + if (image->bits_per_pixel == 8) + ErrorStatus = GetImagePixels8(image, width, height, &pmap); + else if (image->bits_per_pixel == 16) + ErrorStatus = GetImagePixels16(image, width, height, &pmap); + else if (image->bits_per_pixel == 32) + ErrorStatus = GetImagePixels32(image, width, height, &pmap); + } else + ErrorStatus = GetImagePixels(image, width, height, &pmap); +# else + ErrorStatus = AGetImagePixels(image, width, height, &pmap, + storePixel); +# endif +#else + ErrorStatus = MSWGetImagePixels(display, image, width, height, &pmap, + storePixel); +#endif + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + /* + * get rgb values and a string of char, and possibly a name for each + * color + */ + if (pmap.ncolors >= UINT_MAX / sizeof(XpmColor)) + RETURN(XpmNoMemory); + colorTable = (XpmColor *) XpmCalloc(pmap.ncolors, sizeof(XpmColor)); + if (!colorTable) + RETURN(XpmNoMemory); + + /* compute the minimal cpp */ + for (cppm = 1, c = MAXPRINTABLE; pmap.ncolors > c; cppm++) + c *= MAXPRINTABLE; + if (cpp < cppm) + cpp = cppm; + + if (pmap.mask_pixel) { + ErrorStatus = ScanTransparentColor(colorTable, cpp, attributes); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + } + + ErrorStatus = ScanOtherColors(display, colorTable, pmap.ncolors, + pmap.pixels, pmap.mask_pixel, cpp, + attributes); + if (ErrorStatus != XpmSuccess) + RETURN(ErrorStatus); + + /* + * store found informations in the XpmImage structure + */ + xpmimage->width = width; + xpmimage->height = height; + xpmimage->cpp = cpp; + xpmimage->ncolors = pmap.ncolors; + xpmimage->colorTable = colorTable; + xpmimage->data = pmap.pixelindex; + + XpmFree(pmap.pixels); + return (XpmSuccess); + +/* exit point in case of error, free only locally allocated variables */ +error: + if (pmap.pixelindex) + XpmFree(pmap.pixelindex); + if (pmap.pixels) + XpmFree(pmap.pixels); + if (colorTable) + xpmFreeColorTable(colorTable, pmap.ncolors); + + return (ErrorStatus); +} + +static int +ScanTransparentColor( + XpmColor *color, + unsigned int cpp, + XpmAttributes *attributes) +{ + char *s; + unsigned int a, b, c; + + /* first get a character string */ + a = 0; + if (cpp >= UINT_MAX - 1) + return (XpmNoMemory); + if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) + return (XpmNoMemory); + *s++ = printable[c = a % MAXPRINTABLE]; + for (b = 1; b < cpp; b++, s++) + *s = printable[c = ((a - c) / MAXPRINTABLE) % MAXPRINTABLE]; + *s = '\0'; + + /* then retreive related info from the attributes if any */ + if (attributes && (attributes->valuemask & XpmColorTable +/* 3.2 backward compatibility code */ + || attributes->valuemask & XpmInfos) +/* end 3.2 bc */ + && attributes->mask_pixel != XpmUndefPixel) { + + unsigned int key; + char **defaults = (char **) color; + char **mask_defaults; + +/* 3.2 backward compatibility code */ + if (attributes->valuemask & XpmColorTable) +/* end 3.2 bc */ + mask_defaults = (char **) ( + attributes->colorTable + attributes->mask_pixel); +/* 3.2 backward compatibility code */ + else + mask_defaults = (char **) + ((XpmColor **) attributes->colorTable)[attributes->mask_pixel]; +/* end 3.2 bc */ + for (key = 1; key <= NKEYS; key++) { + if ((s = mask_defaults[key])) { + defaults[key] = (char *) xpmstrdup(s); + if (!defaults[key]) + return (XpmNoMemory); + } + } + } else { + color->c_color = (char *) xpmstrdup(TRANSPARENT_COLOR); + if (!color->c_color) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +static int +ScanOtherColors( + Display *display, + XpmColor *colors, + unsigned int ncolors, + Pixel *pixels, + unsigned int mask, + unsigned int cpp, + XpmAttributes *attributes) +{ + /* variables stored in the XpmAttributes structure */ + Colormap colormap; + char *rgb_fname; + +#ifndef FOR_MSW + xpmRgbName rgbn[MAX_RGBNAMES]; +#else + xpmRgbName *rgbn = NULL; +#endif + int rgbn_max = 0; + unsigned int i, j, c, i2; + XpmColor *color; + XColor *xcolors = NULL, *xcolor; + char *colorname, *s; + XpmColor *colorTable = NULL, **oldColorTable = NULL; + unsigned int ancolors = 0; + Pixel *apixels = NULL; + unsigned int mask_pixel = 0; + Bool found; + + /* retrieve information from the XpmAttributes */ + if (attributes && (attributes->valuemask & XpmColormap)) + colormap = attributes->colormap; + else + colormap = XDefaultColormap(display, XDefaultScreen(display)); + if (attributes && (attributes->valuemask & XpmRgbFilename)) + rgb_fname = attributes->rgb_fname; + else + rgb_fname = NULL; + + /* start from the right element */ + if (mask) { + colors++; + ncolors--; + pixels++; + } + + /* first get character strings and rgb values */ + if (ncolors >= UINT_MAX / sizeof(XColor) || cpp >= UINT_MAX - 1) + return (XpmNoMemory); + xcolors = (XColor *) XpmMalloc(sizeof(XColor) * ncolors); + if (!xcolors) + return (XpmNoMemory); + + for (i = 0, i2 = mask, color = colors, xcolor = xcolors; + i < ncolors; i++, i2++, color++, xcolor++, pixels++) { + + if (!(s = color->string = (char *) XpmMalloc(cpp + 1))) { + XpmFree(xcolors); + return (XpmNoMemory); + } + *s++ = printable[c = i2 % MAXPRINTABLE]; + for (j = 1; j < cpp; j++, s++) + *s = printable[c = ((i2 - c) / MAXPRINTABLE) % MAXPRINTABLE]; + *s = '\0'; + + xcolor->pixel = *pixels; + } + XQueryColors(display, colormap, xcolors, ncolors); + +#ifndef FOR_MSW + /* read the rgb file if any was specified */ + if (rgb_fname) + rgbn_max = xpmReadRgbNames(attributes->rgb_fname, rgbn); +#else + /* FOR_MSW: rgb names and values are hardcoded in rgbtab.h */ + rgbn_max = xpmReadRgbNames(NULL, NULL); +#endif + + if (attributes && attributes->valuemask & XpmColorTable) { + colorTable = attributes->colorTable; + ancolors = attributes->ncolors; + apixels = attributes->pixels; + mask_pixel = attributes->mask_pixel; + } +/* 3.2 backward compatibility code */ + else if (attributes && attributes->valuemask & XpmInfos) { + oldColorTable = (XpmColor **) attributes->colorTable; + ancolors = attributes->ncolors; + apixels = attributes->pixels; + mask_pixel = attributes->mask_pixel; + } +/* end 3.2 bc */ + + for (i = 0, color = colors, xcolor = xcolors; i < ncolors; + i++, color++, xcolor++) { + + /* look for related info from the attributes if any */ + found = False; + if (ancolors) { + unsigned int offset = 0; + + for (j = 0; j < ancolors; j++) { + if (j == mask_pixel) { + offset = 1; + continue; + } + if (apixels[j - offset] == xcolor->pixel) + break; + } + if (j != ancolors) { + unsigned int key; + char **defaults = (char **) color; + char **adefaults; + +/* 3.2 backward compatibility code */ + if (oldColorTable) + adefaults = (char **) oldColorTable[j]; + else +/* end 3.2 bc */ + adefaults = (char **) (colorTable + j); + + found = True; + for (key = 1; key <= NKEYS; key++) { + if ((s = adefaults[key])) + defaults[key] = (char *) xpmstrdup(s); + } + } + } + if (!found) { + /* if nothing found look for a color name */ + colorname = NULL; + if (rgbn_max) + colorname = xpmGetRgbName(rgbn, rgbn_max, xcolor->red, + xcolor->green, xcolor->blue); + if (colorname) + color->c_color = (char *) xpmstrdup(colorname); + else { + /* at last store the rgb value */ + char buf[BUFSIZ]; +#ifndef FOR_MSW + sprintf(buf, "#%04X%04X%04X", + xcolor->red, xcolor->green, xcolor->blue); +#else + sprintf(buf, "#%02x%02x%02x", + xcolor->red, xcolor->green, xcolor->blue); +#endif + color->c_color = (char *) xpmstrdup(buf); + } + if (!color->c_color) { + XpmFree(xcolors); + xpmFreeRgbNames(rgbn, rgbn_max); + return (XpmNoMemory); + } + } + } + + XpmFree(xcolors); + xpmFreeRgbNames(rgbn, rgbn_max); + return (XpmSuccess); +} + +#ifndef FOR_MSW +# ifndef AMIGA +/* + * The functions below are written from X11R5 MIT's code (XImUtil.c) + * + * The idea is to have faster functions than the standard XGetPixel function + * to scan the image data. Indeed we can speed up things by suppressing tests + * performed for each pixel. We do exactly the same tests but at the image + * level. + */ + +static unsigned long const low_bits_table[] = { + 0x00000000, 0x00000001, 0x00000003, 0x00000007, + 0x0000000f, 0x0000001f, 0x0000003f, 0x0000007f, + 0x000000ff, 0x000001ff, 0x000003ff, 0x000007ff, + 0x00000fff, 0x00001fff, 0x00003fff, 0x00007fff, + 0x0000ffff, 0x0001ffff, 0x0003ffff, 0x0007ffff, + 0x000fffff, 0x001fffff, 0x003fffff, 0x007fffff, + 0x00ffffff, 0x01ffffff, 0x03ffffff, 0x07ffffff, + 0x0fffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, + 0xffffffff +}; + +/* + * Default method to scan pixels of an image data structure. + * The algorithm used is: + * + * copy the source bitmap_unit or Zpixel into temp + * normalize temp if needed + * extract the pixel bits into return value + * + */ + +static int +GetImagePixels( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap) +{ + char *src; + char *dst; + unsigned int *iptr; + char *data; + unsigned int x, y; + int bits, depth, ibu, ibpp, offset, i; + unsigned long lbt; + Pixel pixel, px; + + data = image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + ibpp = image->bits_per_pixel; + offset = image->xoffset; + + if (image->bitmap_unit < 0) + return (XpmNoMemory); + + if ((image->bits_per_pixel | image->depth) == 1) { + ibu = image->bitmap_unit; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + src = &data[XYINDEX(x, y, image)]; + dst = (char *) &pixel; + pixel = 0; + for (i = ibu >> 3; --i >= 0;) + *dst++ = *src++; + XYNORMALIZE(&pixel, image); + bits = (x + offset) % ibu; + pixel = ((((char *) &pixel)[bits >> 3]) >> (bits & 7)) & 1; + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else if (image->format == XYPixmap) { + int nbytes, bpl, j; + long plane = 0; + ibu = image->bitmap_unit; + nbytes = ibu >> 3; + bpl = image->bytes_per_line; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = 0; + plane = 0; + for (i = depth; --i >= 0;) { + src = &data[XYINDEX(x, y, image) + plane]; + dst = (char *) &px; + px = 0; + for (j = nbytes; --j >= 0;) + *dst++ = *src++; + XYNORMALIZE(&px, image); + bits = (x + offset) % ibu; + pixel = (pixel << 1) | + (((((char *) &px)[bits >> 3]) >> (bits & 7)) & 1); + plane = plane + (bpl * height); + } + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else if (image->format == ZPixmap) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + src = &data[ZINDEX(x, y, image)]; + dst = (char *) &px; + px = 0; + for (i = (ibpp + 7) >> 3; --i >= 0;) + *dst++ = *src++; + ZNORMALIZE(&px, image); + pixel = 0; + for (i = sizeof(unsigned long); --i >= 0;) + pixel = (pixel << 8) | ((unsigned char *) &px)[i]; + if (ibpp == 4) { + if (x & 1) + pixel >>= 4; + else + pixel &= 0xf; + } + if (ibpp != depth) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else + return (XpmColorError); /* actually a bad image */ + return (XpmSuccess); +} + +/* + * scan pixels of a 32-bits Z image data structure + */ + +#if !defined(WORD64) && !defined(LONG64) +static unsigned long byteorderpixel = MSBFirst << 24; +#endif + +static int +GetImagePixels32( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap) +{ + unsigned char *addr; + unsigned char *data; + unsigned int *iptr; + unsigned int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; +#if !defined(WORD64) && !defined(LONG64) + if (*((char *) &byteorderpixel) == image->byte_order) { + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = *((unsigned long *) addr); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + } else +#endif + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = ((unsigned long) addr[0] << 24 | + (unsigned long) addr[1] << 16 | + (unsigned long) addr[2] << 8 | + addr[3]); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX32(x, y, image)]; + pixel = (addr[0] | + (unsigned long) addr[1] << 8 | + (unsigned long) addr[2] << 16 | + (unsigned long) addr[3] << 24); + if (depth != 32) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +/* + * scan pixels of a 16-bits Z image data structure + */ + +static int +GetImagePixels16( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap) +{ + unsigned char *addr; + unsigned char *data; + unsigned int *iptr; + unsigned int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + if (image->byte_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + pixel = addr[0] << 8 | addr[1]; + if (depth != 16) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + addr = &data[ZINDEX16(x, y, image)]; + pixel = addr[0] | addr[1] << 8; + if (depth != 16) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +/* + * scan pixels of a 8-bits Z image data structure + */ + +static int +GetImagePixels8( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap) +{ + unsigned int *iptr; + unsigned char *data; + unsigned int x, y; + unsigned long lbt; + Pixel pixel; + int depth; + + data = (unsigned char *) image->data; + iptr = pmap->pixelindex; + depth = image->depth; + lbt = low_bits_table[depth]; + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + pixel = data[ZINDEX8(x, y, image)]; + if (depth != 8) + pixel &= lbt; + if (storePixel(pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +/* + * scan pixels of a 1-bit depth Z image data structure + */ + +static int +GetImagePixels1( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap, + storeFuncPtr storeFunc) +{ + unsigned int *iptr; + unsigned int x, y; + char *data; + Pixel pixel; + int xoff, yoff, offset, bpl; + + data = image->data; + iptr = pmap->pixelindex; + offset = image->xoffset; + bpl = image->bytes_per_line; + + if (image->bitmap_bit_order == MSBFirst) + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + xoff = x + offset; + yoff = y * bpl + (xoff >> 3); + xoff &= 7; + pixel = (data[yoff] & (0x80 >> xoff)) ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + else + for (y = 0; y < height; y++) + for (x = 0; x < width; x++, iptr++) { + xoff = x + offset; + yoff = y * bpl + (xoff >> 3); + xoff &= 7; + pixel = (data[yoff] & (1 << xoff)) ? 1 : 0; + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + return (XpmSuccess); +} + +# else /* AMIGA */ + +#define CLEAN_UP(status) \ +do {\ + if (pixels) XpmFree (pixels);\ + if (tmp_img) FreeXImage (tmp_img);\ + return (status);\ +} while(0) + +static int +AGetImagePixels ( + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap, + int (*storeFunc) (Pixel, PixelsMap *, unsigned int *)) +{ + unsigned int *iptr; + unsigned int x, y; + unsigned char *pixels; + XImage *tmp_img; + + pixels = XpmMalloc ((((width+15)>>4)<<4)*sizeof (*pixels)); + if (pixels == NULL) + return XpmNoMemory; + + tmp_img = AllocXImage ((((width+15)>>4)<<4), 1, image->rp->BitMap->Depth); + if (tmp_img == NULL) + CLEAN_UP (XpmNoMemory); + + iptr = pmap->pixelindex; + for (y = 0; y < height; ++y) + { + ReadPixelLine8 (image->rp, 0, y, width, pixels, tmp_img->rp); + for (x = 0; x < width; ++x, ++iptr) + { + if ((*storeFunc) (pixels[x], pmap, iptr)) + CLEAN_UP (XpmNoMemory); + } + } + + CLEAN_UP (XpmSuccess); +} + +#undef CLEAN_UP + +# endif/* AMIGA */ +#else /* ndef FOR_MSW */ +static int +MSWGetImagePixels( + Display *display, + XImage *image, + unsigned int width, + unsigned int height, + PixelsMap *pmap, + int (*storeFunc) (Pixel, PixelsMap*, unsigned int *)) +{ + unsigned int *iptr; + unsigned int x, y; + Pixel pixel; + + iptr = pmap->pixelindex; + + SelectObject(*display, image->bitmap); + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++, iptr++) { + pixel = GetPixel(*display, x, y); + if ((*storeFunc) (pixel, pmap, iptr)) + return (XpmNoMemory); + } + } + return (XpmSuccess); +} + +#endif + +#ifndef FOR_MSW +# ifndef AMIGA +int +XpmCreateXpmImageFromPixmap( + Display *display, + Pixmap pixmap, + Pixmap shapemask, + XpmImage *xpmimage, + XpmAttributes *attributes) +{ + XImage *ximage = NULL; + XImage *shapeimage = NULL; + unsigned int width = 0; + unsigned int height = 0; + int ErrorStatus; + + /* get geometry */ + if (attributes && attributes->valuemask & XpmSize) { + width = attributes->width; + height = attributes->height; + } + /* get the ximages */ + if (pixmap) + xpmCreateImageFromPixmap(display, pixmap, &ximage, &width, &height); + if (shapemask) + xpmCreateImageFromPixmap(display, shapemask, &shapeimage, + &width, &height); + + /* create the related XpmImage */ + ErrorStatus = XpmCreateXpmImageFromImage(display, ximage, shapeimage, + xpmimage, attributes); + + /* destroy the ximages */ + if (ximage) + XDestroyImage(ximage); + if (shapeimage) + XDestroyImage(shapeimage); + + return (ErrorStatus); +} + +# endif/* not AMIGA */ +#endif /* ndef FOR_MSW */ diff --git a/src/simx.c b/src/simx.c new file mode 100644 index 0000000..c76934b --- /dev/null +++ b/src/simx.c @@ -0,0 +1,293 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* simx.c: 0.1a * +* * +* This emulates some Xlib functionality for MSW. It's not a general solution, * +* it is close related to XPM-lib. It is only intended to satisfy what is need * +* there. Thus allowing to read XPM files under MS windows. * +* * +* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de) * +\*****************************************************************************/ + +#ifdef FOR_MSW + +#ifdef HAVE_CONFIG_H +#include +#endif +#include "xpm.h" +#include "xpmi.h" /* for XpmMalloc */ + +/* + * On DOS size_t is only 2 bytes, thus malloc(size_t s) can only malloc + * 64K. BUT an expression data=malloc(width*height) may result in an + * overflow. So this function takes a long as input, and returns NULL if the + * request is larger than 64K, is size_t is only 2 bytes. + * + * This requires casts like XpmMalloc( (long)width*(long(height)), else it + * might have no effect at all. + */ + +void * +boundCheckingMalloc(long s) +{ + if (sizeof(size_t) == sizeof(long)) { /* same size, just do it */ + return (malloc((size_t) s)); + } else { + if (sizeof(size_t) == 2) { + if (s > 0xFFFF) + return (NULL); /* to large, size_t with 2 bytes + * only allows 16 bits */ + else + return (malloc((size_t) s)); + } else { /* it's not a long, not 2 bytes, + * what is it ??? */ + return (malloc((size_t) s)); + } + } +} +void * +boundCheckingCalloc(long num, long s) +{ + if (sizeof(size_t) == sizeof(long)) { /* same size, just do it */ + return (calloc((size_t) num, (size_t) s)); + } else { + if (sizeof(size_t) == 2) { + if (s > 0xFFFF || num * s > 0xFFFF) + return (NULL); /* to large, size_t with 2 bytes + * only allows 16 bits */ + else + return (calloc((size_t) num, (size_t) s)); + } else { /* it's not a long, not 2 bytes, + * what is it ??? */ + return (calloc((size_t) num, (size_t) s)); + } + } +} +void * +boundCheckingRealloc(void *p, long s) +{ + if (sizeof(size_t) == sizeof(long)) { /* same size, just do it */ + return (realloc(p, (size_t) s)); + } else { + if (sizeof(size_t) == 2) { + if (s > 0xFFFF) + return (NULL); /* to large, size_t with 2 bytes + * only allows 16 bits */ + else + return (realloc(p, (size_t) s)); + } else { /* it's not a long, not 2 bytes, + * what is it ??? */ + return (realloc(p, (size_t) s)); + } + } +} + +/* static Visual theVisual = { 0 }; */ +Visual * +XDefaultVisual(Display *display, Screen *screen) +{ + return (NULL); /* struct could contain info about + * MONO, GRAY, COLOR */ +} + +Screen * +XDefaultScreen(Display *d) +{ + return (NULL); +} + +/* I get only 1 plane but 8 bits per pixel, + so I think BITSPIXEL should be depth */ +int +XDefaultDepth(Display *display, Screen *screen) +{ + int d, b; + + b = GetDeviceCaps(*display, BITSPIXEL); + d = GetDeviceCaps(*display, PLANES); + return (b); +} + +Colormap * +XDefaultColormap(Display *display, Screen *screen) +{ + return (NULL); +} + +/* convert hex color names, + wrong digits (not a-f,A-F,0-9) are treated as zero */ +static int +hexCharToInt(c) +{ + int r; + + if (c >= '0' && c <= '9') + r = c - '0'; + else if (c >= 'a' && c <= 'f') + r = c - 'a' + 10; + else if (c >= 'A' && c <= 'F') + r = c - 'A' + 10; + else + r = 0; + + return (r); +} + +static int +rgbFromHex(char *hex, int *r, int *g, int *b) +{ + int len; + + if (hex == NULL || hex[0] != '#') + return (0); + + len = strlen(hex); + if (len == 3 + 1) { + *r = hexCharToInt(hex[1]); + *g = hexCharToInt(hex[2]); + *b = hexCharToInt(hex[3]); + } else if (len == 6 + 1) { + *r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]); + *g = hexCharToInt(hex[3]) * 16 + hexCharToInt(hex[4]); + *b = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]); + } else if (len == 12 + 1) { + /* it's like c #32329999CCCC */ + /* so for now only take two digits */ + *r = hexCharToInt(hex[1]) * 16 + hexCharToInt(hex[2]); + *g = hexCharToInt(hex[5]) * 16 + hexCharToInt(hex[6]); + *b = hexCharToInt(hex[9]) * 16 + hexCharToInt(hex[10]); + } else + return (0); + + return (1); +} + +/* Color related functions */ +int +XParseColor(Display *d, Colormap *cmap, char *name, XColor *color) +{ + int r, g, b; /* only 8 bit values used */ + int okay; + +/* TODO: use colormap via PALETTE */ + /* parse name either in table or #RRGGBB #RGB */ + if (name == NULL) + return (0); + + if (name[0] == '#') { /* a hex string */ + okay = rgbFromHex(name, &r, &g, &b); + } else { + okay = xpmGetRGBfromName(name, &r, &g, &b); + } + + if (okay) { + color->pixel = RGB(r, g, b); + color->red = (BYTE) r; + color->green = (BYTE) g; + color->blue = (BYTE) b; + return (1); + } else + return (0); /* --> ColorError */ +} + + +int +XAllocColor(Display *d, Colormap cmap, XColor *color) +{ +/* colormap not used yet so color->pixel is the real COLORREF (RBG) and not an + index in some colormap as in X */ + return (1); +} +void +XQueryColors(Display *display, Colormap *colormap, + XColor *xcolors, int ncolors) +{ +/* under X this fills the rgb values to given .pixel */ +/* since there no colormap use FOR_MSW (not yet!!), rgb is plain encoded */ + XColor *xc = xcolors; + int i; + + for (i = 0; i < ncolors; i++, xc++) { + xc->red = GetRValue(xc->pixel); + xc->green = GetGValue(xc->pixel); + xc->blue = GetBValue(xc->pixel); + } + return; +} +int +XFreeColors(Display *d, Colormap cmap, + unsigned long pixels[], int npixels, unsigned long planes) +{ + /* no colormap yet */ + return (0); /* correct ??? */ +} + +/* XImage functions */ +XImage * +XCreateImage(Display *d, Visual *v, + int depth, int format, + int x, int y, int width, int height, + int pad, int foo) +{ + XImage *img = (XImage *) XpmMalloc(sizeof(XImage)); + + if (img) { + /*JW: This is what it should be, but the picture comes out + just black!? It appears to be doing monochrome reduction, + but I've got no clue why. Using CreateBitmap() is supposed + to be slower, but otherwise ok + if ( depth == GetDeviceCaps(*d, BITSPIXEL) ) { + img->bitmap = CreateCompatibleBitmap(*d, width, height); + } else*/ { + img->bitmap = CreateBitmap(width, height, 1 /* plane */ , + depth /* bits per pixel */ , NULL); + } + img->width = width; + img->height = height; + img->depth = depth; + } + return (img); + +} + +void +XImageFree(XImage *img) +{ + if (img) { + XpmFree(img); + } +} +void +XDestroyImage(XImage *img) +{ + if (img) { + DeleteObject(img->bitmap); /* check return ??? */ + XImageFree(img); + } +} + +#endif diff --git a/src/simx.h b/src/simx.h new file mode 100644 index 0000000..7c4c4b9 --- /dev/null +++ b/src/simx.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* simx.h: 0.1a * +* * +* This emulates some Xlib functionality for MSW. It's not a general solution, * +* it is close related to XPM-lib. It is only intended to satisfy what is need * +* there. Thus allowing to read XPM files under MS windows. * +* * +* Developed by HeDu 3/94 (hedu@cul-ipn.uni-kiel.de) * +\*****************************************************************************/ + + +#ifndef _SIMX_H +#define _SIMX_H + +#ifdef FOR_MSW + +#include "windows.h" /* MS windows GDI types */ +#define _XFUNCPROTOBEGIN +#define _XFUNCPROTOEND +#define NO_ZPIPE + +/* + * minimal portability layer between ansi and KR C + */ +/* this comes from xpm.h, and is here again, to avoid complicated + includes, since this is included from xpm.h */ +/* these defines get undefed at the end of this file */ +#if __STDC__ || defined(__cplusplus) || defined(c_plusplus) + /* ANSI || C++ */ +#define FUNC(f, t, p) extern t f p +#define LFUNC(f, t, p) static t f p +#else /* k&R */ +#define FUNC(f, t, p) extern t f() +#define LFUNC(f, t, p) static t f() +#endif + + +FUNC(boundCheckingMalloc, void *, (long s)); +FUNC(boundCheckingCalloc, void *, (long num, long s)); +FUNC(boundCheckingRealloc, void *, (void *p, long s)); + +/* define MSW types for X window types, + I don't know much about MSW, but the following defines do the job */ + +typedef HDC Display; /* this should be similar */ +typedef void *Screen; /* not used */ +typedef void *Visual; /* not used yet, is for GRAY, COLOR, + * MONO */ + +typedef void *Colormap; /* should be COLORPALETTE, not done + * yet */ + +typedef COLORREF Pixel; + +#define PIXEL_ALREADY_TYPEDEFED /* to let xpm.h know about it */ + +typedef struct { + Pixel pixel; + BYTE red, green, blue; +} XColor; + +typedef struct { + HBITMAP bitmap; + unsigned int width; + unsigned int height; + unsigned int depth; +} XImage; + +#if defined(__cplusplus) || defined(c_plusplus) +extern "C" { +#endif +/* some replacements for X... functions */ + +/* XDefaultXXX */ + FUNC(XDefaultVisual, Visual *, (Display *display, Screen *screen)); + FUNC(XDefaultScreen, Screen *, (Display *d)); + FUNC(XDefaultColormap, Colormap *, (Display *display, Screen *screen)); + FUNC(XDefaultDepth, int, (Display *d, Screen *s)); + +/* color related */ + FUNC(XParseColor, int, (Display *, Colormap *, char *, XColor *)); + FUNC(XAllocColor, int, (Display *, Colormap, XColor *)); + FUNC(XQueryColors, void, (Display *display, Colormap *colormap, + XColor *xcolors, int ncolors)); + FUNC(XFreeColors, int, (Display *d, Colormap cmap, + unsigned long pixels[], + int npixels, unsigned long planes)); +/* XImage */ + FUNC(XCreateImage, XImage *, (Display *, Visual *, int depth, int format, + int x, int y, int width, int height, + int pad, int foo)); + +/* free and destroy bitmap */ + FUNC(XDestroyImage, void /* ? */ , (XImage *)); +/* free only, bitmap remains */ + FUNC(XImageFree, void, (XImage *)); +#if defined(__cplusplus) || defined(c_plusplus) +} /* end of extern "C" */ +#endif /* cplusplus */ + +#define ZPixmap 1 /* not really used */ +#define XYBitmap 1 /* not really used */ + +#ifndef True +#define True 1 +#define False 0 +#endif +#ifndef Bool +typedef BOOL Bool; /* take MSW bool */ +#endif +/* make these local here, simx.c gets the same from xpm.h */ +#undef LFUNC +#undef FUNC + +/* Some functions and constants that have non-standard names in the + MS library. */ +#define bzero(addr,sz) memset(addr, 0, sz) +#define close _close +#define fdopen _fdopen +#define index strchr +#define open _open +#define O_RDONLY _O_RDONLY +#define rindex strrchr +#define strdup _strdup + + +#endif /* def FOR_MSW */ + +#endif /* _SIMX_H */ diff --git a/sxpm/Makefile.am b/sxpm/Makefile.am new file mode 100644 index 0000000..7181bde --- /dev/null +++ b/sxpm/Makefile.am @@ -0,0 +1,25 @@ +if BUILD_SXPM + +bin_PROGRAMS = sxpm + +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CFLAGS = $(CWARNFLAGS) $(SXPM_CFLAGS) + +sxpm_SOURCES = sxpm.c + +LDADD = $(SXPM_LIBS) $(top_builddir)/src/libXpm.la + +if USE_GETTEXT +noinst_DATA = sxpm.po + +sxpm.po: $(sxpm_SOURCES:%=$(srcdir)/%) + $(AM_V_GEN)xgettext -c"L10N_Comments" -d sxpm -n $(sxpm_SOURCES:%=$(srcdir)/%) + +CLEANFILES = sxpm.po +endif +endif + +EXTRA_DIST = \ + plaid_ext.xpm \ + plaid_mask.xpm \ + plaid.xpm diff --git a/sxpm/plaid.xpm b/sxpm/plaid.xpm new file mode 100644 index 0000000..6befe8b --- /dev/null +++ b/sxpm/plaid.xpm @@ -0,0 +1,34 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 4 2 ", +/* colors */ +" c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +/* pixels */ +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x " +} ; diff --git a/sxpm/plaid_ext.xpm b/sxpm/plaid_ext.xpm new file mode 100644 index 0000000..c8429d3 --- /dev/null +++ b/sxpm/plaid_ext.xpm @@ -0,0 +1,43 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 4 2 XPMEXT", +/* colors */ +" c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +/* pixels */ +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +"Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x x x x x x x x x x x x x ", +"x x x x x x x x x x x x + x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +" x x x Y x x ", +" x x x x Y x x x ", +"XPMEXT ext1 data1", +"XPMEXT ext2", +"data2_1", +"data2_2", +"XPMEXT ext3", +"data3", +"XPMEXT", +"data4", +"XPMENDEXT" +} ; diff --git a/sxpm/plaid_mask.xpm b/sxpm/plaid_mask.xpm new file mode 100644 index 0000000..f8e7876 --- /dev/null +++ b/sxpm/plaid_mask.xpm @@ -0,0 +1,35 @@ +/* XPM */ +static char * plaid[] = { +/* plaid pixmap + * width height ncolors chars_per_pixel */ +"22 22 5 2", +/* colors */ +". c red m white s light_color ", +"Y c green m black s lines_in_mix ", +"+ c yellow m white s lines_in_dark ", +"x m black s dark_color ", +" c none s mask ", +/* pixels */ +" x x x x x + x x x x x ", +" . x x x x x x x x x x x ", +" . x x x x x x + x x x x x ", +" . x . x x x x x x x x x x x ", +" . x . x x x x x x + x x x x x ", +" Y Y Y Y Y + x + x + x + x + x + ", +" x x . x . x x x x x x + x x x x x ", +" . x . x . x . x x x x x x x x x x x ", +" . x x x . x . x x x x x x + x x x x x ", +" . x . x . x . x . x x x x x x x x x x x ", +" . x . x x x . x . x x x x x x + x x x x x ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +"x x x x x x x x x x x x x x x x x x x x x x ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x ", +". . . . . x . . . . . . x . x . Y . x . x . ", +". . . . . x . . . . . x . x . x Y x . x . x " +} ; diff --git a/sxpm/sxpm.c b/sxpm/sxpm.c new file mode 100644 index 0000000..a5eaa32 --- /dev/null +++ b/sxpm/sxpm.c @@ -0,0 +1,750 @@ +/* + * Copyright (C) 1989-95 GROUPE BULL + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * GROUPE BULL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of GROUPE BULL shall not be + * used in advertising or otherwise to promote the sale, use or other dealings + * in this Software without prior written authorization from GROUPE BULL. + */ + +/*****************************************************************************\ +* sxpm.c: * +* * +* Show XPM File program * +* * +* Developed by Arnaud Le Hors * +\*****************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef VMS +#include +#else +#include +#endif + +#include + +#ifdef USE_GETTEXT +#include +#include +#else +#define gettext(a) (a) +#endif + +/* XPM */ +/* plaid pixmap */ +static char *plaid[] = { + /* width height ncolors chars_per_pixel */ + "22 22 4 2 XPMEXT", + /* colors */ + " c red m white s light_color", + "Y c green m black s lines_in_mix", + "+ c yellow m white s lines_in_dark", + "x m black s dark_color", + /* pixels */ + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + "Y Y Y Y Y x Y Y Y Y Y + x + x + x + x + x + ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x x x x x x x x x x x x x ", + "x x x x x x x x x x x x + x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + "x x x x x x x x x x x x x x x x x x x x x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + " x x x Y x x ", + " x x x x Y x x x ", + "bullshit", + "XPMEXT ext1 data1", + "XPMEXT ext2", + "data2_1", + "data2_2", + "XPMEXT", + "foo", + "", + "XPMEXT ext3", + "data3", + "XPMENDEXT" +}; + +#define win XtWindow(topw) +#define dpy XtDisplay(topw) +#define root XRootWindowOfScreen(XtScreen(topw)) +#define xrdb XtDatabase(dpy) +static Colormap colormap; + +void Usage(void); +void ErrorMessage(int ErrorStatus, const char *tag); +void Punt(int i); +void VersionInfo(void); +void kinput(Widget widget, char *tag, XEvent *xe, Boolean *b); +void GetNumbers(int num, int *format_return, + int *libmajor_return, + char *libminor_return); + +#define IWIDTH 50 +#define IHEIGHT 50 + +typedef struct _XpmIcon { + Pixmap pixmap; + Pixmap mask; + XpmAttributes attributes; +} XpmIcon; + +static char **command; +static Widget topw; +static XpmIcon view, icon; +static XrmOptionDescRec options[] = { + {"-hints", ".hints", XrmoptionNoArg, (XtPointer) "True"}, + {"-icon", ".icon", XrmoptionSepArg, (XtPointer) NULL}, +}; + +int +main( + int argc, + char **argv) +{ + int ErrorStatus; + unsigned int verbose = 0; /* performs verbose output */ + unsigned int stdinf = 1; /* read from stdin */ + unsigned int stdoutf = 0; /* write to stdout */ + unsigned int nod = 0; /* no display */ + unsigned int nom = 0; /* no mask display */ + unsigned int incResize = 0; + unsigned int resize = 0; + unsigned int w_rtn; + unsigned int h_rtn; + char *input = NULL; + char *output = NULL; + char *iconFile = NULL; + unsigned int numsymbols = 0; + XpmColorSymbol symbols[10]; + char *stype; + XrmValue val; + unsigned long valuemask = 0; + int n; + Arg args[4]; + +#ifdef Debug + char **data; + char *buffer; +#endif + +#ifdef USE_GETTEXT + XtSetLanguageProc(NULL,NULL,NULL); + bindtextdomain("sxpm",LOCALEDIR); + textdomain("sxpm"); +#endif + + topw = XtInitialize(argv[0], "Sxpm", + options, XtNumber(options), &argc, argv); + + if (!topw) { + /* L10N_Comments : Error if no $DISPLAY or $DISPLAY can't be opened. + Not normally reached as Xt exits before we get here. */ + fprintf(stderr, gettext("Sxpm Error... [ Undefined DISPLAY ]\n")); + exit(1); + } + colormap = XDefaultColormapOfScreen(XtScreen(topw)); + + /* + * geometry management + */ + + if (XrmGetResource(xrdb, NULL, "sxpm.geometry", &stype, &val) + || XrmGetResource(xrdb, NULL, "Sxpm.geometry", &stype, &val)) { + + int flags; + int x_rtn; + int y_rtn; + char *geo = NULL; + + geo = (char *) val.addr; + flags = XParseGeometry(geo, &x_rtn, &y_rtn, + (unsigned int *) &w_rtn, + (unsigned int *) &h_rtn); + + if (!((WidthValue & flags) && (HeightValue & flags))) + resize = 1; + + } else + resize = 1; + + n = 0; + if (resize) { + w_rtn = 0; + h_rtn = 0; + XtSetArg(args[n], XtNwidth, 1); + n++; + XtSetArg(args[n], XtNheight, 1); + n++; + } + XtSetArg(args[n], XtNmappedWhenManaged, False); + n++; + XtSetArg(args[n], XtNinput, True); + n++; + XtSetValues(topw, args, n); + + if ((XrmGetResource(xrdb, "sxpm.hints", "", &stype, &val) + || XrmGetResource(xrdb, "Sxpm.hints", "", &stype, &val)) + && !strcmp((char *) val.addr, "True")) { + /* gotcha */ + incResize = 1; + resize = 1; + } + + /* + * icon management + */ + + if (XrmGetResource(xrdb, "sxpm.icon", "", &stype, &val) + || XrmGetResource(xrdb, "Sxpm.icon", "", &stype, &val)) { + iconFile = (char *) val.addr; + } + if (iconFile) { + + XColor color, junk; + Pixel bpix; + Window iconW; + + if (XAllocNamedColor(dpy, colormap, "black", &color, &junk)) + bpix = color.pixel; + else + bpix = XBlackPixelOfScreen(XtScreen(topw)); + + iconW = XCreateSimpleWindow(dpy, root, 0, 0, + IWIDTH, IHEIGHT, 1, bpix, bpix); + + icon.attributes.valuemask = XpmReturnAllocPixels; + ErrorStatus = XpmReadFileToPixmap(dpy, root, iconFile, &icon.pixmap, + &icon.mask, &icon.attributes); + ErrorMessage(ErrorStatus, "Icon"); + + XSetWindowBackgroundPixmap(dpy, iconW, icon.pixmap); + + n = 0; + XtSetArg(args[n], XtNbackground, bpix); + n++; + XtSetArg(args[n], XtNiconWindow, iconW); + n++; + XtSetValues(topw, args, n); + } + + /* + * arguments parsing + */ + + command = argv; + for (n = 1; n < argc; n++) { + if (strcmp(argv[n], "-plaid") == 0) { + stdinf = 0; + continue; + } + if (argv[n][0] != '-') { + stdinf = 0; + input = argv[n]; + continue; + } + if ((strlen(argv[n]) == 1) && (argv[n][0] == '-')) + /* stdin */ + continue; + if (strcmp(argv[n], "-o") == 0) { + if (n < argc - 1) { + if ((strlen(argv[n + 1]) == 1) && (argv[n + 1][0] == '-')) + stdoutf = 1; + else + output = argv[n + 1]; + n++; + continue; + } else + Usage(); + } + if (strcmp(argv[n], "-nod") == 0) { + nod = 1; + continue; + } + if (strcmp(argv[n], "-nom") == 0) { + nom = 1; + continue; + } + if (strcmp(argv[n], "-sc") == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols++].value = argv[++n]; + continue; + } else + Usage(); + } + if (strcmp(argv[n], "-sp") == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = argv[++n]; + symbols[numsymbols].value = NULL; + symbols[numsymbols++].pixel = atol(argv[++n]); + continue; + } + } + if (strcmp(argv[n], "-cp") == 0) { + if (n < argc - 2) { + valuemask |= XpmColorSymbols; + symbols[numsymbols].name = NULL; + symbols[numsymbols].value = argv[++n]; + symbols[numsymbols++].pixel = atol(argv[++n]); + continue; + } + } + if (strcmp(argv[n], "-mono") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_MONO; + continue; + } + if (strcmp(argv[n], "-gray4") == 0 || strcmp(argv[n], "-grey4") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_GRAY4; + continue; + } + if (strcmp(argv[n], "-gray") == 0 || strcmp(argv[n], "-grey") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_GRAY; + continue; + } + if (strcmp(argv[n], "-color") == 0) { + valuemask |= XpmColorKey; + view.attributes.color_key = XPM_COLOR; + continue; + } + if (strncmp(argv[n], "-closecolors", 6) == 0) { + valuemask |= XpmCloseness; + view.attributes.closeness = 40000; + continue; + } + if (strcmp(argv[n], "-rgb") == 0) { + if (n < argc - 1) { + valuemask |= XpmRgbFilename; + view.attributes.rgb_fname = argv[++n]; + continue; + } else + Usage(); + + } + if (strncmp(argv[n], "-version", 4) == 0) { + VersionInfo(); + exit(0); + } + if (strcmp(argv[n], "-v") == 0) { + verbose = 1; + continue; + } + if (strcmp(argv[n], "-pcmap") == 0) { + valuemask |= XpmColormap; + continue; + } + Usage(); + } + + XtRealizeWidget(topw); + if (valuemask & XpmColormap) { + colormap = XCreateColormap(dpy, win, + DefaultVisual(dpy, DefaultScreen(dpy)), + AllocNone); + view.attributes.colormap = colormap; + XSetWindowColormap(dpy, win, colormap); + } + view.attributes.colorsymbols = symbols; + view.attributes.numsymbols = numsymbols; + view.attributes.valuemask = valuemask; + +#ifdef Debug + /* this is just to test the XpmCreateDataFromPixmap function */ + + view.attributes.valuemask |= XpmReturnAllocPixels; + view.attributes.valuemask |= XpmReturnExtensions; + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Plaid"); + + ErrorStatus = XpmCreateDataFromPixmap(dpy, &data, view.pixmap, view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Data"); + if (verbose && view.attributes.nextensions) { + unsigned int i, j; + + for (i = 0; i < view.attributes.nextensions; i++) { + fprintf(stderr, "Xpm extension : %s\n", + view.attributes.extensions[i].name); + for (j = 0; j < view.attributes.extensions[i].nlines; j++) + fprintf(stderr, "\t\t%s\n", + view.attributes.extensions[i].lines[j]); + } + } + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.alloc_pixels, + view.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&view.attributes); + view.attributes.valuemask = valuemask; +#endif + + if (input || stdinf) { + view.attributes.valuemask |= XpmReturnInfos; + view.attributes.valuemask |= XpmReturnAllocPixels; + view.attributes.valuemask |= XpmReturnExtensions; + +#ifdef Debug + XpmFree(data); + + /* + * this is just to test the XpmCreatePixmapFromBuffer and + * XpmCreateBufferFromPixmap functions + */ + ErrorStatus = XpmReadFileToBuffer(input, &buffer); + ErrorMessage(ErrorStatus, "CreateBufferFromFile"); + + ErrorStatus = XpmCreatePixmapFromBuffer(dpy, win, buffer, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreatePixmapFromBuffer"); + XpmFree(buffer); + ErrorStatus = XpmCreateBufferFromPixmap(dpy, &buffer, + view.pixmap, view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreateBufferFromPixmap"); + ErrorStatus = XpmWriteFileFromBuffer("buffer_output", buffer); + ErrorMessage(ErrorStatus, "WriteFileFromBuffer"); + XpmFree(buffer); + if (view.pixmap) { + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, view.attributes.alloc_pixels, + view.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&view.attributes); + } + ErrorStatus = XpmReadFileToData(input, &data); + ErrorMessage(ErrorStatus, "ReadFileToData"); + ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "CreatePixmapFromData"); + ErrorStatus = XpmWriteFileFromData("sxpmout.xpm", data); + ErrorMessage(ErrorStatus, "WriteFileFromData"); + XpmFree(data); + XpmFreeAttributes(&view.attributes); +#endif + ErrorStatus = XpmReadFileToPixmap(dpy, win, input, + &view.pixmap, &view.mask, + &view.attributes); + ErrorMessage(ErrorStatus, "Read"); + if (verbose && view.attributes.nextensions) { + unsigned int i, j; + + for (i = 0; i < view.attributes.nextensions; i++) { + /* L10N_Comments : Output when -v & file has extensions + %s is replaced by extension name */ + fprintf(stderr, gettext("Xpm extension : %s\n"), + view.attributes.extensions[i].name); + for (j = 0; j < view.attributes.extensions[i].nlines; j++) + fprintf(stderr, "\t\t%s\n", + view.attributes.extensions[i].lines[j]); + } + } + } else { +#ifdef Debug + ErrorStatus = XpmCreatePixmapFromData(dpy, win, data, + &view.pixmap, &view.mask, + &view.attributes); + XpmFree(data); +#else + ErrorStatus = XpmCreatePixmapFromData(dpy, win, plaid, + &view.pixmap, &view.mask, + &view.attributes); +#endif + ErrorMessage(ErrorStatus, "Plaid"); + } + if (output || stdoutf) { + ErrorStatus = XpmWriteFileFromPixmap(dpy, output, view.pixmap, + view.mask, &view.attributes); + ErrorMessage(ErrorStatus, "Write"); + } + if (!nod) { + + /* + * manage display if requested + */ + + XSizeHints size_hints; + char *xString = NULL; + + if (w_rtn && h_rtn + && ((w_rtn < view.attributes.width) + || h_rtn < view.attributes.height)) { + resize = 1; + } + if (resize) { + XtResizeWidget(topw, + view.attributes.width, view.attributes.height, 1); + } + if (incResize) { + size_hints.flags = USSize | PMinSize | PResizeInc; + size_hints.height = view.attributes.height; + size_hints.width = view.attributes.width; + size_hints.height_inc = view.attributes.height; + size_hints.width_inc = view.attributes.width; + } else + size_hints.flags = PMinSize; + + size_hints.min_height = view.attributes.height; + size_hints.min_width = view.attributes.width; + XSetWMNormalHints(dpy, win, &size_hints); + + if (input) { + xString = (char *) XtMalloc((sizeof(char) * strlen(input)) + 20); + sprintf(xString, "Sxpm: %s", input); + XStoreName(dpy, win, xString); + XSetIconName(dpy, win, xString); + } else if (stdinf) { + XStoreName(dpy, win, "Sxpm: stdin"); + XSetIconName(dpy, win, "Sxpm: stdin"); + } else { + XStoreName(dpy, win, "Sxpm"); + XSetIconName(dpy, win, "Sxpm"); + } + + XtAddEventHandler(topw, KeyPressMask, False, + (XtEventHandler) kinput, NULL); + XSetWindowBackgroundPixmap(dpy, win, view.pixmap); + + if (view.mask && !nom) + XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, + view.mask, ShapeSet); + + XClearWindow(dpy, win); + XtMapWidget(topw); + if (xString) + XtFree(xString); + XtMainLoop(); + } + Punt(0); + + /* Muffle gcc */ + return 0; +} + +void +Usage(void) +{ + /* L10N_Comments : Usage message (sxpm -h) in two parts. + In the first part %s is replaced by the command name. */ + fprintf(stderr, gettext("\nUsage: %s [options...]\n"), command[0]); + fprintf(stderr, gettext("Where options are:\n\ +\n\ +[-d host:display] Display to connect to.\n\ +[-g geom] Geometry of window.\n\ +[-hints] Set ResizeInc for window.\n\ +[-icon filename] Set pixmap for iconWindow.\n\ +[-plaid] Read the included plaid pixmap.\n\ +[filename] Read from file 'filename', and from standard\n\ + input if 'filename' is '-'.\n\ +[-o filename] Write to file 'filename', and to standard\n\ + output if 'filename' is '-'.\n\ +[-pcmap] Use a private colormap.\n\ +[-closecolors] Try to use `close' colors.\n\ +[-nod] Don't display in window.\n\ +[-nom] Don't use clip mask if any.\n\ +[-mono] Use the colors specified for a monochrome visual.\n\ +[-grey4] Use the colors specified for a 4 greyscale visual.\n\ +[-grey] Use the colors specified for a greyscale visual.\n\ +[-color] Use the colors specified for a color visual.\n\ +[-sc symbol color] Override color defaults.\n\ +[-sp symbol pixel] Override color defaults.\n\ +[-cp color pixel] Override color defaults.\n\ +[-rgb filename] Search color names in the rgb text file 'filename'.\n\ +[-v] Verbose - print out extensions.\n\ +[-version] Print out program's version number\n\ + and library's version number if different.\n\ +if no input is specified sxpm reads from standard input.\n\ +\n")); + exit(0); +} + + +void +ErrorMessage( + int ErrorStatus, + const char *tag) +{ + char *error = NULL; + char *warning = NULL; + + switch (ErrorStatus) { + case XpmSuccess: + return; + case XpmColorError: +/* L10N_Comments : The following set of messages are classified as + either errors or warnings. Based on the class of message, different + wrappers are selected at the end to state the message source & class. + + L10N_Comments : WARNING produced when filename can be read, but + contains an invalid color specification (need to create test case)*/ + warning = gettext("Could not parse or alloc requested color"); + break; + case XpmOpenFailed: + /* L10N_Comments : ERROR produced when filename does not exist + or insufficient permissions to open (i.e. sxpm /no/such/file ) */ + error = gettext("Cannot open file"); + break; + case XpmFileInvalid: + /* L10N_Comments : ERROR produced when filename can be read, but + is not an XPM file (i.e. sxpm /dev/null ) */ + error = gettext("Invalid XPM file"); + break; + case XpmNoMemory: + /* L10N_Comments : ERROR produced when filename can be read, but + is too big for memory + (i.e. limit datasize 32 ; sxpm /usr/dt/backdrops/Crochet.pm ) */ + error = gettext("Not enough memory"); + break; + case XpmColorFailed: + /* L10N_Comments : ERROR produced when filename can be read, but + contains an invalid color specification (need to create test case)*/ + error = gettext("Failed to parse or alloc some color"); + break; + } + + if (warning) + /* L10N_Comments : Wrapper around above WARNING messages. + First %s is the tag for the operation that produced the warning. + Second %s is the message selected from the above set. */ + fprintf(stderr, gettext("%s Xpm Warning: %s.\n"), tag, warning); + + if (error) { + /* L10N_Comments : Wrapper around above ERROR messages. + First %s is the tag for the operation that produced the error. + Second %s is the message selected from the above set */ + fprintf(stderr, gettext("%s Xpm Error: %s.\n"), tag, error); + Punt(1); + } +} + +void +Punt(int i) +{ + if (icon.pixmap) { + XFreePixmap(dpy, icon.pixmap); + if (icon.mask) + XFreePixmap(dpy, icon.mask); + + XFreeColors(dpy, colormap, + icon.attributes.alloc_pixels, + icon.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&icon.attributes); + } + if (view.pixmap) { + XFreePixmap(dpy, view.pixmap); + if (view.mask) + XFreePixmap(dpy, view.mask); + + XFreeColors(dpy, colormap, + view.attributes.alloc_pixels, + view.attributes.nalloc_pixels, 0); + + XpmFreeAttributes(&view.attributes); + } + exit(i); +} + +void +kinput( + Widget widget, + char *tag, + XEvent *xe, + Boolean *b) +{ + char c = '\0'; + + XLookupString(&(xe->xkey), &c, 1, NULL, NULL); + if (c == 'q' || c == 'Q') + Punt(0); +} + +/* + * small function to extract various version numbers from the given global + * number (following the rule described in xpm.h). + */ +void +GetNumbers( + int num, + int *format_return, + int *libmajor_return, + char *libminor_return) +{ + *format_return = num / 10000; + *libmajor_return = (num % 10000) / 100; + *libminor_return = 'a' + (num % 10000) % 100 - 1; +} + +void +VersionInfo(void) +{ + int format, libmajor; + char libminor; + + GetNumbers(XpmIncludeVersion, &format, &libmajor, &libminor); + /* L10N_Comments : sxpm -version output */ + fprintf(stderr, gettext("sxpm version: %d.%d%c\n"), + format, libmajor, libminor); + /* L10N_Comments : + * if we are linked to an XPM library different from the one we've been + * compiled with, print its own number too when sxpm -version is called. + */ + if (XpmIncludeVersion != XpmLibraryVersion()) { + GetNumbers(XpmLibraryVersion(), &format, &libmajor, &libminor); + fprintf(stderr, gettext("using the XPM library version: %d.%d%c\n"), + format, libmajor, libminor); + } +} diff --git a/xpm.pc.in b/xpm.pc.in new file mode 100644 index 0000000..e7be72f --- /dev/null +++ b/xpm.pc.in @@ -0,0 +1,12 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +includedir=@includedir@ + +Name: Xpm +Description: X Pixmap Library +Version: @PACKAGE_VERSION@ +Requires: x11 +Requires.private: x11 +Cflags: -I${includedir} +Libs: -L${libdir} -lXpm -- 2.7.4