Git init
authorKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:49:10 +0000 (00:49 +0900)
committerKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:49:10 +0000 (00:49 +0900)
66 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0755]
INSTALL [new file with mode: 0755]
Makefile.am [new file with mode: 0755]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0755]
debian/README.source [new file with mode: 0644]
debian/changelog [new file with mode: 0755]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0644]
debian/libxcursor-dev.install [new file with mode: 0755]
debian/libxcursor-dev.manpages [new file with mode: 0755]
debian/libxcursor1-udeb.install [new file with mode: 0644]
debian/libxcursor1.install [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/watch [new file with mode: 0644]
debian/xsfbs/repack.sh [new file with mode: 0644]
debian/xsfbs/xsfbs.mk [new file with mode: 0644]
debian/xsfbs/xsfbs.sh [new file with mode: 0644]
include/X11/Xcursor/Xcursor.h [new file with mode: 0644]
man/Makefile.am [new file with mode: 0644]
man/Xcursor.man [new file with mode: 0644]
man/XcursorCursorsCreate.man [new file with mode: 0755]
man/XcursorCursorsDestroy.man [new file with mode: 0755]
man/XcursorFilenameLoad.man [new file with mode: 0755]
man/XcursorFilenameLoadAllImages.man [new file with mode: 0755]
man/XcursorFilenameLoadCursor.man [new file with mode: 0755]
man/XcursorFilenameLoadImage.man [new file with mode: 0755]
man/XcursorFilenameLoadImages.man [new file with mode: 0755]
man/XcursorFilenameSave.man [new file with mode: 0755]
man/XcursorFilenameSaveImages.man [new file with mode: 0755]
man/XcursorGetDefaultSize.man [new file with mode: 0755]
man/XcursorGetTheme.man [new file with mode: 0755]
man/XcursorImageCreate.man [new file with mode: 0755]
man/XcursorImageDestroy.man [new file with mode: 0755]
man/XcursorImagesCreate.man [new file with mode: 0755]
man/XcursorImagesDestroy.man [new file with mode: 0755]
man/XcursorLibraryLoadCursor.man [new file with mode: 0755]
man/XcursorLibraryLoadCursors.man [new file with mode: 0755]
man/XcursorLibraryLoadImage.man [new file with mode: 0755]
man/XcursorLibraryLoadImages.man [new file with mode: 0755]
man/XcursorSetDefaultSize.man [new file with mode: 0755]
man/XcursorSetTheme.man [new file with mode: 0755]
man/XcursorShapeLoadCursor.man [new file with mode: 0755]
man/XcursorShapeLoadCursors.man [new file with mode: 0755]
man/XcursorShapeLoadImage.man [new file with mode: 0755]
man/XcursorShapeLoadImages.man [new file with mode: 0755]
man/XcursorSupportsARGB.man [new file with mode: 0755]
man/XcursorXcFileLoad.man [new file with mode: 0755]
man/XcursorXcFileLoadAllImages.man [new file with mode: 0755]
man/XcursorXcFileLoadImage.man [new file with mode: 0755]
man/XcursorXcFileLoadImages.man [new file with mode: 0755]
man/XcursorXcFileSave.man [new file with mode: 0755]
packaging/libXcursor.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0755]
src/cursor.c [new file with mode: 0644]
src/display.c [new file with mode: 0644]
src/file.c [new file with mode: 0644]
src/library.c [new file with mode: 0644]
src/xcursorint.h [new file with mode: 0644]
src/xlib.c [new file with mode: 0644]
xcursor.pc.in [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..57c4efd
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Keith Packard, HP
+
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..8d01a81
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,19 @@
+Copyright © 2002 Keith Packard
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name of Keith Packard not be used in
+advertising or publicity pertaining to distribution of the software without
+specific, written prior permission.  Keith Packard makes no
+representations about the suitability of this software for any purpose.  It
+is provided "as is" without express or implied warranty.
+
+KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/ChangeLog b/ChangeLog
new file mode 100755 (executable)
index 0000000..0dd5ca2
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,593 @@
+commit 731e84d79e83b59d022d0f453b245696b4d2750f
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date:   Wed Oct 27 22:48:19 2010 -0700
+
+    libXcursor 1.1.11
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 42b7717c32b3c7097180667a9ba2f62e40fc6506
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Aug 16 19:28:57 2010 -0400
+
+    man: whitespace management
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 862bc06d58152e74e85fc29db7eaec06af20e00b
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Aug 16 19:25:25 2010 -0400
+
+    man: reorder makefile statements
+    
+    No functional change. Shadows are part of libman_PRE.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit b18568dd5b5a11ae49cad66a54ec50465c6ffa77
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Aug 16 19:17:21 2010 -0400
+
+    man: store shadow man pages in git rather than generating them
+    
+    Simplify the build process and the makefile.
+    
+    Local fix in CVS for bug 5628 is not required
+    as the problem has been fixed in
+    util-macros d9062e4077ebfd0985baf8418f3d0f111b9ddbba
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 68d830bcf67632b474c8996b6a2c9bcde8e27f97
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Aug 16 19:05:35 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.
+    
+    Use AC_PROG_SED now supplied by XORG_DEFAULT_OPTIONS
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 0caadca51ca56a2ae2cfe67cbd2b29e89b6a68d8
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Mar 29 16:50:33 2010 -0400
+
+    config: update AC_PREREQ statement to 2.60
+    
+    Unrelated to the previous patches, the new value simply reflects
+    the reality that the minimum level for autoconf to configure
+    all x.org modules is 2.60 dated June 2006.
+    
+    ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit b511b260ddcec34035c1d97285f27f3182663a6a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Mar 29 14:53:48 2010 -0400
+
+    config: remove the pkgconfig pc.in file from EXTRA_DIST
+    
+    Automake always includes it in the tarball.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit a3e03bb23bf7a92bf20d51eebe692e0a4f667065
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Feb 16 10:37:21 2010 -0500
+
+    config: move CWARNFLAGS from configure.ac to Makefile.am
+    
+    Compiler warning flags should be explicitly set in the makefile
+    rather than being merged with other packages compiler flags.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 8198d1490959d49573790405e205a471ac7a5b98
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Nov 27 20:56:04 2009 -0500
+
+    Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES
+    
+    Now that the INSTALL file is generated.
+    Allows running make maintainer-clean.
+
+commit ecddb70049a1e79b88d4d647f7e944237055fa2e
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Oct 28 14:09:10 2009 -0400
+
+    INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206
+    
+    Add missing INSTALL file. Use standard GNU file on building tarball
+    README may have been updated
+    Remove AUTHORS file as it is empty and no content available yet.
+    Remove NEWS file as it is empty and no content available yet.
+
+commit 02cd3d7a617c71dbc13023f91f41b896dc260c50
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Oct 27 15:07:25 2009 -0400
+
+    Deploy the new XORG_DEFAULT_OPTIONS #24242
+    
+    This macro aggregate a number of existing macros that sets commmon
+    X.Org components configuration options. It shields the configuration file from
+    future changes.
+
+commit 1ca6aefa6690930b336490525f5ed515ddad26ac
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Oct 26 22:08:42 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 1c158db62ad2c7584d88e840f3c7fe151de84150
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 22 12:34:19 2009 -0400
+
+    .gitignore: use common defaults with custom section # 24239
+    
+    Using common defaults will reduce errors and maintenance.
+    Only the very small or inexistent custom section need periodic maintenance
+    when the structure of the component changes. Do not edit defaults.
+
+commit 5e14cd9bd8a8f9266ecaa69d58c15d8e298d8a78
+Author: Jeremy Huddleston <jeremyhu@freedesktop.org>
+Date:   Wed Oct 21 12:47:24 2009 -0700
+
+    This is not a GNU project, so declare it foreign.
+    
+    On Wed, 2009-10-21 at 13:36 +1000, Peter Hutterer wrote:
+    > On Tue, Oct 20, 2009 at 08:23:55PM -0700, Jeremy Huddleston wrote:
+    > > I noticed an INSTALL file in xlsclients and libXvMC today, and it
+    > > was quite annoying to work around since 'autoreconf -fvi' replaces
+    > > it and git wants to commit it.  Should these files even be in git?
+    > > Can I nuke them for the betterment of humanity and since they get
+    > > created by autoreconf anyways?
+    >
+    > See https://bugs.freedesktop.org/show_bug.cgi?id=24206
+    
+    As an interim measure, replace AM_INIT_AUTOMAKE([dist-bzip2]) with
+    AM_INIT_AUTOMAKE([foreign dist-bzip2]). This will prevent the generation
+    of the INSTALL file. It is also part of the 24206 solution.
+    
+    Signed-off-by: Jeremy Huddleston <jeremyhu@freedesktop.org>
+
+commit fbf229879370a96a070ebf087426f6f6c0dbe5a2
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Aug 28 14:49:15 2009 +1000
+
+    libXcursor 1.1.10
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 59e3f6520f4d1682d3242d1d5656e7972cf11944
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Feb 2 20:34:32 2009 -0800
+
+    Add README with pointers to mailing list, bugzilla & git repos
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit f00ae32322d2b3c5d97724b80c72d3e2d0812935
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Thu Jan 29 15:34:11 2009 -0200
+
+    Janitor: make distcheck, compiler warnings, extra .gitignore files.
+
+commit 04641d3cc3e2f7389c5a3ea6e1d55543e033153f
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Mar 9 00:34:36 2008 +0100
+
+    nuke RCS Ids
+
+commit 94531dc8f6eff9c9f5cbb18ca6b3d4ff79eec752
+Author: James Cloos <cloos@jhcloos.com>
+Date:   Thu Dec 6 16:38:25 2007 -0500
+
+    Replace static ChangeLog with dist-hook to generate from git log
+
+commit a4f29e6deef2bf46cae811aaac1f535945cd9fee
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Aug 24 14:01:07 2007 -0700
+
+    Version bump: 1.1.9
+
+commit 5a2601740d04d4180e77695c4b60f2cf5c84be6c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Wed Aug 22 19:40:55 2007 -0700
+
+    Make shadow man pages for each function
+
+commit fef474da694ea3c1fd184d93cc07bf8d95f89327
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Aug 21 19:45:35 2007 -0700
+
+    Add XCURSOR_PATH to man page
+
+commit a9ccf1bd91ad6e06f7b7116efe836c365b68645b
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Aug 21 19:33:00 2007 -0700
+
+    Use cursorpath found by configure in man page
+
+commit 110131bd40d0fc042f4a81922372307a1582b591
+Author: Tilman Sauerbeck <tilman@code-monkey.de>
+Date:   Sat May 12 22:42:08 2007 +0200
+
+    Added object files to .gitignore.
+
+commit 3c5d4f591ce0b473af9f693cfe25a1506cc573d6
+Author: Tilman Sauerbeck <tilman@code-monkey.de>
+Date:   Sat May 12 22:41:27 2007 +0200
+
+    Store the cursor names in one large string.
+    
+    This means the compiler doesn't need to place the array in the
+    read-write sections of the DSO, which means less relocations
+    when the library is loaded and a smaller memory footprint.
+
+commit 8b73dc04111c1910a6467417133a44d0aa29c6ac
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Fri Oct 13 16:01:17 2006 -0400
+
+    Bump to 1.1.8
+
+commit 9df9640643fae7b922b18ee219d6d9694345df14
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Oct 10 14:57:16 2006 -0700
+
+    Fix many sparse warnings: Using plain integer as NULL pointer
+
+commit b6b9f5885566e4c2df8e3319fe092c22f319983f
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Oct 10 13:46:17 2006 -0700
+
+    Fix lint warning: deallocating a pointer that could be NULL: library.c(266)
+
+commit d0e12a97849871b0b2af04bf8d7a3839c54b31a8
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Oct 10 13:33:33 2006 -0700
+
+    Add XORG_WITH_LINT to allow checking code with lint/sparse/etc.
+
+commit 932965298c244553f303fab3bdf23941cc40bb23
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Oct 6 16:44:37 2006 -0700
+
+    Use $prefix & $ICONDIR settings from configure for default path in manpage
+    
+    (Stop hardcoding /usr/X11R6 & /usr/share in the paths shown.)
+
+commit f591196271e53c64e27cf41e5b6ae844a480cb3d
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Fri Oct 6 16:22:52 2006 -0700
+
+    Xcursor.man formatting cleanups
+
+commit 3c5f5860d6f85230f417ce6af30fc73ab75c437b
+Author: Bart Massey <bart@po8.org>
+Date:   Tue Sep 12 09:02:54 2006 -0700
+
+    Added missing dependency
+
+commit c7d048dacf3fce6f3121cf0114fd08bb130130b8
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Aug 24 19:21:47 2006 -0700
+
+    Use version number from configure.ac in Xcursor.man instead of "Version 1.0"
+
+commit 8c73ee726016dae6f56195d44339b4729121bcf2
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Aug 24 18:42:36 2006 -0700
+
+    Add *~ to .gitignore to skip over emacs droppings
+
+commit c7886900f180da2c460d0a5926daee787e7258ea
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Aug 24 18:42:03 2006 -0700
+
+    Man page typo fixes (pimaps, directorys)
+
+commit e0a501e91c270c0e99a55aa568f6df0d3d6e541d
+Author: Chris Wilson <cpwilson@taz.qinetiq.com>
+Date:   Sat Aug 12 19:55:44 2006 +0300
+
+    fix leak in header destruction
+    Fix a couple of if (!foo) free(foo); tests.
+
+commit 2f08984396552c0719fbc3d3e1148157a1423376
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Jul 13 14:58:50 2006 -0700
+
+    renamed: .cvsignore -> .gitignore
+
+commit c6f65af419d14a753459a71a671baafd84fa1330
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Jun 3 10:23:57 2006 +0000
+
+    Bug #5268: Fix small memory leak. (Matthias Clasen). Change some return 0s
+        to NULL. Bump to 1.1.7.
+
+commit 8adc6fe181991af8befb0f365360e9a68357da29
+Author: Eric Anholt <anholt@freebsd.org>
+Date:   Thu Apr 27 17:26:28 2006 +0000
+
+    Look for cursors in datadir, not always /usr/share.
+
+commit 3c69a6ef12aa43d5c9cc5cfbd76c6bea1fa2bd00
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Thu Apr 27 00:04:48 2006 +0000
+
+    Bump to 1.1.6
+
+commit f9bc007d71f58db93b7eadeb8c77d0f90379c620
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Fri Apr 7 00:58:59 2006 +0000
+
+    Coverity #159: Prevent a possible NULL chase.
+
+commit 1f862e619f12b54bee2efbb66f77c750184b191f
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Mar 4 21:00:40 2006 +0000
+
+    Bug #4439: Include Xlib.h.
+
+commit 461b3c5c0e47eed1b4abf5189ba92bb70d700fa1
+Author: Kevin E Martin <kem@kem.org>
+Date:   Thu Dec 15 00:24:29 2005 +0000
+
+    Update package version number for final X11R7 release candidate.
+
+commit aed42762a9fcfcf1b7729dc0a7014ea679d309eb
+Author: Kevin E Martin <kem@kem.org>
+Date:   Fri Dec 9 19:28:41 2005 +0000
+
+    Add icondir to xcursor.pc to be used when installing cursors.
+
+commit 189c9672264c4b62f18f9da9422375b216dc7037
+Author: Kevin E Martin <kem@kem.org>
+Date:   Thu Dec 8 17:55:19 2005 +0000
+
+    Add configure options to allow hard-coded paths to be changed.
+
+commit b8c92a26d01b14cb9d27cd30d261e24833d0c728
+Author: Kevin E Martin <kem@kem.org>
+Date:   Thu Dec 8 17:54:40 2005 +0000
+
+    Allow hard-coded paths to be configurable.
+
+commit af09e8d8edb7d68367399336ca3163df4c713ffa
+Author: Kevin E Martin <kem@kem.org>
+Date:   Tue Dec 6 22:48:42 2005 +0000
+
+    Change *man_SOURCES ==> *man_PRE to fix autotools warnings.
+
+commit 47043f5e93df6a806bf298eca309e05159c271df
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Dec 3 05:49:43 2005 +0000
+
+    Update package version number for X11R7 RC3 release.
+
+commit a3ddd7c6aa895dd373a73957f0b18181d7f8f486
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Mon Nov 28 22:03:05 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 328e88110f43b18268c1fde62e9ce7247a797699
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Nov 19 07:15:41 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 54d9a60a1891c1c1938db00d835b8fe0a12327c6
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sun Nov 13 17:59:28 2005 +0000
+
+    Use $(LIB_MAN_SUFFIX) instead of forcing man page into section 3.
+
+commit f0dfdfc7b4ee020ffb83a9179b9d4d4a6139b5e1
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Nov 9 21:31:19 2005 +0000
+
+    Bump version numbers for X11R6.9/X11R7 RC2.
+
+commit c0773eea4b50162ae0b9b624a46079e71b8e49c2
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Nov 9 21:19:12 2005 +0000
+
+    Update package version number for X11R7 RC2 release.
+
+commit 345cf369206f0a2a03e842a108bd8f068da36d3f
+Author: Kevin E Martin <kem@kem.org>
+Date:   Tue Nov 1 15:11:51 2005 +0000
+
+    Update pkgcheck dependencies to work with separate build roots.
+
+commit 7c7bdccde9d2208a9330099e3cd21060c60638be
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Wed Oct 19 22:26:55 2005 +0000
+
+    Bug #4244: Make XcursorSetTheme(dpy, NULL) restore the default theme.
+        (Frederico Mena-Quintero)
+
+commit 4d4de72c697217ac155231d1761db065c9a778ee
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Oct 19 02:48:09 2005 +0000
+
+    Update package version number for RC1 release.
+
+commit b1bc7d7328ff2741e1c13151799422fee9e6d0cd
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Thu Oct 13 02:22:47 2005 +0000
+
+    Use troff macros to prevent cpp eating C comments & #defines that are
+        supposed to appear in man page output.
+
+commit 08ccddfa98d3e4daa9993a206ec0fa3cf9329cd1
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Tue Oct 11 01:37:44 2005 +0000
+
+    Define HAVE_XFIXES
+
+commit 7a5e36017905a3b7fe70362dc9712654c816c6a5
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Wed Aug 3 03:28:01 2005 +0000
+
+    Do PKG_CHECK_MODULES on a unique token instead of on "DEP", so builds with
+        a global configure cache don't get confused.
+
+commit af4b88bba232af55484e8b82ce8abab6013e985e
+Author: Kevin E Martin <kem@kem.org>
+Date:   Fri Jul 29 21:22:51 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 b34368c667bd47db56bc7e2b36710a22bc3862b0
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Jul 16 06:35:32 2005 +0000
+
+    Change soversion to 1.0.2 with -version-number.
+
+commit 9ffefcd641352900f9bf7cb06cbe04e91714b490
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 06:13:36 2005 +0000
+
+    Add .cvsignore files Switch _la_CFLAGS for AM_CFLAGS to clean up directory
+
+commit b5a724c201e0881fcb22738560597e333c39ba12
+Author: Keith Packard <keithp@keithp.com>
+Date:   Fri Jul 8 05:02:01 2005 +0000
+
+    Make sure XFIXES appears in LIBS line, fix up other pkg-config usage.
+
+commit 45b0f06f132347e5eaabbc5ff294bc9016de75dd
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sun Jul 3 07:00:56 2005 +0000
+
+    Add Xtrans definitions (FONT_t, TRANS_CLIENT) to clean up warnings.
+    Add XSERV_t, TRANS_SERVER, TRANS_REOPEN to quash warnings.
+    Add #include <dix-config.h> or <xorg-config.h>, as appropriate, to all
+        source files in the xserver/xorg tree, predicated on defines of
+        HAVE_{DIX,XORG}_CONFIG_H. Change all Xfont includes to
+        <X11/fonts/foo.h>.
+
+commit c010a3f076b2f93e2baf4a9472bf5f132266d2db
+Author: Eric Anholt <anholt@freebsd.org>
+Date:   Sun Jul 3 00:02:27 2005 +0000
+
+    There are no manpages in this directory, so don't try to include them in
+        EXTRA_DIST. Should fix the build.
+    Reported by: tinderbox
+
+commit 0881bb3ce0ea793e279fcc8ddd16de6ed7e17471
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Jul 2 06:35:03 2005 +0000
+
+    Add appropriate lib*_CFLAGS to Makefile.am's -- fixes build problems
+
+commit caa910e492e4d15208f3d179021687c25a84f36e
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Wed Jun 29 18:46:53 2005 +0000
+
+    Import Xcursor 1.1.4 from freedesktop.org xlibs tree.
+
+commit e67de73f5ca7ae854c18fa1500c8eaf412b44c6c
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Mon Jun 13 16:44:53 2005 +0000
+
+    Bug #1043: Fix leak when creating animated cursors.
+
+commit 89e52cde6eaf5e2d46198ee2fa16b67ef7e1dd32
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Wed Jun 8 20:51:37 2005 +0000
+
+    Remove experiment with calling the man page file 4x
+
+commit 5589b4f6a36f2c039adc81fa4d406574eeef35b3
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Wed Jun 8 20:44:18 2005 +0000
+
+    Remove all the not found with pkgconfig stuff
+
+commit 4070c0af6c7bfe12218181d56e8e3cbb86006d27
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Wed Jun 8 19:15:43 2005 +0000
+
+    - Add Xcursor build system
+
+commit 50911b052ce90d41cd0ae71f83352ffa45e7c0a4
+Author: Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
+Date:   Sat Dec 4 00:42:47 2004 +0000
+
+    Encoding of numerous files changed to UTF-8
+
+commit cbcf471d9157c88a506cd3f067253c8e64cb8e08
+Author: Egbert Eich <eich@suse.de>
+Date:   Fri Apr 23 18:43:40 2004 +0000
+
+    Merging XORG-CURRENT into trunk
+
+commit fb1739bd2272fa45d9c04fe40517468a49660b37
+Author: Egbert Eich <eich@suse.de>
+Date:   Sun Mar 14 08:32:05 2004 +0000
+
+    Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004
+
+commit bfcfbe061fb492f58ee6bd6dc6e90cedd1cccbbb
+Author: Egbert Eich <eich@suse.de>
+Date:   Wed Mar 3 12:11:23 2004 +0000
+
+    Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004
+
+commit c450b7450372fa2f6660dafcbd3fb7cec9e046df
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 13:35:32 2004 +0000
+
+    readding XFree86's cvs IDs
+
+commit 79b8e8b996311665ae1fc8fa7e7d38270b3d9570
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 09:22:42 2004 +0000
+
+    Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
+
+commit b39c8ec34b4464f78db534355541a4eb5688a999
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Thu Dec 4 22:02:56 2003 +0000
+
+    XFree86 4.3.99.901 (RC 1)
+
+commit 969878fc6fed5e43b4f7e2e3ee46835d93d30dfd
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Tue Nov 25 19:28:09 2003 +0000
+
+    XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks
+
+commit 8387908965317cc3cf2072187c20f617609a13b7
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:48 2003 +0000
+
+    XFree86 4.3.0.1
+
+commit 3b84b14bf06840d5cd446f2aba495108d23d66d7
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:48 2003 +0000
+
+    Initial revision
diff --git a/INSTALL b/INSTALL
new file mode 100755 (executable)
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 `<wchar.h>' 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 100755 (executable)
index 0000000..976151e
--- /dev/null
@@ -0,0 +1,45 @@
+# 
+#  Copyright © 2003 Keith Packard, Noah Levitt
+# 
+#  Permission to use, copy, modify, distribute, and sell this software and its
+#  documentation for any purpose is hereby granted without fee, provided that
+#  the above copyright notice appear in all copies and that both that
+#  copyright notice and this permission notice appear in supporting
+#  documentation, and that the name of Keith Packard not be used in
+#  advertising or publicity pertaining to distribution of the software without
+#  specific, written prior permission.  Keith Packard makes no
+#  representations about the suitability of this software for any purpose.  It
+#  is provided "as is" without express or implied warranty.
+# 
+#  KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+#  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+#  EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+#  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+#  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+#  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+#  PERFORMANCE OF THIS SOFTWARE.
+
+SUBDIRS = src man
+
+AM_CFLAGS = $(XRENDER_CFLAGS) $(XFIXES_CFLAGS) $(X_CFLAGS)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = xcursor.pc
+
+MAINTAINERCLEANFILES = ChangeLog INSTALL
+
+if LINT
+lint:
+       (cd src && $(MAKE) $(MFLAGS) lint)
+endif LINT
+
+
+.PHONY: ChangeLog INSTALL
+
+INSTALL:
+       $(INSTALL_CMD)
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog INSTALL
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..a60d8fe
--- /dev/null
+++ b/README
@@ -0,0 +1,25 @@
+libXcursor - X Window System Cursor management 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/libXcursor
+
+        http://cgit.freedesktop.org/xorg/lib/libXcursor
+
+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/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..218197d
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+#$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..185303f
--- /dev/null
@@ -0,0 +1,80 @@
+dnl 
+dnl  Copyright © 2003 Keith Packard
+dnl 
+dnl  Permission to use, copy, modify, distribute, and sell this software and its
+dnl  documentation for any purpose is hereby granted without fee, provided that
+dnl  the above copyright notice appear in all copies and that both that
+dnl  copyright notice and this permission notice appear in supporting
+dnl  documentation, and that the name of Keith Packard not be used in
+dnl  advertising or publicity pertaining to distribution of the software without
+dnl  specific, written prior permission.  Keith Packard makes no
+dnl  representations about the suitability of this software for any purpose.  It
+dnl  is provided "as is" without express or implied warranty.
+dnl 
+dnl  KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+dnl  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+dnl  EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+dnl  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+dnl  DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+dnl  TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+dnl  PERFORMANCE OF THIS SOFTWARE.
+dnl
+dnl Process this file with autoconf to create configure.
+
+AC_PREREQ([2.60])
+dnl
+dnl This is the package version number, not the shared library
+dnl version.  This same version number must appear in Xcursor.h
+dnl Yes, it is a pain to synchronize version numbers.  Unfortunately, it's
+dnl not possible to extract the version number here from Xcursor.h
+dnl
+AC_INIT([libXcursor], [1.1.11],
+        [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],[libXcursor])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_MAINTAINER_MODE
+AM_CONFIG_HEADER(config.h)
+
+# 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
+
+# Check for progs
+AC_PROG_CC
+AC_PROG_LIBTOOL
+
+AC_ARG_WITH(icondir,
+        AC_HELP_STRING([--with-icondir=<path>],
+                       [Set default icon directory (default: ${datadir}/icons)]),
+        [ICONDIR="$withval"],
+        [ICONDIR=${datadir}/icons])
+AC_SUBST([ICONDIR])
+
+DEF_CURSORPATH="~/.icons:${datadir}/icons:${datadir}/pixmaps"
+if test "x${ICONDIR}" != "x${datadir}/icons"; then
+       DEF_CURSORPATH="${DEF_CURSORPATH}:${ICONDIR}"
+fi
+AC_ARG_WITH(cursorpath,
+        AC_HELP_STRING([--with-cursorpath=<paths>],
+                       [Set default search path for cursors]),
+        [XCURSORPATH="$withval"],
+        [XCURSORPATH=$DEF_CURSORPATH])
+AC_SUBST([XCURSORPATH])
+
+# Reformat cursor path for man page
+XCURSORPATH_LIST=`echo $XCURSORPATH | sed 's/:/, /g'`
+AC_SUBST([XCURSORPATH_LIST])
+
+# Check for X
+PKG_CHECK_MODULES(XCURSOR, xrender >= 0.8.2 xfixes x11 fixesproto)
+AC_DEFINE(HAVE_XFIXES, 1, [Define to 1 if you have Xfixes])
+
+dnl Allow checking code with lint, sparse, etc.
+XORG_WITH_LINT
+
+AC_OUTPUT([Makefile
+          src/Makefile
+          man/Makefile
+           xcursor.pc])
diff --git a/debian/README.source b/debian/README.source
new file mode 100644 (file)
index 0000000..34ab4bf
--- /dev/null
@@ -0,0 +1,73 @@
+------------------------------------------------------
+Quick Guide To Patching This Package For The Impatient
+------------------------------------------------------
+
+1. Make sure you have quilt installed
+2. Unpack the package as usual with "dpkg-source -x"
+3. Run the "patch" target in debian/rules
+4. Create a new patch with "quilt new" (see quilt(1))
+5. Edit all the files you want to include in the patch with "quilt edit" 
+   (see quilt(1)).
+6. Write the patch with "quilt refresh" (see quilt(1))
+7. Run the "clean" target in debian/rules
+
+Alternatively, instead of using quilt directly, you can drop the patch in to 
+debian/patches and add the name of the patch to debian/patches/series.
+
+------------------------------------
+Guide To The X Strike Force Packages
+------------------------------------
+
+The X Strike Force team maintains X packages in git repositories on
+git.debian.org in the pkg-xorg subdirectory. Most upstream packages
+are actually maintained in git repositories as well, so they often
+just need to be pulled into git.debian.org in a "upstream-*" branch.
+Otherwise, the upstream sources are manually installed in the Debian
+git repository.
+
+The .orig.tar.gz upstream source file could be generated this
+"upstream-*" branch in the Debian git repository but it is actually
+copied from upstream tarballs directly.
+
+Due to X.org being highly modular, packaging all X.org applications
+as their own independent packages would have created too many Debian
+packages. For this reason, some X.org applications have been grouped
+into larger packages: xutils, xutils-dev, x11-apps, x11-session-utils,
+x11-utils, x11-xfs-utils, x11-xkb-utils, x11-xserver-utils.
+Most packages, including the X.org server itself and all libraries
+and drivers are, however maintained independently.
+
+The Debian packaging is added by creating the "debian-*" git branch
+which contains the aforementioned "upstream-*" branch plus the debian/
+repository files.
+When a patch has to be applied to the Debian package, two solutions
+are involved:
+* If the patch is available in one of the upstream branches, it
+  may be git'cherry-picked into the Debian repository. In this
+  case, it appears directly in the .diff.gz.
+* Otherwise, the patch is added to debian/patches/ which is managed
+  with quilt as documented in /usr/share/doc/quilt/README.source.
+
+quilt is actually invoked by the Debian X packaging through a larger
+set of scripts called XSFBS. XSFBS brings some other X specific
+features such as managing dependencies and conflicts due to the video
+and input driver ABIs.
+XSFBS itself is maintained in a separate repository at
+  git://git.debian.org/pkg-xorg/xsfbs.git
+and it is pulled inside the other Debian X repositories when needed.
+
+The XSFBS patching system requires a build dependency on quilt. Also
+a dependency on $(STAMP_DIR)/patch has to be added to debian/rules
+so that the XSFBS patching occurs before the actual build. So the
+very first target of the build (likely the one running autoreconf)
+should depend on $(STAMP_DIR)/patch. It should also not depend on
+anything so that parallel builds are correctly supported (nothing
+should probably run while patching is being done). And finally, the
+clean target should depend on the xsfclean target so that patches
+are unapplied on clean.
+
+When the upstream sources contain some DFSG-nonfree files, they are
+listed in text files in debian/prune/ in the "debian-*" branch of
+the Debian repository. XSFBS' scripts then take care of removing
+these listed files during the build so as to generate a modified
+DFSG-free .orig.tar.gz tarball.
diff --git a/debian/changelog b/debian/changelog
new file mode 100755 (executable)
index 0000000..3476c8d
--- /dev/null
@@ -0,0 +1,386 @@
+libxcursor (1:1.1.11-1slp2) unstable; urgency=low
+
+  * [X11R7.6] upgrade package
+  * Git: 165.213.180.234:slp/pkgs/xorg/lib/libxcursor
+  * Tag: libxcursor_1.1.11-1slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Tue, 04 Jan 2011 10:44:23 +0900
+
+libxcursor (1:1.1.10-2) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * Rename the build directory to not include DEB_BUILD_GNU_TYPE for no
+    good reason.  Thanks, Colin Watson!
+  * Remove myself from Uploaders
+
+  [ Cyril Brulebois ]
+  * Add udeb needed for the graphical installer: libxcursor1-udeb.
+  * Version/Bump some B-D to make sure the udeb gets its dependencies on
+    the (recently-added) udebs rather than on the libraries:
+     - libx11-dev
+     - libxfixes-dev
+     - libxrender-dev
+  * Bump Standards-Version from 3.8.3 to 3.8.4 (no changes needed).
+  * Add myself to Uploaders.
+  * Add ${misc:Depends} to non-udeb binaries, and wrap Depends.
+
+ -- Cyril Brulebois <kibi@debian.org>  Thu, 11 Mar 2010 05:05:33 +0100
+
+libxcursor (1:1.1.10-1) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * Drop the -1 debian revisions from build-depends.
+  * Bump Standards-Version to 3.7.3.
+  * Drop the XS- prefix from Vcs-* control fields.
+  * Remove /usr/X11R6/lib/X11/icons from the cursor path (closes: #557292).
+  * Kill vim modeline from debian changelog, it makes lintian angry.
+
+  [ Brice Goglin ]
+  * Add README.source, bump Standards-Version to 3.8.2.
+  * Use updated xsfbs, closes: #538582.
+  * Move -dbg package to section debug.
+
+  [ Timo Aaltonen ]
+  * New upstream release (closes: #554238).
+  * Run autoreconf on build. Add build-deps on automake, libtool
+    and xutils-dev.
+  * Parse space-separated DEB_BUILD_OPTIONS, and handle parallel=N.
+  * Bump Standards-Version to 3.8.3.
+  * Drop pre-dependency on x11-common from libxcursor-dev. This was needed
+    for upgrades from sarge.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 25 Nov 2009 15:30:10 +0100
+
+libxcursor (1:1.1.9-1) unstable; urgency=low
+
+  * New upstream release.
+  * Update URL in debian/copyright.
+  * Add myself to Uploaders, and remove ISHIKAWA Mutsumi and Branden.
+  * Replace deprecated Source-Version with binary:Version.
+
+ -- Julien Cristau <jcristau@debian.org>  Sat, 25 Aug 2007 11:37:23 +0200
+
+libxcursor (1:1.1.8-2) unstable; urgency=low
+
+  * Upload to unstable.
+  * Add XS-Vcs-Browser to debian/control.
+
+ -- Julien Cristau <jcristau@debian.org>  Wed, 11 Apr 2007 12:39:57 +0200
+
+libxcursor (1:1.1.8-1) experimental; urgency=low
+
+  * New upstream release.
+    + drop patch applied upstream.
+  * Add XS-Vcs-Git in debian/control.
+
+ -- Julien Cristau <jcristau@debian.org>  Tue, 13 Feb 2007 10:07:38 +0100
+
+libxcursor (1.1.7-4) unstable; urgency=low
+
+  * Pull leak fixes from upstream (01_leak_fixes.diff)
+
+ -- David Nusinow <dnusinow@debian.org>  Wed, 30 Aug 2006 16:41:34 -0400
+
+libxcursor (1.1.7-3) unstable; urgency=low
+
+  * Recompile for unstable's libxfixes3 3.0.1.
+
+ -- Drew Parsons <dparsons@debian.org>  Sat, 26 Aug 2006 09:31:19 +1000
+
+libxcursor (1.1.7-2) unstable; urgency=low
+
+  * Bring X11R7.1 into unstable.
+
+ -- Drew Parsons <dparsons@debian.org>  Sat, 26 Aug 2006 09:17:06 +1000
+
+libxcursor (1.1.7-1) experimental; urgency=low
+
+  * New upstream version (X11R7.1).
+  * Install man pages with dh_installman.
+  * Exclude .la and man files from dh_install.
+  * Remove libxcursor1-dbg.install. Somehow debhelper just knows where
+    to put the files (ooh, spooky).
+
+ -- Drew Parsons <dparsons@debian.org>  Sat, 12 Aug 2006 22:39:03 +1000
+
+libxcursor (1.1.5.2-6) UNRELEASED; urgency=low
+
+  * Test for obj-$(DEB_BUILD_GNU_TYPE) before creating it during build;
+    idempotency fix.
+  * Run dh_install w/ --list-missing.
+  * Bump standards version to 3.7.2.0.
+  * Version x11-common pre-dep in -dev package to 1:7.0.0 to match
+    the rest of Debian.
+  * Bump debhelper compat to 5.
+  * Fix dh_strip call to skip the -dbg package.
+  * Remove daniels from uploaders.
+
+ -- Andres Salomon <dilinger@debian.org>  Mon, 17 Jul 2006 01:20:47 -0400
+
+libxcursor (1.1.5.2-5) unstable; urgency=low
+
+  * Reorder makeshlib command in rules file so that ldconfig is run
+    properly. Thanks Drew Parsons and Steve Langasek.
+
+ -- David Nusinow <dnusinow@debian.org>  Wed, 19 Apr 2006 00:06:24 -0400
+
+libxcursor (1.1.5.2-4) UNRELEASED; urgency=low
+
+  * Append /usr/X11R6/lib/X11/icons to the icon search path for
+    backwards compatibility.
+
+ -- Steve Langasek <vorlon@debian.org>  Tue, 18 Apr 2006 16:27:59 -0700
+
+libxcursor (1.1.5.2-3) unstable; urgency=low
+
+  * Add libxfixes-dev to the depends of libxcursor-dev
+
+ -- David Nusinow <dnusinow@debian.org>  Wed, 12 Apr 2006 20:52:24 -0400
+
+libxcursor (1.1.5.2-2) unstable; urgency=low
+
+  * Upload to unstable
+
+ -- David Nusinow <dnusinow@debian.org>  Thu, 23 Mar 2006 22:44:31 -0500
+
+libxcursor (1.1.5.2-1) experimental; urgency=low
+
+  * First upload to Debian
+
+ -- David Nusinow <dnusinow@debian.org>  Mon, 23 Jan 2006 22:43:51 -0500
+
+libxcursor (1.1.5.2-0ubuntu2) dapper; urgency=low
+
+  * Change dependency on x-common to x11-common.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Thu, 19 Jan 2006 18:24:22 +1100
+
+libxcursor (1.1.5.2-0ubuntu1) dapper; urgency=low
+
+  * New upstream release.
+  * Repackage in line with all the other X libraries.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Mon, 12 Dec 2005 15:14:52 +1100
+
+xcursor (1.1.5-0ubuntu1) breezy; urgency=low
+
+  * New upstream release.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Wed, 16 Nov 2005 10:09:16 +1100
+
+xcursor (1.1.4-0ubuntu5) breezy; urgency=low
+
+  * Bump Build-Depends on x11proto-core-dev, libx11-dev and libxfixes-dev
+    high enough that we don't see _XOPEN_SOURCE again.
+  * Remove libc6-dev | libc-dev dependency from libxcursor-dev (???), change
+    x-dev to x11proto-core-dev.
+  * Stop installing libXcursor.la.
+  * Clean up libxcursor-dev.install.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Fri, 22 Jul 2005 23:48:13 +1000
+
+xcursor (1.1.4-0ubuntu4) breezy; urgency=low
+
+  * Make the xrender build-dep versioned, to rid us of libXrender.la.
+
+ -- Adam Conrad <adconrad@ubuntu.com>  Tue, 19 Jul 2005 14:54:02 +1000
+
+xcursor (1.1.4-0ubuntu3) breezy; urgency=low
+
+  * Rebuild with the current libXrender.
+
+ -- Sebastien Bacher <seb128@canonical.com>  Fri, 15 Jul 2005 15:52:32 +0200
+
+xcursor (1.1.4-0ubuntu2) breezy; urgency=low
+
+  * Add missing build-deps on libxfixes-dev and make it correctly
+    versioned so we will have the xfixes.pc file in the correct place.
+
+ -- Tollef Fog Heen <tfheen@canonical.com>  Thu, 30 Jun 2005 16:54:15 +0200
+
+xcursor (1.1.4-0ubuntu1) breezy; urgency=low
+
+  * New upstream release.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Thu, 30 Jun 2005 04:36:17 +1000
+
+xcursor (1.1.3-1ubuntu2) breezy; urgency=low
+
+  * Add Pre-Depends on x-common to libxcursor-dev to avoid files getting stuck
+    in /usr/X11R6 thanks to symlink treachery.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Thu, 19 May 2005 00:50:18 +1000
+
+xcursor (1.1.3-1ubuntu1) breezy; urgency=low
+
+  * Move files from /usr/X11R6 to /usr.
+
+ -- Fabio M. Di Nitto <fabbione@ubuntu.com>  Tue, 17 May 2005 19:20:26 +0200
+
+xcursor (1.1.3-1) unstable; urgency=medium
+
+  * Urgency due to fix for release-critical bug.
+
+  * New upstream version.
+    + Invokes AC_SUBST() on X_CFLAGS and X_LIBS, unbreaking xcursor.pc file.
+      (Closes: #241249)
+
+  * Add versioning to libxcursor1's shlibs information, since Xcursor 1.1.2
+    added a member to the XcursorImages structure and added the
+    XcursorImagesSetName() and XcursorLibraryPath() functions.
+
+  * Disable upstream autoconf check for the XFIXES library, as this library is
+    not packaged for Debian yet, and upstream supports no option to the
+    configure script to avoid checking (neverthless, the source is designed to
+    be buildable without it).  Regenerate related files with autogen.sh
+    script.
+
+  * Modify AC_PATH_XTRA invocation to take advantage of Debian's enhancements
+    (from autoconf 2.59-3); don't use the macro's defaults, which look for the
+    Xt library which we don't use.  Instead search for the X11 library, the
+    Xlib.h header file, and the XInternAtom() function, all of which are
+    actually used by the Xcursor library.  Regenerate related files with the
+    autogen.sh script.
+
+  * Update config.guess, config.sub, and ltmain.sh with libtoolize --force
+    --copy.
+
+  * Update package descriptions.
+
+ -- Branden Robinson <branden@debian.org>  Mon, 19 Apr 2004 15:39:41 -0500
+
+xcursor (1.0.2-5) unstable; urgency=low
+
+  * Make package compatible with the XFree86 4.3.0 package reorganization.
+    - debian/control
+      + package build-depends on x-dev and libx11-dev instead of xlibs-dev
+      + libxcursor-dev depends on x-dev and libx11-dev instead of xlibs-dev
+
+  * Remove README.Debian; the release of xfree86 4.3.0-1 to unstable renders
+    advice about installing these xcursor packages in conjunction with
+    experimental XFree86 4.3.0 packages unecessary.
+    - debian/README.Debian
+
+  * Give source package a section ("devel", just like xft) to shut up
+    complaints from dpkg-genchanges.
+    - debian/control
+
+  * Remove AC_PATH_X and subsequent bailout logic from configure.ac; the
+    mechanism used to find the Xrender suffices to configure the build
+    environment.  Run aclocal && automake --foreign && autoconf.
+    - configure
+    - Makefile.in
+    - config.h.in
+    - configure.ac
+    - aclocal.m4
+
+ -- Branden Robinson <branden@debian.org>  Fri, 12 Mar 2004 12:51:55 -0500
+
+xcursor (1.0.2-4) unstable; urgency=medium
+
+  * urgency due to fix for FTBFS
+
+  * Set priority of libxcursor1-dbg package to extra (resolves override
+    disparity).
+    - debian/control
+
+  * Restore build-dependency on pkg-config; AM_MAINTAINER_MODE doesn't prevent
+    the ./configure script from running during a package build, and the
+    ./configure script does indeed invoke pkg-config (fixes FTBFS).
+    (Closes: #225433)
+    - debian/control
+
+ -- Branden Robinson <branden@debian.org>  Tue, 30 Dec 2003 11:46:15 -0500
+
+xcursor (1.0.2-3) unstable; urgency=low
+
+  * Update copyright file to refer to new canonical upstream URL for source
+    archive.
+    - debian/copyright
+
+  * Elaborate and clarify README.Debian as regards Daniel Stone's experimental
+    xfree86 packages.
+    - debian/README.Debian
+
+  * Set AM_MAINTAINER_MODE because we do not want automake running during
+    Debian package builds.
+    - configure.ac
+
+  * Run aclocal && automake --foreign && autoconf to resynchronize with
+    change to configure.ac.
+    - Makefile.in
+    - aclocal.m4
+    - configure
+
+  * Stop passing arguments to dh_makeshlibs; there has not yet been a version
+    of xcursor released to Debian that has not been forwards-compatible.
+    - debian/rules
+
+  * Bump package's standards-version to 3.6.1; no changes necessary.
+    - debian/control
+
+  * Clean up package's build-dependencies and -dev package's dependencies.
+    - debian/control:
+      + add versioning of (>= 0.4.12) to build-dependency on cdbs for proper
+        support of debugging libraries
+      + tweak versioned build-dependency on debhelper (>> 4.0.0) to be a >=
+        instead
+      + drop versioning of build-dependency on xlibs-dev; libXcursor1 links
+        only against libX11, thus no versioning is necessary
+      + drop build-dependencies on autotools-dev and pkg-config since we now
+        use AM_MAINTAINER_MODE
+      + drop libxcursor-dev's dependency on ${shlibs:Depends}; it's not
+        necessary
+      + add dependencies on xlibs-dev and libxrender-dev to libxcursor-dev
+
+  * Remove extraneous and possibly misleading wording in libxcursor1-dbg's
+    extended description.
+    - debian/control
+
+  * Add Daniel Stone to list of uploaders.
+    - debian/control
+
+ -- Branden Robinson <branden@debian.org>  Mon, 13 Oct 2003 00:12:31 -0500
+
+xcursor (1.0.2-2) unstable; urgency=low
+
+  * add missing Build-Depends: pkg-config, closes: #198584
+
+ -- ISHIKAWA Mutsumi <ishikawa@debian.org>  Tue, 24 Jun 2003 16:05:57 +0900
+
+xcursor (1.0.2-1) unstable; urgency=low
+
+  * I'm back and Initial official upload release.
+  * libraries moved into /usr/lib/{,debug} instead of
+    /usr/X11R6/lib/{,debug} (adapt Debian policy section 12.8.7.)
+  * drop conflicts: xlibs* (>> 4.3.0-0), xlibs* (<< 4.3.0-0pre1v1)
+    because versioned AND conflicts are not supported.
+
+ -- ISHIKAWA Mutsumi <ishikawa@debian.org>  Tue,  3 Jun 2003 00:35:13 +0900
+
+xcursor (1.0.2-0beta4) unstable; urgency=low
+
+  * only conflicts: xlibs* (>> 4.3.0-0), xlibs* (<< 4.3.0-0pre1v1)
+
+ -- ISHIKAWA Mutsumi <ishikawa@debian.org>  Fri, 30 May 2003 01:35:26 +0900
+
+xcursor (1.0.2-0beta3) unstable; urgency=low
+
+  * migrate to use cdbs
+  * add Build-Depends: cdbs
+  * remove Daniel Stone from uploaders (because he is not DD, yet)
+  * Bump Standards-Version: 3.5.10
+
+ -- ISHIKAWA Mutsumi <ishikawa@debian.org>  Wed, 28 May 2003 03:10:50 +0900
+
+xcursor (1.0.2-0beta2) unstable; urgency=low
+
+  * fix to install Xcursor.h into correct place
+
+ -- ISHIKAWA Mutsumi <ishikawa@debian.org>  Sat, 24 May 2003 03:55:44 +0900
+
+xcursor (1.0.2-0beta1) unstable; urgency=low
+
+  * Initial Beta Release.
+
+ -- ISHIKAWA Mutsumi <ishikawa@debian.org>  Thu, 22 May 2003 02:31:37 +0900
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..9e668b2
--- /dev/null
@@ -0,0 +1,57 @@
+Source: libxcursor
+Section: devel
+Priority: optional
+Maintainer: SooChan Lim <sc.lim@samsung.com>, Sangjin Lee <lsj119@samsung.com>, Debian X Strike Force <debian-x@lists.debian.org>
+Uploaders: SooChan Lim <sc1.lim@samsung.com>, Sung-Jin Park <sj76.park@samsung.com>, David Nusinow <dnusinow@debian.org>, Drew Parsons <dparsons@debian.org>, Cyril Brulebois <kibi@debian.org>
+Build-Depends: debhelper (>= 5.0.0), x11proto-core-dev (>= 6.2.1+cvs.20050722), libx11-dev (>= 2:1.3.3-2), libxrender-dev (>= 1:0.9.5-2), libxfixes-dev (>= 1:4.0.4-2), pkg-config, quilt, automake, libtool, xutils-dev (>= 1:7.4+4)
+Standards-Version: 3.8.4
+Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/libxcursor
+Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/libxcursor.git
+
+Package: libxcursor1
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}
+Description: X cursor management library
+ Xcursor is a simple library designed to help locate and load cursors for the
+ X Window System.  Cursors can be loaded from files or memory and can exist in
+ several sizes; the library automatically picks the best size.  When using
+ images loaded from files, Xcursor prefers to use the Render extension's
+ CreateCursor request for rendering cursors.  Where the Render extension is
+ not supported, Xcursor maps the cursor image to a standard X cursor and uses
+ the core X protocol CreateCursor request.
+
+#Package: libxcursor1-udeb
+#XC-Package-Type: udeb
+#Section: debian-installer
+#Architecture: any
+#Depends: ${shlibs:Depends},
+#Description: X cursor management library
+# This is a udeb, or a microdeb, for the debian-installer.
+
+Package: libxcursor1-dbg
+Section: debug
+Priority: extra
+Architecture: any
+Depends: libxcursor1 (= ${binary:Version}), ${shlibs:Depends}, 
+Description: X cursor management library (unstripped)
+ This package provides an unstripped shared object with debugging symbols,
+ useful to provide a backtrace with symbol names in a debugger; this
+ facilitates interpretation of core dumps, and aids in finding logic errors in
+ programs using this library (or the library itself).  The library is
+ installed in /usr/lib/debug and can be used by placing that directory in the
+ LD_LIBRARY_PATH environment variable when the code to be debugged is
+ executed.  Non-programmers will likely have little use for this package.
+ .
+ Non-programmers will likely have little use for this package.  See the
+ libxcursor1 package for further information.
+
+Package: libxcursor-dev
+Section: libdevel
+Architecture: any
+Depends: libxcursor1 (= ${binary:Version}), x11proto-core-dev, libx11-dev, libxrender-dev, libxfixes-dev,
+Description: X cursor management library (development files)
+ Header files and a static version of the X cursor management library are
+ provided by this package.
+ .
+ See the libxcursor1 package for further information.
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..d3cfb2b
--- /dev/null
@@ -0,0 +1,56 @@
+This package was debianized by ISHIKAWA Mutsumi <ishikawa@debian.org> on
+Mon, 12 May 2003 05:14:45 +0900.
+
+It was downloaded from
+http://xorg.freedesktop.org/releases/individual/lib/
+
+Upstream copyright:
+
+  Copyright © 2001,2003 Keith Packard
+
+Upstream license:
+
+  Permission to use, copy, modify, distribute, and sell this software and its
+  documentation for any purpose is hereby granted without fee, provided that
+  the above copyright notice appear in all copies and that both that copyright
+  notice and this permission notice appear in supporting documentation, and
+  that the name of Keith Packard not be used in advertising or publicity
+  pertaining to distribution of the software without specific, written prior
+  permission.  Keith Packard makes no representations about the suitability of
+  this software for any purpose.  It is provided "as is" without express or
+  implied warranty.
+
+  KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
+  SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+  PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+  SOFTWARE.
+
+The Debian packaging infrastructure in the debian/ directory of the source
+package is independently authored and copyrighted.
+
+Debian copyright:
+
+  Copyright 2003 Software in the Public Interest, Inc.
+
+Debian license:
+
+  Permission to use, copy, modify, distribute, and sell this software and its
+  documentation for any purpose is hereby granted without fee, provided that
+  the above copyright notice appear in all copies and that both that copyright
+  notice and this permission notice appear in supporting documentation, and
+  that the name of Software in the Public Interest, Inc. not be used in
+  advertising or publicity pertaining to distribution of the software without
+  specific, written prior permission.  Software in the Public Interest, Inc.
+  makes no representations about the suitability of this software for any
+  purpose.  It is provided "as is" without express or implied warranty.
+
+  SOFTWARE IN THE PUBLIC INTEREST, INC. DISCLAIMS ALL WARRANTIES WITH REGARD
+  TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+  FITNESS, IN NO EVENT SHALL SOFTWARE IN THE PUBLIC INTEREST, INC. BE LIABLE
+  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+  CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/debian/libxcursor-dev.install b/debian/libxcursor-dev.install
new file mode 100755 (executable)
index 0000000..47e4cb6
--- /dev/null
@@ -0,0 +1,6 @@
+usr/include/X11/Xcursor/Xcursor.h
+usr/lib/libXcursor.a
+usr/lib/libXcursor.la
+usr/lib/libXcursor.so
+usr/lib/pkgconfig/*.pc
+
diff --git a/debian/libxcursor-dev.manpages b/debian/libxcursor-dev.manpages
new file mode 100755 (executable)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/debian/libxcursor1-udeb.install b/debian/libxcursor1-udeb.install
new file mode 100644 (file)
index 0000000..400d2d7
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/libXcursor.so.*
diff --git a/debian/libxcursor1.install b/debian/libxcursor1.install
new file mode 100644 (file)
index 0000000..400d2d7
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/libXcursor.so.*
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..d1b3643
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/bin/make -f
+# debian/rules for the Debian libxcursor package.
+# Copyright © 2004 Scott James Remnant <scott@netsplit.com>
+# Copyright © 2005 Daniel Stone <daniel@fooishbar.org>
+# Copyright © 2005 David Nusinow <dnusinow@debian.org>
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# set this to the name of the main shlib's binary package
+PACKAGE = libxcursor1
+
+include debian/xsfbs/xsfbs.mk
+
+CFLAGS = -Wall -g
+LDFLAGS +=  -Wl,--hash-style=both -Wl,--as-needed
+ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       MAKEFLAGS += -j$(NUMJOBS)
+endif
+
+DEB_HOST_ARCH      ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_HOST_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
+       confflags += --build=$(DEB_HOST_GNU_TYPE)
+else
+       confflags += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+endif
+
+autogen:
+       dh_testdir
+
+       ./autogen.sh
+
+#build: patch build-stamp
+build: autogen build-stamp
+build-stamp:
+       dh_testdir
+       test -d obj-$(DEB_BUILD_GNU_TYPE) || mkdir obj-$(DEB_BUILD_GNU_TYPE)
+       cd obj-$(DEB_BUILD_GNU_TYPE) && \
+       ../configure --prefix=/usr CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)"
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE)
+
+       touch build-stamp
+
+clean: xsfclean
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp
+
+       rm -f config.cache config.log config.status
+       rm -f */config.cache */config.log */config.status
+       rm -f conftest* */conftest*
+       rm -rf autom4te.cache */autom4te.cache
+       rm -rf obj-*
+       rm -f aclocal.m4 config.guess config.h.in config.sub configure
+       rm -f depcomp install-sh missing mkinstalldirs ltmain.sh
+       #rm -f ltmain.sh
+       find -name Makefile.in -exec rm -f {} \;
+       #find -name Makefile.in -delete
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+
+#      dh_installdocs
+       dh_install --sourcedir=debian/tmp --list-missing --exclude=usr/share/man/man3
+#      dh_installman
+#      dh_installchangelogs
+       dh_link
+       dh_strip --dbg-package=$(PACKAGE)-dbg
+       dh_compress
+       dh_fixperms
+       dh_makeshlibs -V "libxcursor1 (>> 1.1.2)"
+#      dh_makeshlibs -V "libxcursor1 (>> 1.1.2)" --add-udeb=$(PACKAGE)-udeb
+       dh_shlibdeps
+       dh_installdeb
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+# Build architecture-independent files here.
+binary-indep: build install
+# Nothing to do
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/debian/watch b/debian/watch
new file mode 100644 (file)
index 0000000..9f1353a
--- /dev/null
@@ -0,0 +1,2 @@
+version=3
+http://xorg.freedesktop.org/releases/individual/lib/ libXcursor-(.*)\.tar\.gz
diff --git a/debian/xsfbs/repack.sh b/debian/xsfbs/repack.sh
new file mode 100644 (file)
index 0000000..5935cc9
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+if ! [ -d debian/prune ]; then
+       exit 0
+fi
+
+if [ "x$1" != x--upstream-version ]; then
+       exit 1
+fi
+
+version="$2"
+filename="$3"
+
+if [ -z "$version" ] || ! [ -f "$filename" ]; then
+       exit 1
+fi
+
+dir="$(pwd)"
+tempdir="$(mktemp -d)"
+
+cd "$tempdir"
+tar xf "$dir/$filename"
+cat "$dir"/debian/prune/* | while read file; do rm -f */$file; done
+
+tar czf "$dir/$filename" *
+cd "$dir"
+rm -rf "$tempdir"
+echo "Done pruning upstream tarball"
+
+exit 0
diff --git a/debian/xsfbs/xsfbs.mk b/debian/xsfbs/xsfbs.mk
new file mode 100644 (file)
index 0000000..5e16b10
--- /dev/null
@@ -0,0 +1,276 @@
+#!/usr/bin/make -f
+
+# Debian X Strike Force Build System (XSFBS): Make portion
+
+# Copyright 1996 Stephen Early
+# Copyright 1997 Mark Eichin
+# Copyright 1998-2005, 2007 Branden Robinson
+# Copyright 2005 David Nusinow
+#
+# Licensed under the GNU General Public License, version 2.  See the file
+# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
+
+# Originally by Stephen Early <sde1000@debian.org>
+# Modified by Mark W. Eichin <eichin@kitten.gen.ma.us>
+# Modified by Adam Heath <doogie@debian.org>
+# Modified by Branden Robinson <branden@debian.org>
+# Modified by Fabio Massimo Di Nitto <fabbione@fabbione.net>
+# Modified by David Nusinow <dnusinow@debian.org>
+# Acknowledgements to Manoj Srivastava.
+
+# Pass $(DH_OPTIONS) into the environment for debhelper's benefit.
+export DH_OPTIONS
+
+# force quilt to not use ~/.quiltrc and to use debian/patches
+QUILT = QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null
+
+# Set up parameters for the upstream build environment.
+
+# Determine (source) package name from Debian changelog.
+SOURCE_NAME:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Source:' | awk '{print $$2}')
+
+# Determine package version from Debian changelog.
+SOURCE_VERSION:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Version:' | awk '{print $$2}')
+
+# Determine upstream version number.
+UPSTREAM_VERSION:=$(shell echo $(SOURCE_VERSION) | sed 's/-.*//')
+
+# Determine the source version without the epoch for make-orig-tar-gz
+NO_EPOCH_VER:=$(shell echo $(UPSTREAM_VERSION) | sed 's/^.://')
+
+# Figure out who's building this package.
+BUILDER:=$(shell echo $${DEBEMAIL:-$${EMAIL:-$$(echo $$LOGNAME@$$(cat /etc/mailname 2>/dev/null))}})
+
+# Find out if this is an official build; an official build has nothing but
+# digits, dots, and/or the codename of a release in the Debian part of the
+# version number.  Anything else indicates an unofficial build.
+OFFICIAL_BUILD:=$(shell VERSION=$(SOURCE_VERSION); if ! expr "$$(echo $${VERSION\#\#*-} | sed 's/\(woody\|sarge\|etch\|lenny\)//g')" : ".*[^0-9.].*" >/dev/null 2>&1; then echo yes; fi)
+
+# Set up parameters for the Debian build environment.
+
+# Determine our architecture.
+BUILD_ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
+# Work around some old-time dpkg braindamage.
+BUILD_ARCH:=$(subst i486,i386,$(BUILD_ARCH))
+# The DEB_HOST_ARCH variable may be set per the Debian cross-compilation policy.
+ifdef DEB_HOST_ARCH
+ ARCH:=$(DEB_HOST_ARCH)
+else
+ # dpkg-cross sets the ARCH environment variable; if set, use it.
+ ifdef ARCH
+  ARCH:=$(ARCH)
+ else
+  ARCH:=$(BUILD_ARCH)
+ endif
+endif
+
+# $(STAMP_DIR) houses stamp files for complex targets.
+STAMP_DIR:=stampdir
+
+# $(DEBTREEDIR) is where all install rules are told (via $(DESTDIR)) to place
+# their files.
+DEBTREEDIR:=$(CURDIR)/debian/tmp
+
+# All "important" targets have four lines:
+#   1) A target name that is invoked by a package-building tool or the user.
+#      This consists of a dependency on a "$(STAMP_DIR)/"-prefixed counterpart.
+#   2) A line delcaring 1) as a phony target (".PHONY:").
+#   3) A "$(STAMP_DIR)/"-prefixed target which does the actual work, and may
+#   depend on other targets.
+#   4) A line declaring 3) as a member of the $(stampdir_targets) variable; the
+#   "$(STAMP_DIR)/" prefix is omitted.
+#
+# This indirection is needed so that the "stamp" files that signify when a rule
+# is done can be located in a separate "stampdir".  Recall that make has no way
+# to know when a goal has been met for a phony target (like "build" or
+# "install").
+#
+# At the end of each "$(STAMP_DIR)/" target, be sure to run the command ">$@"
+# so that the target will not be run again.  Removing the file will make Make
+# run the target over.
+
+# All phony targets should be declared as dependencies of .PHONY, even if they
+# do not have "($STAMP_DIR)/"-prefixed counterparts.
+
+# Define a harmless default rule to keep things from going nuts by accident.
+.PHONY: default
+default:
+
+# Set up the $(STAMP_DIR) directory.
+.PHONY: stampdir
+stampdir_targets+=stampdir
+stampdir: $(STAMP_DIR)/stampdir
+$(STAMP_DIR)/stampdir:
+       mkdir $(STAMP_DIR)
+       >$@
+
+# Set up the package build directory as quilt expects to find it.
+.PHONY: prepare
+stampdir_targets+=prepare
+prepare: $(STAMP_DIR)/prepare
+$(STAMP_DIR)/prepare: $(STAMP_DIR)/log $(STAMP_DIR)/genscripts
+       >$@
+
+.PHONY: log
+stampdir_targets+=log
+log: $(STAMP_DIR)/log
+$(STAMP_DIR)/log: $(STAMP_DIR)/stampdir
+       mkdir -p $(STAMP_DIR)/log
+
+# Apply all patches to the upstream source.
+.PHONY: patch
+stampdir_targets+=patch
+patch: $(STAMP_DIR)/patch
+$(STAMP_DIR)/patch: $(STAMP_DIR)/prepare
+       if ! [ `which quilt` ]; then \
+               echo "Couldn't find quilt. Please install it or add it to the build-depends for this package."; \
+               exit 1; \
+       fi; \
+       if $(QUILT) next >/dev/null 2>&1; then \
+         echo -n "Applying patches..."; \
+         if $(QUILT) push -a -v >$(STAMP_DIR)/log/patch 2>&1; then \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "failed! (check $(STAMP_DIR)/log/patch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "No patches to apply"; \
+       fi; \
+       >$@
+
+# Revert all patches to the upstream source.
+.PHONY: unpatch
+unpatch: $(STAMP_DIR)/log
+       rm -f $(STAMP_DIR)/patch
+       @echo -n "Unapplying patches..."; \
+       if $(QUILT) applied >/dev/null 2>/dev/null; then \
+         if $(QUILT) pop -a -v >$(STAMP_DIR)/log/unpatch 2>&1; then \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "failed! (check $(STAMP_DIR)/log/unpatch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "nothing to do."; \
+       fi
+
+# Clean the generated maintainer scripts.
+.PHONY: cleanscripts
+cleanscripts:
+       rm -f $(STAMP_DIR)/genscripts
+       rm -f debian/*.config \
+             debian/*.postinst \
+             debian/*.postrm \
+             debian/*.preinst \
+             debian/*.prerm
+
+# Clean the package build tree.
+.PHONY: xsfclean
+xsfclean: cleanscripts unpatch
+       dh_testdir
+       rm -rf .pc
+       rm -rf $(STAMP_DIR)
+       dh_clean
+
+# Remove files from the upstream source tree that we don't need, or which have
+# licensing problems.  It must be run before creating the .orig.tar.gz.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: prune-upstream-tree
+prune-upstream-tree:
+       # Ensure we're in the correct directory.
+       dh_testdir
+       grep -rvh '^#' debian/prune/ | xargs --no-run-if-empty rm -rf
+
+# Verify that there are no offsets or fuzz in the patches we apply.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: patch-audit
+patch-audit: prepare unpatch
+       @echo -n "Auditing patches..."; \
+       >$(STAMP_DIR)/log/patch; \
+       FUZZY=; \
+       while [ -n "$$($(QUILT) next)" ]; do \
+         RESULT=$$($(QUILT) push -v | tee -a $(STAMP_DIR)/log/patch | grep ^Hunk | sed 's/^Hunk.*\(succeeded\|FAILED\).*/\1/');\
+         case "$$RESULT" in \
+           succeeded) \
+             echo "fuzzy patch: $$($(QUILT) top)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) top); \
+             FUZZY=yes; \
+             ;; \
+           FAILED) \
+             echo "broken patch: $$($(QUILT) next)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) next); \
+             exit 1; \
+             ;; \
+         esac; \
+       done; \
+       if [ -n "$$FUZZY" ]; then \
+         echo "there were fuzzy patches; please fix."; \
+         exit 1; \
+       else \
+         echo "done."; \
+       fi
+
+# Generate the maintainer scripts.
+.PHONY: genscripts
+stampdir_targets+=genscripts
+genscripts: $(STAMP_DIR)/genscripts
+$(STAMP_DIR)/genscripts: $(STAMP_DIR)/stampdir
+       for FILE in debian/*.config.in \
+                   debian/*.postinst.in \
+                   debian/*.postrm.in \
+                   debian/*.preinst.in \
+                   debian/*.prerm.in; do \
+         if [ -e "$$FILE" ]; then \
+           MAINTSCRIPT=$$(echo $$FILE | sed 's/.in$$//'); \
+           sed -n '1,/^#INCLUDE_SHELL_LIB#$$/p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >$$MAINTSCRIPT.tmp; \
+           cat debian/xsfbs/xsfbs.sh >>$$MAINTSCRIPT.tmp; \
+           sed -n '/^#INCLUDE_SHELL_LIB#$$/,$$p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >>$$MAINTSCRIPT.tmp; \
+           sed -e 's/@SOURCE_VERSION@/$(SOURCE_VERSION)/' \
+               -e 's/@OFFICIAL_BUILD@/$(OFFICIAL_BUILD)/' \
+             <$$MAINTSCRIPT.tmp >$$MAINTSCRIPT; \
+           rm $$MAINTSCRIPT.tmp; \
+         fi; \
+       done
+       # Validate syntax of generated shell scripts.
+       #sh debian/scripts/validate-posix-sh debian/*.config \
+       #                                    debian/*.postinst \
+       #                                    debian/*.postrm \
+       #                                    debian/*.preinst \
+       #                                    debian/*.prerm
+       >$@
+
+SERVERMINVERS = $(shell cat /usr/share/xserver-xorg/serverminver 2>/dev/null)
+VIDEOABI = $(shell cat /usr/share/xserver-xorg/videoabiver 2>/dev/null)
+INPUTABI = $(shell cat /usr/share/xserver-xorg/inputabiver 2>/dev/null)
+SERVER_DEPENDS = xserver-xorg-core (>= $(SERVERMINVERS))
+VIDDRIVER_PROVIDES = xserver-xorg-video-$(VIDEOABI)
+INPDRIVER_PROVIDES = xserver-xorg-input-$(INPUTABI)
+ifeq ($(PACKAGE),)
+PACKAGE=$(shell awk '/^Package:/ { print $$2; exit }' < debian/control)
+endif
+
+.PHONY: serverabi
+serverabi: install
+ifeq ($(SERVERMINVERS),)
+       @echo error: xserver-xorg-dev needs to be installed
+       @exit 1
+else
+       echo "xserver:Depends=$(SERVER_DEPENDS)" >> debian/$(PACKAGE).substvars
+       echo "xviddriver:Provides=$(VIDDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+       echo "xinpdriver:Provides=$(INPDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+endif
+
+# vim:set noet ai sts=8 sw=8 tw=0:
diff --git a/debian/xsfbs/xsfbs.sh b/debian/xsfbs/xsfbs.sh
new file mode 100644 (file)
index 0000000..813fd8d
--- /dev/null
@@ -0,0 +1,622 @@
+# This is the X Strike Force shell library for X Window System package
+# maintainer scripts.  It serves to define shell functions commonly used by
+# such packages, and performs some error checking necessary for proper operation
+# of those functions.  By itself, it does not "do" much; the maintainer scripts
+# invoke the functions defined here to accomplish package installation and
+# removal tasks.
+
+# If you are reading this within a Debian package maintainer script (e.g.,
+# /var/lib/dpkg/info/PACKAGE.{config,preinst,postinst,prerm,postrm}), you can
+# skip past this library by scanning forward in this file to the string
+# "GOBSTOPPER".
+
+SOURCE_VERSION=@SOURCE_VERSION@
+OFFICIAL_BUILD=@OFFICIAL_BUILD@
+
+# Use special abnormal exit codes so that problems with this library are more
+# easily tracked down.
+SHELL_LIB_INTERNAL_ERROR=86
+SHELL_LIB_THROWN_ERROR=74
+SHELL_LIB_USAGE_ERROR=99
+
+# old -> new variable names
+if [ -z "$DEBUG_XORG_PACKAGE" ] && [ -n "$DEBUG_XFREE86_PACKAGE" ]; then
+  DEBUG_XORG_PACKAGE="$DEBUG_XFREE86_PACKAGE"
+fi
+if [ -z "$DEBUG_XORG_DEBCONF" ] && [ -n "$DEBUG_XFREE86_DEBCONF" ]; then
+  DEBUG_XORG_DEBCONF="$DEBUG_XFREE86_DEBCONF"
+fi
+
+# initial sanity checks
+if [ -z "$THIS_PACKAGE" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_PACKAGE shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of this package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ -z "$THIS_SCRIPT" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_SCRIPT shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of the
+"$THIS_PACKAGE" package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ "$1" = "reconfigure" ] || [ -n "$DEBCONF_RECONFIGURE" ]; then
+  RECONFIGURE="true"
+else
+  RECONFIGURE=
+fi
+
+if ([ "$1" = "install" ] || [ "$1" = "configure" ]) && [ -z "$2" ]; then
+  FIRSTINST="yes"
+fi
+
+if [ -z "$RECONFIGURE" ] && [ -z "$FIRSTINST" ]; then
+  UPGRADE="yes"
+fi
+
+trap "message;\
+      message \"Received signal.  Aborting $THIS_PACKAGE package $THIS_SCRIPT script.\";\
+      message;\
+      exit 1" HUP INT QUIT TERM
+
+reject_nondigits () {
+  # syntax: reject_nondigits [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters other than decimal digits and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain anything but digits?
+    if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+      # can't use die(), because it wraps message() which wraps this function
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \
+           "possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+reject_unlikely_path_chars () {
+  # syntax: reject_unlikely_path_chars [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters unlikely to be seen in a path and which the shell might
+  # interpret and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain any funny characters?
+    if expr "$1" : '.*[!$&()*;<>?|].*' > /dev/null 2>&1; then
+      # can't use die(), because I want to avoid forward references
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \
+           "encountered possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+# Query the terminal to establish a default number of columns to use for
+# displaying messages to the user.  This is used only as a fallback in the
+# event the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while
+# the script is running, and this cannot, only being calculated once.)
+DEFCOLUMNS=$(stty size 2> /dev/null | awk '{print $2}') || true
+if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+  DEFCOLUMNS=80
+fi
+
+message () {
+  # pretty-print messages of arbitrary length
+  reject_nondigits "$COLUMNS"
+  echo "$*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} >&2
+}
+
+observe () {
+  # syntax: observe message ...
+  #
+  # issue observational message suitable for logging someday when support for
+  # it exists in dpkg
+  if [ -n "$DEBUG_XORG_PACKAGE" ]; then
+    message "$THIS_PACKAGE $THIS_SCRIPT note: $*"
+  fi
+}
+
+warn () {
+  # syntax: warn message ...
+  #
+  # issue warning message suitable for logging someday when support for
+  # it exists in dpkg; also send to standard error
+  message "$THIS_PACKAGE $THIS_SCRIPT warning: $*"
+}
+
+die () {
+  # syntax: die message ...
+  #
+  # exit script with error message
+  message "$THIS_PACKAGE $THIS_SCRIPT error: $*"
+  exit $SHELL_LIB_THROWN_ERROR
+}
+
+internal_error () {
+  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
+  message "internal error: $*"
+  if [ -n "$OFFICIAL_BUILD" ]; then
+    message "Please report a bug in the $THIS_SCRIPT script of the" \
+            "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+            "Tracking System.  Include all messages above that mention the" \
+            "$THIS_PACKAGE package.  Visit " \
+            "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+            "instructions, read the file" \
+            "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+            "package, or install the reportbug package and use the command of" \
+            "the same name to file a report."
+  fi
+  exit $SHELL_LIB_INTERNAL_ERROR
+}
+
+usage_error () {
+  message "usage error: $*"
+  message "Please report a bug in the $THIS_SCRIPT script of the" \
+          "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+          "Tracking System.  Include all messages above that mention the" \
+          "$THIS_PACKAGE package.  Visit " \
+          "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+          "instructions, read the file" \
+          "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+          "package, or install the reportbug package and use the command of" \
+          "the same name to file a report."
+  exit $SHELL_LIB_USAGE_ERROR
+}
+
+font_update () {
+  # run $UPDATECMDS in $FONTDIRS
+
+  local dir cmd shortcmd x_font_dir_prefix
+
+  x_font_dir_prefix="/usr/share/fonts/X11"
+
+  if [ -z "$UPDATECMDS" ]; then
+    usage_error "font_update() called but \$UPDATECMDS not set"
+  fi
+  if [ -z "$FONTDIRS" ]; then
+    usage_error "font_update() called but \$FONTDIRS not set"
+  fi
+
+  reject_unlikely_path_chars "$UPDATECMDS"
+  reject_unlikely_path_chars "$FONTDIRS"
+
+  for dir in $FONTDIRS; do
+    if [ -d "$x_font_dir_prefix/$dir" ]; then
+      for cmd in $UPDATECMDS; do
+        if which "$cmd" > /dev/null 2>&1; then
+          shortcmd=${cmd##*/}
+          observe "running $shortcmd in $dir font directory"
+         cmd_opts=
+          if [ "$shortcmd" = "update-fonts-alias" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-dir" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-scale" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          $cmd $cmd_opts $dir || warn "$cmd $cmd_opts $dir" \
+                              "failed; font directory data may not" \
+                              "be up to date"
+        else
+          warn "$cmd not found; not updating corresponding $dir font" \
+               "directory data"
+        fi
+      done
+    else
+      warn "$dir is not a directory; not updating font directory data"
+    fi
+  done
+}
+
+remove_conffile_prepare () {
+  # syntax: remove_conffile_prepare filename official_md5sum ...
+  #
+  # Check a conffile "filename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 2 ]; then
+    usage_error "remove_conffile_prepare() called with wrong number of" \
+                "arguments; expected at least 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+  shift
+
+  # does the conffile even exist?
+  if [ -e "$conffile" ]; then
+    # calculate its checksum
+    current_checksum=$(md5sum < "$conffile" | sed 's/[[:space:]].*//')
+    # compare it to each supplied checksum
+    while [ -n "$1" ]; do
+      if [ "$current_checksum" = "$1" ]; then
+        # we found a match; move the confffile and stop looking
+        observe "preparing obsolete conffile $conffile for removal"
+        mv "$conffile" "$conffile.$THIS_PACKAGE-tmp"
+        break
+      fi
+      shift
+    done
+  fi
+}
+
+remove_conffile_lookup () {
+  # syntax: remove_conffile_lookup package filename
+  #
+  # Lookup the md5sum of a conffile in dpkg's database, and prepare for removal
+  # if it matches the actual file's md5sum.
+  #
+  # Call this function when you would call remove_conffile_prepare but only
+  # want to check against dpkg's status database instead of known checksums.
+
+  local package conffile old_md5sum
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "remove_conffile_lookup() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  package="$1"
+  conffile="$2"
+
+  if ! [ -e "$conffile" ]; then
+    return
+  fi
+  old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$package" | \
+    awk '{ if (match($0, "^ '"$conffile"' ")) print $2}')"
+  if [ -n "$old_md5sum" ]; then
+    remove_conffile_prepare "$conffile" "$old_md5sum"
+  fi
+}
+
+remove_conffile_commit () {
+  # syntax: remove_conffile_commit filename
+  #
+  # Complete the removal of a conffile "filename" that has become obsolete.
+  #
+  # Call this function from a postinst script after having used
+  # remove_conffile_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_commit() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, remove it
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "committing removal of obsolete conffile $conffile"
+    rm "$conffile.$THIS_PACKAGE-tmp"
+  fi
+}
+
+remove_conffile_rollback () {
+  # syntax: remove_conffile_rollback filename
+  #
+  # Roll back the removal of a conffile "filename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" is  after having used remove_conffile_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_rollback() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, move it
+  # back
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "rolling back removal of obsolete conffile $conffile"
+    mv "$conffile.$THIS_PACKAGE-tmp" "$conffile"
+  fi
+}
+
+replace_conffile_with_symlink_prepare () {
+  # syntax: replace_conffile_with_symlink_prepare oldfilename newfilename \
+  # official_md5sum ...
+  #
+  # Check a conffile "oldfilename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails. Otherwise copy it
+  # to newfilename and let dpkg handle it through conffiles mechanism.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 3 ]; then
+    usage_error "replace_conffile_with_symlink_prepare() called with wrong" \
+                " number of arguments; expected at least 3, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  shift
+  newconffile="$1"
+  shift
+
+  remove_conffile_prepare "$_oldconffile" "$@"
+  # If $oldconffile still exists, then md5sums didn't match.
+  # Copy it to new one.
+  if [ -f "$oldconffile" ]; then
+    cp "$oldconffile" "$newconffile"
+  fi
+
+}
+
+replace_conffile_with_symlink_commit () {
+  # syntax: replace_conffile_with_symlink_commit oldfilename
+  #
+  # Complete the removal of a conffile "oldfilename" that has been
+  # replaced by a symlink.
+  #
+  # Call this function from a postinst script after having used
+  # replace_conffile_with_symlink_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "replace_conffile_with_symlink_commit() called with wrong" \
+                "number of arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  remove_conffile_commit "$conffile"
+}
+
+replace_conffile_with_symlink_rollback () {
+  # syntax: replace_conffile_with_symlink_rollback oldfilename newfilename
+  #
+  # Roll back the replacing of a conffile "oldfilename" with symlink to
+  # "newfilename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" and verify $2 to ensure the package failed to upgrade
+  # from a version (or install over a version removed-but-not-purged) prior
+  # to the one in which the conffile was obsoleted.
+  # You should have  used replace_conffile_with_symlink_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "replace_conffile_with_symlink_rollback() called with wrong" \
+                "number of arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  newconffile="$2"
+
+  remove_conffile_rollback "$_oldconffile"
+  if [ -f "$newconffile" ]; then
+    rm "$newconffile"
+  fi
+}
+
+run () {
+  # syntax: run command [ argument ... ]
+  #
+  # Run specified command with optional arguments and report its exit status.
+  # Useful for commands whose exit status may be nonzero, but still acceptable,
+  # or commands whose failure is not fatal to us.
+  #
+  # NOTE: Do *not* use this function with db_get or db_metaget commands; in
+  # those cases the return value of the debconf command *must* be checked
+  # before the string returned by debconf is used for anything.
+
+  local retval
+
+  # validate arguments
+  if [ $# -lt 1 ]; then
+    usage_error "run() called with wrong number of arguments; expected at" \
+                "least 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  "$@" || retval=$?
+
+  if [ ${retval:-0} -ne 0 ]; then
+    observe "command \"$*\" exited with status $retval"
+  fi
+}
+
+make_symlink_sane () {
+  # syntax: make_symlink_sane symlink target
+  #
+  # Ensure that the symbolic link symlink exists, and points to target.
+  #
+  # If symlink does not exist, create it and point it at target.
+  #
+  # If symlink exists but is not a symbolic link, back it up.
+  #
+  # If symlink exists, is a symbolic link, but points to the wrong location, fix
+  # it.
+  #
+  # If symlink exists, is a symbolic link, and already points to target, do
+  # nothing.
+  #
+  # This function wouldn't be needed if ln had an -I, --idempotent option.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "make_symlink_sane() called with wrong number of arguments;" \
+      "expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local symlink target
+
+  symlink="$1"
+  target="$2"
+
+  if [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$target" ]; then
+      observe "link from $symlink to $target already exists"
+  else
+    observe "creating symbolic link from $symlink to $target"
+    mkdir -p "${target%/*}" "${symlink%/*}"
+    ln -s -b -S ".dpkg-old" "$target" "$symlink"
+  fi
+}
+
+migrate_dir_to_symlink () {
+  # syntax: migrate_dir_to_symlink old_location new_location
+  #
+  # Per Debian Policy section 6.5.4, "A directory will never be replaced by a
+  # symbolic link to a directory or vice versa; instead, the existing state
+  # (symlink or not) will be left alone and dpkg will follow the symlink if
+  # there is one."
+  #
+  # We have to do it ourselves.
+  #
+  # This function moves the contents of old_location, a directory, into
+  # new_location, a directory, then makes old_location a symbolic link to
+  # new_location.
+  #
+  # old_location need not exist, but if it does, it must be a directory (or a
+  # symlink to a directory).  If it is not, it is backed up.  If new_location
+  # exists already and is not a directory, it is backed up.
+  #
+  # This function should be called from a package's preinst so that other
+  # packages unpacked after this one --- but before this package's postinst runs
+  # --- are unpacked into new_location even if their payloads contain
+  # old_location filespecs.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "migrate_dir_to_symlink() called with wrong number of"
+                "arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local new old
+
+  old="$1"
+  new="$2"
+
+  # Is old location a symlink?
+  if [ -L "$old" ]; then
+    # Does it already point to new location?
+    if [ "$(readlink "$old")" = "$new" ]; then
+      # Nothing to do; migration has already been done.
+      observe "migration of $old to $new already done"
+      return 0
+    else
+      # Back it up.
+      warn "backing up symbolic link $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+    fi
+  fi
+
+  # Does old location exist, but is not a directory?
+  if [ -e "$old" ] && ! [ -d "$old" ]; then
+      # Back it up.
+      warn "backing up non-directory $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+  fi
+
+  observe "migrating $old to $new"
+
+  # Is new location a symlink?
+  if [ -L "$new" ]; then
+    # Does it point the wrong way, i.e., back to where we're migrating from?
+    if [ "$(readlink "$new")" = "$old" ]; then
+      # Get rid of it.
+      observe "removing symbolic link $new which points to $old"
+      rm "$new"
+    else
+      # Back it up.
+      warn "backing up symbolic link $new as $new.dpkg-old"
+      mv -b "$new" "$new.dpkg-old"
+    fi
+  fi
+
+  # Does new location exist, but is not a directory?
+  if [ -e "$new" ] && ! [ -d "$new" ]; then
+    warn "backing up non-directory $new as $new.dpkg-old"
+    mv -b "$new" "$new.dpkg-old"
+  fi
+
+  # Create new directory if it does not yet exist.
+  if ! [ -e "$new" ]; then
+    observe "creating $new"
+    mkdir -p "$new"
+  fi
+
+  # Copy files in old location to new location.  Back up any filenames that
+  # already exist in the new location with the extension ".dpkg-old".
+  observe "copying files from $old to $new"
+  if ! (cd "$old" && cp -a -b -S ".dpkg-old" . "$new"); then
+    die "error(s) encountered while copying files from $old to $new"
+  fi
+
+  # Remove files at old location.
+  observe "removing $old"
+  rm -r "$old"
+
+  # Create symlink from old location to new location.
+  make_symlink_sane "$old" "$new"
+}
+
+# vim:set ai et sw=2 ts=2 tw=80:
+
+# GOBSTOPPER: The X Strike Force shell library ends here.
diff --git a/include/X11/Xcursor/Xcursor.h b/include/X11/Xcursor/Xcursor.h
new file mode 100644 (file)
index 0000000..90bfdd6
--- /dev/null
@@ -0,0 +1,500 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XCURSOR_H_
+#define _XCURSOR_H_
+#include <stdio.h>
+#include <X11/Xfuncproto.h>
+#include <X11/Xlib.h>
+
+typedef int            XcursorBool;
+typedef unsigned int   XcursorUInt;
+
+typedef XcursorUInt    XcursorDim;
+typedef XcursorUInt    XcursorPixel;
+
+#define XcursorTrue    1
+#define XcursorFalse   0
+
+/*
+ * Cursor files start with a header.  The header
+ * contains a magic number, a version number and a
+ * table of contents which has type and offset information
+ * for the remaining tables in the file.
+ *
+ * File minor versions increment for compatible changes
+ * File major versions increment for incompatible changes (never, we hope)
+ *
+ * Chunks of the same type are always upward compatible.  Incompatible
+ * changes are made with new chunk types; the old data can remain under
+ * the old type.  Upward compatible changes can add header data as the
+ * header lengths are specified in the file.
+ *
+ *  File:
+ *     FileHeader
+ *     LISTofChunk
+ *
+ *  FileHeader:
+ *     CARD32          magic       magic number
+ *     CARD32          header      bytes in file header
+ *     CARD32          version     file version
+ *     CARD32          ntoc        number of toc entries
+ *     LISTofFileToc   toc         table of contents
+ *
+ *  FileToc:
+ *     CARD32          type        entry type
+ *     CARD32          subtype     entry subtype (size for images)
+ *     CARD32          position    absolute file position
+ */
+
+#define XCURSOR_MAGIC  0x72756358  /* "Xcur" LSBFirst */
+
+/*
+ * Current Xcursor version number.  This same number
+ * must appear in the Xcursor configure.ac file. Yes,
+ * it'a a pain to synchronize version numbers like this.
+ */
+
+#define XCURSOR_LIB_MAJOR      1
+#define XCURSOR_LIB_MINOR      1
+#define XCURSOR_LIB_REVISION   9
+#define XCURSOR_LIB_VERSION    ((XCURSOR_LIB_MAJOR * 10000) + \
+                                (XCURSOR_LIB_MINOR * 100) + \
+                                (XCURSOR_LIB_REVISION))
+
+/*
+ * This version number is stored in cursor files; changes to the
+ * file format require updating this version number
+ */
+#define XCURSOR_FILE_MAJOR     1
+#define XCURSOR_FILE_MINOR     0
+#define XCURSOR_FILE_VERSION   ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR))
+#define XCURSOR_FILE_HEADER_LEN        (4 * 4)
+#define XCURSOR_FILE_TOC_LEN   (3 * 4)
+
+typedef struct _XcursorFileToc {
+    XcursorUInt            type;       /* chunk type */
+    XcursorUInt            subtype;    /* subtype (size for images) */
+    XcursorUInt            position;   /* absolute position in file */
+} XcursorFileToc;
+
+typedef struct _XcursorFileHeader {
+    XcursorUInt            magic;      /* magic number */
+    XcursorUInt            header;     /* byte length of header */
+    XcursorUInt            version;    /* file version number */
+    XcursorUInt            ntoc;       /* number of toc entries */
+    XcursorFileToc  *tocs;     /* table of contents */
+} XcursorFileHeader;
+
+/*
+ * The rest of the file is a list of chunks, each tagged by type
+ * and version.
+ *
+ *  Chunk:
+ *     ChunkHeader
+ *     <extra type-specific header fields>
+ *     <type-specific data>
+ *
+ *  ChunkHeader:
+ *     CARD32      header      bytes in chunk header + type header
+ *     CARD32      type        chunk type
+ *     CARD32      subtype     chunk subtype
+ *     CARD32      version     chunk type version
+ */
+
+#define XCURSOR_CHUNK_HEADER_LEN    (4 * 4)
+
+typedef struct _XcursorChunkHeader {
+    XcursorUInt            header;     /* bytes in chunk header */
+    XcursorUInt            type;       /* chunk type */
+    XcursorUInt            subtype;    /* chunk subtype (size for images) */
+    XcursorUInt            version;    /* version of this type */
+} XcursorChunkHeader;
+
+/*
+ * Here's a list of the known chunk types
+ */
+
+/*
+ * Comments consist of a 4-byte length field followed by
+ * UTF-8 encoded text
+ *
+ *  Comment:
+ *     ChunkHeader header      chunk header
+ *     CARD32      length      bytes in text
+ *     LISTofCARD8 text        UTF-8 encoded text
+ */
+
+#define XCURSOR_COMMENT_TYPE       0xfffe0001
+#define XCURSOR_COMMENT_VERSION            1
+#define XCURSOR_COMMENT_HEADER_LEN  (XCURSOR_CHUNK_HEADER_LEN + (1 *4))
+#define XCURSOR_COMMENT_COPYRIGHT   1
+#define XCURSOR_COMMENT_LICENSE            2
+#define XCURSOR_COMMENT_OTHER      3
+#define XCURSOR_COMMENT_MAX_LEN            0x100000
+
+typedef struct _XcursorComment {
+    XcursorUInt            version;
+    XcursorUInt            comment_type;
+    char           *comment;
+} XcursorComment;
+
+/*
+ * Each cursor image occupies a separate image chunk.
+ * The length of the image header follows the chunk header
+ * so that future versions can extend the header without
+ * breaking older applications
+ *
+ *  Image:
+ *     ChunkHeader     header  chunk header
+ *     CARD32          width   actual width
+ *     CARD32          height  actual height
+ *     CARD32          xhot    hot spot x
+ *     CARD32          yhot    hot spot y
+ *     CARD32          delay   animation delay
+ *     LISTofCARD32    pixels  ARGB pixels
+ */
+
+#define XCURSOR_IMAGE_TYPE         0xfffd0002
+#define XCURSOR_IMAGE_VERSION      1
+#define XCURSOR_IMAGE_HEADER_LEN    (XCURSOR_CHUNK_HEADER_LEN + (5*4))
+#define XCURSOR_IMAGE_MAX_SIZE     0x7fff      /* 32767x32767 max cursor size */
+
+typedef struct _XcursorImage {
+    XcursorUInt            version;    /* version of the image data */
+    XcursorDim     size;       /* nominal size for matching */
+    XcursorDim     width;      /* actual width */
+    XcursorDim     height;     /* actual height */
+    XcursorDim     xhot;       /* hot spot x (must be inside image) */
+    XcursorDim     yhot;       /* hot spot y (must be inside image) */
+    XcursorUInt            delay;      /* animation delay to next frame (ms) */
+    XcursorPixel    *pixels;   /* pointer to pixels */
+} XcursorImage;
+
+/*
+ * Other data structures exposed by the library API
+ */
+typedef struct _XcursorImages {
+    int                    nimage;     /* number of images */
+    XcursorImage    **images;  /* array of XcursorImage pointers */
+    char           *name;      /* name used to load images */
+} XcursorImages;
+
+typedef struct _XcursorCursors {
+    Display        *dpy;       /* Display holding cursors */
+    int                    ref;        /* reference count */
+    int                    ncursor;    /* number of cursors */
+    Cursor         *cursors;   /* array of cursors */
+} XcursorCursors;
+
+typedef struct _XcursorAnimate {
+    XcursorCursors   *cursors; /* list of cursors to use */
+    int                    sequence;   /* which cursor is next */
+} XcursorAnimate;
+
+typedef struct _XcursorFile XcursorFile;
+
+struct _XcursorFile {
+    void    *closure;
+    int            (*read)  (XcursorFile *file, unsigned char *buf, int len);
+    int            (*write) (XcursorFile *file, unsigned char *buf, int len);
+    int            (*seek)  (XcursorFile *file, long offset, int whence);
+};
+
+typedef struct _XcursorComments {
+    int                    ncomment;   /* number of comments */
+    XcursorComment  **comments;        /* array of XcursorComment pointers */
+} XcursorComments;
+
+#define XCURSOR_CORE_THEME  "core"
+
+_XFUNCPROTOBEGIN
+
+/*
+ * Manage Image objects
+ */
+XcursorImage *
+XcursorImageCreate (int width, int height);
+
+void
+XcursorImageDestroy (XcursorImage *image);
+
+/*
+ * Manage Images objects 
+ */
+XcursorImages *
+XcursorImagesCreate (int size);
+
+void
+XcursorImagesDestroy (XcursorImages *images);
+
+void
+XcursorImagesSetName (XcursorImages *images, const char *name);
+
+/*
+ * Manage Cursor objects
+ */
+XcursorCursors *
+XcursorCursorsCreate (Display *dpy, int size);
+
+void
+XcursorCursorsDestroy (XcursorCursors *cursors);
+
+/*
+ * Manage Animate objects
+ */
+XcursorAnimate *
+XcursorAnimateCreate (XcursorCursors *cursors);
+
+void
+XcursorAnimateDestroy (XcursorAnimate *animate);
+
+Cursor
+XcursorAnimateNext (XcursorAnimate *animate);
+
+/*
+ * Manage Comment objects
+ */
+XcursorComment *
+XcursorCommentCreate (XcursorUInt comment_type, int length);
+
+void
+XcursorCommentDestroy (XcursorComment *comment);
+
+XcursorComments *
+XcursorCommentsCreate (int size);
+
+void
+XcursorCommentsDestroy (XcursorComments *comments);
+
+/*
+ * XcursorFile/Image APIs
+ */
+XcursorImage *
+XcursorXcFileLoadImage (XcursorFile *file, int size);
+
+XcursorImages *
+XcursorXcFileLoadImages (XcursorFile *file, int size);
+
+XcursorImages *
+XcursorXcFileLoadAllImages (XcursorFile *file);
+
+XcursorBool
+XcursorXcFileLoad (XcursorFile     *file,
+                  XcursorComments  **commentsp,
+                  XcursorImages    **imagesp);
+
+XcursorBool
+XcursorXcFileSave (XcursorFile             *file, 
+                  const XcursorComments    *comments,
+                  const XcursorImages      *images);
+
+/*
+ * FILE/Image APIs
+ */
+XcursorImage *
+XcursorFileLoadImage (FILE *file, int size);
+
+XcursorImages *
+XcursorFileLoadImages (FILE *file, int size);
+
+XcursorImages *
+XcursorFileLoadAllImages (FILE *file);
+
+XcursorBool
+XcursorFileLoad (FILE              *file, 
+                XcursorComments    **commentsp, 
+                XcursorImages      **imagesp);
+
+XcursorBool
+XcursorFileSaveImages (FILE *file, const XcursorImages *images);
+
+XcursorBool
+XcursorFileSave (FILE *                        file, 
+                const XcursorComments  *comments,
+                const XcursorImages    *images);
+
+/*
+ * Filename/Image APIs
+ */
+XcursorImage *
+XcursorFilenameLoadImage (const char *filename, int size);
+
+XcursorImages *
+XcursorFilenameLoadImages (const char *filename, int size);
+
+XcursorImages *
+XcursorFilenameLoadAllImages (const char *filename);
+
+XcursorBool
+XcursorFilenameLoad (const char                *file,
+                    XcursorComments    **commentsp,
+                    XcursorImages      **imagesp);
+
+XcursorBool
+XcursorFilenameSaveImages (const char *filename, const XcursorImages *images);
+
+XcursorBool
+XcursorFilenameSave (const char                    *file, 
+                    const XcursorComments  *comments,
+                    const XcursorImages    *images);
+
+/*
+ * Library/Image APIs
+ */
+XcursorImage *
+XcursorLibraryLoadImage (const char *library, const char *theme, int size);
+
+XcursorImages *
+XcursorLibraryLoadImages (const char *library, const char *theme, int size);
+
+/*
+ * Library/shape API
+ */
+
+const char *
+XcursorLibraryPath (void);
+
+int
+XcursorLibraryShape (const char *library);
+    
+/*
+ * Image/Cursor APIs
+ */
+
+Cursor
+XcursorImageLoadCursor (Display *dpy, const XcursorImage *image);
+
+XcursorCursors *
+XcursorImagesLoadCursors (Display *dpy, const XcursorImages *images);
+
+Cursor
+XcursorImagesLoadCursor (Display *dpy, const XcursorImages *images);
+
+/*
+ * Filename/Cursor APIs
+ */
+Cursor
+XcursorFilenameLoadCursor (Display *dpy, const char *file);
+
+XcursorCursors *
+XcursorFilenameLoadCursors (Display *dpy, const char *file);
+
+/*
+ * Library/Cursor APIs
+ */
+Cursor
+XcursorLibraryLoadCursor (Display *dpy, const char *file);
+
+XcursorCursors *
+XcursorLibraryLoadCursors (Display *dpy, const char *file);
+
+/*
+ * Shape/Image APIs
+ */
+
+XcursorImage *
+XcursorShapeLoadImage (unsigned int shape, const char *theme, int size);
+
+XcursorImages *
+XcursorShapeLoadImages (unsigned int shape, const char *theme, int size);
+
+/*
+ * Shape/Cursor APIs
+ */
+Cursor
+XcursorShapeLoadCursor (Display *dpy, unsigned int shape);
+
+XcursorCursors *
+XcursorShapeLoadCursors (Display *dpy, unsigned int shape);
+
+/*
+ * This is the function called by Xlib when attempting to
+ * load cursors from XCreateGlyphCursor.  The interface must
+ * not change as Xlib loads 'libXcursor.so' instead of
+ * a specific major version
+ */
+Cursor
+XcursorTryShapeCursor (Display     *dpy,
+                      Font         source_font,
+                      Font         mask_font,
+                      unsigned int source_char,
+                      unsigned int mask_char,
+                      XColor _Xconst *foreground,
+                      XColor _Xconst *background);
+
+void
+XcursorNoticeCreateBitmap (Display     *dpy,
+                          Pixmap       pid,
+                          unsigned int width,
+                          unsigned int height);
+
+void
+XcursorNoticePutBitmap (Display            *dpy,
+                       Drawable    draw,
+                       XImage      *image);
+
+Cursor
+XcursorTryShapeBitmapCursor (Display           *dpy,
+                            Pixmap             source,
+                            Pixmap             mask,
+                            XColor             *foreground,
+                            XColor             *background,
+                            unsigned int       x,
+                            unsigned int       y);
+
+#define XCURSOR_BITMAP_HASH_SIZE    16
+
+void
+XcursorImageHash (XImage       *image, 
+                 unsigned char hash[XCURSOR_BITMAP_HASH_SIZE]);
+
+/*
+ * Display information APIs
+ */
+XcursorBool
+XcursorSupportsARGB (Display *dpy);
+
+XcursorBool
+XcursorSupportsAnim (Display *dpy);
+
+XcursorBool
+XcursorSetDefaultSize (Display *dpy, int size);
+
+int
+XcursorGetDefaultSize (Display *dpy);
+
+XcursorBool
+XcursorSetTheme (Display *dpy, const char *theme);
+
+char *
+XcursorGetTheme (Display *dpy);
+
+XcursorBool
+XcursorGetThemeCore (Display *dpy);
+
+XcursorBool
+XcursorSetThemeCore (Display *dpy, XcursorBool theme_core);
+
+_XFUNCPROTOEND
+
+#endif
diff --git a/man/Makefile.am b/man/Makefile.am
new file mode 100644 (file)
index 0000000..abb555d
--- /dev/null
@@ -0,0 +1,73 @@
+libmandir = $(LIB_MAN_DIR)
+
+libman_PRE = Xcursor.man
+libman_DATA = $(libman_PRE:man=@LIB_MAN_SUFFIX@)
+
+all-local: $(libman_DATA)
+
+EXTRA_DIST = $(libman_PRE)
+CLEANFILES = $(libman_DATA)
+
+SUFFIXES = .$(LIB_MAN_SUFFIX) .man
+
+# Strings to replace in man pages
+XORGRELSTRING = @PACKAGE_STRING@
+
+MAN_SUBSTS = \
+       -e 's|__xorgversion__|"$(XORGRELSTRING)"|' \
+       -e 's|__XCURSORPATH__|$(XCURSORPATH_LIST)|g' \
+       -e 's|__appmansuffix__|$(APP_MAN_SUFFIX)|g' \
+       -e 's|__libmansuffix__|$(LIB_MAN_SUFFIX)|g' \
+       -e 's|__adminmansuffix__|$(ADMIN_MAN_SUFFIX)|g' \
+       -e 's|__miscmansuffix__|$(MISC_MAN_SUFFIX)|g' \
+       -e 's|__filemansuffix__|$(FILE_MAN_SUFFIX)|g'
+
+.man.$(LIB_MAN_SUFFIX):
+       -rm -f $@
+       sed $(MAN_SUBSTS) < $< > $@
+
+# Generate man page shadow files
+
+LIB_MAN_DIR_SUFFIX = $(LIB_MAN_DIR:@mandir@/man%=%)
+libman_DATA += $(Xcursor_shadows:=.@LIB_MAN_SUFFIX@)
+BUILT_SOURCES = shadows.DONE
+CLEANFILES += shadows.DONE
+
+Xcursor_shadows = \
+       XcursorImageCreate \
+       XcursorImageDestroy \
+       XcursorImagesCreate \
+       XcursorImagesDestroy \
+       XcursorCursorsCreate \
+       XcursorCursorsDestroy \
+       XcursorXcFileLoadImage \
+       XcursorXcFileLoadImages \
+       XcursorXcFileLoadAllImages \
+       XcursorXcFileLoad \
+       XcursorXcFileSave \
+       XcursorFilenameLoadImage \
+       XcursorFilenameLoadImages \
+       XcursorFilenameLoadAllImages \
+       XcursorFilenameLoad \
+       XcursorFilenameSaveImages \
+       XcursorFilenameSave \
+       XcursorLibraryLoadImage \
+       XcursorLibraryLoadImages \
+       XcursorFilenameLoadCursor \
+       XcursorLibraryLoadCursor \
+       XcursorLibraryLoadCursors \
+       XcursorShapeLoadImage \
+       XcursorShapeLoadImages \
+       XcursorShapeLoadCursor \
+       XcursorShapeLoadCursors \
+       XcursorSupportsARGB \
+       XcursorSetDefaultSize \
+       XcursorGetDefaultSize \
+       XcursorSetTheme \
+       XcursorGetTheme
+
+shadows.DONE:
+       -rm -f $(Xcursor_shadows:=.@LIB_MAN_SUFFIX@)
+       (for i in $(Xcursor_shadows:=.@LIB_MAN_SUFFIX@) ; do \
+        echo .so man$(LIB_MAN_DIR_SUFFIX)/Xcursor.$(LIB_MAN_SUFFIX) > $$i; \
+        done)
diff --git a/man/Xcursor.man b/man/Xcursor.man
new file mode 100644 (file)
index 0000000..a16a7c1
--- /dev/null
@@ -0,0 +1,384 @@
+.\"
+.\" Copyright © 2002 Keith Packard
+.\"
+.\" Permission to use, copy, modify, distribute, and sell this software and its
+.\" documentation for any purpose is hereby granted without fee, provided that
+.\" the above copyright notice appear in all copies and that both that
+.\" copyright notice and this permission notice appear in supporting
+.\" documentation, and that the name of Keith Packard not be used in
+.\" advertising or publicity pertaining to distribution of the software without
+.\" specific, written prior permission.  Keith Packard makes no
+.\" representations about the suitability of this software for any purpose.  It
+.\" is provided "as is" without express or implied warranty.
+.\"
+.\" KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+.\" INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+.\" EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+.\" CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+.\" DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+.\" TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+.\" PERFORMANCE OF THIS SOFTWARE.
+.\"
+.de TQ
+.br
+.ns
+.TP \\$1
+..
+.TH XCURSOR __libmansuffix__ __xorgversion__ "Keith Packard"
+
+.SH NAME
+XCURSOR \- Cursor management library
+
+.SH SYNOPSIS
+.nf
+.B #include <X11/Xcursor/Xcursor.h>
+.fi
+.SH DESCRIPTION
+.B Xcursor
+is a simple library designed to help locate and load cursors.  Cursors can
+be loaded from files or memory.  A library of common cursors exists which
+map to the standard X cursor names.  Cursors can exist in several sizes and
+the library automatically picks the best size.
+
+.SH FUNCTIONAL OVERVIEW
+Xcursor is built in a couple of layers; at the bottom layer is code which
+can load cursor images from files.  Above that is a layer which locates
+cursor files based on the library path and theme.  At the top is a layer
+which builds cursors either out of an image loaded from a file or one of the
+standard X cursors.  When using images loaded from files, Xcursor prefers
+to use the Render extension CreateCursor request if supported by the X
+server.  Where not supported, Xcursor maps the cursor image to a standard X
+cursor and uses the core CreateCursor request.
+
+.SS CURSOR FILES
+Xcursor defines a new format for cursors on disk.  Each file holds
+one or more cursor images.  Each cursor image is tagged with a nominal size
+so that the best size can be selected automatically.  Multiple cursors of
+the same nominal size can be loaded together; applications are expected to
+use them as an animated sequence.
+.P
+Cursor files are stored as a header containing a table of contents followed
+by a sequence of chunks.  The table of contents indicates the type, subtype
+and position in the file of each chunk.  The file header looks like:
+.LP
+.in +.2i
+\fImagic\fP\^: CARD32 'Xcur' (0x58, 0x63, 0x75, 0x72)
+.br
+\fIheader\fP\^: CARD32 bytes in this header
+.br
+\fIversion\fP\^: CARD32 file version number
+.br
+\fIntoc\fP\^: CARD32 number of toc entries
+.br
+\fItoc\fP\^: LISTofTOC table of contents
+.in -.2i
+.P
+Each table of contents entry looks like:
+.LP
+.in +.2i
+\fItype\fP\^: CARD32 entry type
+.br
+\fIsubtype\fP\^: CARD32 type-specific label - size for images
+.br
+\fIposition\fP\^: CARD32 absolute byte position of table in file
+.in -.2i
+.P
+.P
+Each chunk in the file has set of common header fields followed by
+additional type-specific fields:
+.LP
+.in +.2i
+\fIheader\fP\^: CARD32 bytes in chunk header (including type-specific fields)
+.br
+\fItype\fP\^: CARD32 must match type in TOC for this chunk
+.br
+\fIsubtype\fP\^: CARD32 must match subtype in TOC for this chunk
+.br
+\fIversion\fP\^: CARD32 version number for this chunk type
+.in -.2i
+.P
+There are currently two chunk types defined for cursor files; comments and
+images.  Comments look like:
+.LP
+.in +.2i
+\fIheader\fP\^: 20 Comment headers are 20 bytes
+.br
+\fItype\fP\^: 0xfffe0001 Comment type is 0xfffe0001
+.br
+\fIsubtype\fP\^: { 1 (COPYRIGHT), 2 (LICENSE), 3 (OTHER) }
+.br
+\fIversion\fP\^: 1
+.br
+\fIlength\fP\^: CARD32 byte length of UTF-8 string
+.br
+\fIstring\fP\^: LISTofCARD8 UTF-8 string
+.in -.2i
+.P
+Images look like:
+.LP
+.in +.2i
+\fIheader\fP\^: 36 Image headers are 36 bytes
+.br
+\fItype\fP\^: 0xfffd0002 Image type is 0xfffd0002
+.br
+\fIsubtype\fP\^: CARD32 Image subtype is the nominal size
+.br
+\fIversion\fP\^: 1
+.br
+\fIwidth\fP\^: CARD32 Must be less than or equal to 0x7fff
+.br
+\fIheight\fP\^: CARD32 Must be less than or equal to 0x7fff
+.br
+\fIxhot\fP\^: CARD32 Must be less than or equal to width
+.br
+\fIyhot\fP\^: CARD32 Must be less than or equal to height
+.br
+\fIdelay\fP\^: CARD32 Delay between animation frames in milliseconds
+.br
+\fIpixels\fP\^: LISTofCARD32 Packed ARGB format pixels
+.in -.2i
+
+.SS THEMES
+Xcursor (mostly) follows the freedesktop.org spec for theming icons.  The
+default search path it uses is __XCURSORPATH__.  Within each of these
+directories, it searches for a directory using the theme name.  Within the
+theme directory, it looks for cursor files in the 'cursors' subdirectory.
+It uses the first cursor file found along  the path.
+.PP
+If necessary, Xcursor also looks for a "index.theme" file in each theme
+directory to find inherited themes and searches along the path for those
+themes as well.
+.PP
+If no theme is set, or if no cursor is found for the specified theme,
+Xcursor checks the "default" theme.
+
+.SH DATATYPES
+
+.TP
+.B XcursorImage
+holds a single cursor image in memory.  Each pixel in the cursor is a 32-bit
+value containing ARGB with A in the high byte.
+.sp
+.nf
+.ft CR
+    typedef struct _XcursorImage {
+        XcursorDim     size;       /\(** nominal size for matching */
+        XcursorDim     width;      /\(** actual width */
+        XcursorDim     height;     /\(** actual height */
+        XcursorDim     xhot;       /\(** hot spot x (must be inside image) */
+        XcursorDim     yhot;       /\(** hot spot y (must be inside image) */
+        XcursorPixel    *pixels;    /\(** pointer to pixels */
+    } XcursorImage;
+.ft
+.fi
+
+.TP
+.B XcursorImages
+holds multiple XcursorImage structures.  They're all freed when the
+XcursorImages is freed.
+.sp
+.nf
+.ft CR
+    typedef struct _XcursorImages {
+        int             nimage;            /\(** number of images */
+        XcursorImage    **images;   /\(** array of XcursorImage pointers */
+    } XcursorImages;
+.ft
+.fi
+
+.TP
+.B XcursorCursors
+Holds multiple Cursor objects.  They're all freed when the XcursorCursors is
+freed.  These are reference counted so that multiple XcursorAnimate
+structures can use the same XcursorCursors.
+.sp
+.nf
+.ft CR
+    typedef struct _XcursorCursors {
+        Display     *dpy;      /\(** Display holding cursors */
+        int        ref;        /\(** reference count */
+        int        ncursor;    /\(** number of cursors */
+        Cursor     *cursors;   /\(** array of cursors */
+    } XcursorCursors;
+.ft
+.fi
+
+.TP
+.B XcursorAnimate
+References a set of cursors and a sequence within that set.  Multiple
+XcursorAnimate structures may reference the same XcursorCursors; each
+holds a reference which is removed when the XcursorAnimate is freed.
+.sp
+.nf
+.ft CR
+    typedef struct _XcursorAnimate {
+        XcursorCursors   *cursors;  /\(** list of cursors to use */
+        int             sequence;  /\(** which cursor is next */
+    } XcursorAnimate;
+.ft
+.fi
+
+.TP
+.B XcursorFile
+Xcursor provides an abstract API for accessing the file data.  Xcursor
+provides a stdio implementation of this abstract API; applications
+are free to create additional implementations.  These functions
+parallel the stdio functions in return value and expected argument values;
+the read and write functions flip the arguments around to match the POSIX
+versions.
+.sp
+.nf
+.ft CR
+    typedef struct _XcursorFile {
+        void   *closure;
+        int    (*read)  (XcursorFile *file, unsigned char *buf, int len);
+        int    (*write) (XcursorFile *file, unsigned char *buf, int len);
+        int    (*seek)  (XcursorFile *file, long offset, int whence);
+    };
+.ft
+.fi
+
+.SH FUNCTIONS
+
+.SS Object Management
+.TP
+XcursorImage *XcursorImageCreate (int width, int height)
+.TQ
+void XcursorImageDestroy (XcursorImage *image)
+Allocate and free images.  On allocation, the hotspot and the pixels are
+left uninitialized.  The size is set to the maximum of width and height.
+
+.TP
+XcursorImages *XcursorImagesCreate (int size)
+.TQ
+void XcursorImagesDestroy (XcursorImages *images)
+Allocate and free arrays to hold multiple cursor images.  On allocation,
+nimage is set to zero.
+
+.TP
+XcursorCursors *XcursorCursorsCreate (Display *dpy, int size)
+.TQ
+void XcursorCursorsDestroy (XcursorCursors *cursors)
+Allocate and free arrays to hold multiple cursors.  On allocation,
+ncursor is set to zero, ref is set to one.
+
+.SS Reading and writing images.
+
+.TP
+XcursorImage *XcursorXcFileLoadImage (XcursorFile *file, int size)
+.TQ
+XcursorImages *XcursorXcFileLoadImages (XcursorFile *file, int size)
+.TQ
+XcursorImages *XcursorXcFileLoadAllImages (XcursorFile *file)
+.TQ
+XcursorBool XcursorXcFileLoad (XcursorFile *file, XcursorComments **commentsp, XcursorImages **imagesp)
+.TQ
+XcursorBool XcursorXcFileSave (XcursorFile *file, const XcursorComments *comments, const XcursorImages *images)
+These read and write cursors from an XcursorFile handle.  After reading, the
+file pointer will be left at some random place in the file.
+                  
+.TP
+XcursorImage *XcursorFileLoadImage (FILE *file, int size)
+.TQ
+XcursorImages *XcursorFileLoadImages (FILE *file, int size)
+.TQ
+XcursorImages *XcursorFileLoadAllImages (FILE *file)
+.TQ
+XcursorBool XcursorFileLoad (FILE *file, XcursorComments **commentsp, XcursorImages **imagesp)
+.TQ
+XcursorBool XcursorFileSaveImages (FILE *file, const XcursorImages *images)
+.TQ
+XcursorBool XcursorFileSave (FILE * file, const XcursorComments *comments, const XcursorImages *images)
+These read and write cursors from a stdio FILE handle.  Writing flushes
+before returning so that any errors should be detected.
+
+.TP
+XcursorImage *XcursorFilenameLoadImage (const char *filename, int size)
+.TQ
+XcursorImages *XcursorFilenameLoadImages (const char *filename, int size)
+.TQ
+XcursorImages *XcursorFilenameLoadAllImages (FILE *file)
+.TQ
+XcursorBool XcursorFilenameLoad (const char *file, XcursorComments **commentsp, XcursorImages **imagesp)
+.TQ
+XcursorBool XcursorFilenameSaveImages (const char *filename, const XcursorImages *images)
+.TQ
+XcursorBool XcursorFilenameSave (const char *file, const XcursorComments *comments, const XcursorImages *images)
+These parallel the stdio FILE interfaces above, but take filenames.
+
+.SS Reading library images
+.TP
+XcursorImage *XcursorLibraryLoadImage (const char *name, const char *theme, int size)
+.TQ
+XcursorImages *XcursorLibraryLoadImages (const char *name, const char *theme, int size)
+These search the library path, loading the first file found.  If 'theme' is
+not NULL, these functions first try appending -theme to name and then
+name alone.
+
+.SS Cursor APIs
+
+.TP
+Cursor XcursorFilenameLoadCursor (Display *dpy, const char *file)
+.TQ
+XcursorCursors *XcursorFilenameLoadCursors (Display *dpy, const char *file)
+These load cursors from the specified file.
+
+.TP
+Cursor XcursorLibraryLoadCursor (Display *dpy, const char *name)
+.TQ
+XcursorCursors *XcursorLibraryLoadCursors (Display *dpy, const char *name)
+These load cursors using the specified library name.  The theme
+comes from the display.
+
+.SS X Cursor Name APIs
+
+.TP
+XcursorImage *XcursorShapeLoadImage (unsigned int shape, const char *theme, int size)
+.TQ
+XcursorImages *XcursorShapeLoadImages (unsigned int shape, const char *theme, int size)
+These map 'shape' to a library name using the standard X cursor names and
+then load the images.
+
+.TP
+Cursor XcursorShapeLoadCursor (Display *dpy, unsigned int shape)
+.TQ
+XcursorCursors *XcursorShapeLoadCursors (Display *dpy, unsigned int shape)
+These map 'shape' to a library name and then load the cursors.
+
+.SS Display Information APIs
+
+.TP
+XcursorBool XcursorSupportsARGB (Display *dpy)
+Returns whether the display supports ARGB cursors or whether cursors will be
+mapped to a core X cursor.
+
+.TP
+XcursorBool XcursorSetDefaultSize (Display *dpy, int size)
+Sets the default size for cursors on the specified display. When loading
+cursors, those whose nominal size is closest to this size will be preferred.
+
+.TP
+int XcursorGetDefaultSize (Display *dpy)
+Gets the default cursor size.
+
+.TP
+XcursorBool XcursorSetTheme (Display *dpy, const char *theme)
+Sets the current theme name.
+
+.TP
+char *XcursorGetTheme (Display *dpy)
+Gets the current theme name.
+
+.SH "ENVIRONMENT VARIABLES"
+.TP 15
+.B XCURSOR_PATH
+This variable sets the list of paths to look for cursors in.   
+Directories in this path are separated by colons (:).
+
+.SH RESTRICTIONS
+.B Xcursor
+will probably change radically in the future; weak attempts will be made to
+retain some level of source-file compatibility.
+
+.SH AUTHOR
+Keith Packard
diff --git a/man/XcursorCursorsCreate.man b/man/XcursorCursorsCreate.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorCursorsDestroy.man b/man/XcursorCursorsDestroy.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameLoad.man b/man/XcursorFilenameLoad.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameLoadAllImages.man b/man/XcursorFilenameLoadAllImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameLoadCursor.man b/man/XcursorFilenameLoadCursor.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameLoadImage.man b/man/XcursorFilenameLoadImage.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameLoadImages.man b/man/XcursorFilenameLoadImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameSave.man b/man/XcursorFilenameSave.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorFilenameSaveImages.man b/man/XcursorFilenameSaveImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorGetDefaultSize.man b/man/XcursorGetDefaultSize.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorGetTheme.man b/man/XcursorGetTheme.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorImageCreate.man b/man/XcursorImageCreate.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorImageDestroy.man b/man/XcursorImageDestroy.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorImagesCreate.man b/man/XcursorImagesCreate.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorImagesDestroy.man b/man/XcursorImagesDestroy.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorLibraryLoadCursor.man b/man/XcursorLibraryLoadCursor.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorLibraryLoadCursors.man b/man/XcursorLibraryLoadCursors.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorLibraryLoadImage.man b/man/XcursorLibraryLoadImage.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorLibraryLoadImages.man b/man/XcursorLibraryLoadImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorSetDefaultSize.man b/man/XcursorSetDefaultSize.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorSetTheme.man b/man/XcursorSetTheme.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorShapeLoadCursor.man b/man/XcursorShapeLoadCursor.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorShapeLoadCursors.man b/man/XcursorShapeLoadCursors.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorShapeLoadImage.man b/man/XcursorShapeLoadImage.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorShapeLoadImages.man b/man/XcursorShapeLoadImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorSupportsARGB.man b/man/XcursorSupportsARGB.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorXcFileLoad.man b/man/XcursorXcFileLoad.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorXcFileLoadAllImages.man b/man/XcursorXcFileLoadAllImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorXcFileLoadImage.man b/man/XcursorXcFileLoadImage.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorXcFileLoadImages.man b/man/XcursorXcFileLoadImages.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/man/XcursorXcFileSave.man b/man/XcursorXcFileSave.man
new file mode 100755 (executable)
index 0000000..690dab2
--- /dev/null
@@ -0,0 +1 @@
+.so man__libmansuffix__/Xcursor.__libmansuffix__
diff --git a/packaging/libXcursor.spec b/packaging/libXcursor.spec
new file mode 100644 (file)
index 0000000..64ca445
--- /dev/null
@@ -0,0 +1,70 @@
+Name:       libXcursor
+Summary:    X cursor management library
+Version:    1.1.11
+Release:    1
+Group:      System/Libraries
+License:    MIT
+Source0:    libXcursor-%{version}.tar.gz
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  pkgconfig(x11)
+BuildRequires:  pkgconfig(xproto)
+BuildRequires:  pkgconfig(xfixes)
+BuildRequires:  pkgconfig(xrender)
+BuildRequires:  pkgconfig(xorg-macros)
+
+%description
+Xcursor is a simple library designed to help locate and load cursors for the
+X Window System. Cursors can be loaded from files or memory and can exist in
+several sizes; the library automatically picks the best size. When using
+images loaded from files, Xcursor prefers to use the Render extension's
+CreateCursor request for rendering cursors. Where the Render extension is
+not supported, Xcursor maps the cursor image to a standard X cursor and uses
+the core X protocol CreateCursor request.
+
+
+
+%package devel
+Summary:    X cursor management library (development files)
+Group:      TO_BE/FILLED
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Header files and a static version of the X cursor management library are
+provided by this package.
+.
+See the libxcursor1 package for further information.
+
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+chmod +x autogen.sh
+libtoolize -f -c
+./autogen.sh
+%configure --disable-static
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+rm -rf %{buildroot}/usr/share/man
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+/usr/lib/*.so.*
+
+
+%files devel
+/usr/include/*
+/usr/lib/*.so
+/usr/lib/pkgconfig/xcursor.pc
+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755 (executable)
index 0000000..a55b8d6
--- /dev/null
@@ -0,0 +1,31 @@
+lib_LTLIBRARIES = libXcursor.la
+
+libXcursor_la_SOURCES = xcursorint.h cursor.c display.c file.c library.c xlib.c
+
+ICONDIR=@ICONDIR@
+XCURSORPATH=@XCURSORPATH@
+
+libXcursor_la_LIBADD = $(XCURSOR_LIBS)
+AM_CFLAGS = \
+       $(XCURSOR_CFLAGS) \
+       $(CWARNFLAGS)\
+       -DICONDIR=\"$(ICONDIR)\" \
+       -DXCURSORPATH=\"$(XCURSORPATH)\"
+
+INCLUDES = -I$(top_srcdir)/include/X11/Xcursor
+
+#
+# Shared library version info.  This is not the same as the package version
+#
+libXcursor_la_LDFLAGS = -version-number 1:0:2 -no-undefined
+
+libXcursorincludedir = $(includedir)/X11/Xcursor
+libXcursorinclude_HEADERS = $(top_srcdir)/include/X11/Xcursor/Xcursor.h 
+
+if LINT
+ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+               $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
+
+lint:
+       $(LINT) $(ALL_LINT_FLAGS) $(libXcursor_la_SOURCES) $(XCURSOR_LIBS)
+endif LINT
diff --git a/src/cursor.c b/src/cursor.c
new file mode 100644 (file)
index 0000000..ac1b2c4
--- /dev/null
@@ -0,0 +1,819 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xcursorint.h"
+#include <X11/Xlibint.h>
+#include <X11/Xutil.h>
+
+XcursorCursors *
+XcursorCursorsCreate (Display *dpy, int size)
+{
+    XcursorCursors  *cursors;
+
+    cursors = malloc (sizeof (XcursorCursors) +
+                     size * sizeof (Cursor));
+    if (!cursors)
+       return NULL;
+    cursors->ref = 1;
+    cursors->dpy = dpy;
+    cursors->ncursor = 0;
+    cursors->cursors = (Cursor *) (cursors + 1);
+    return cursors;
+}
+
+void
+XcursorCursorsDestroy (XcursorCursors *cursors)
+{
+    int            n;
+
+    if (!cursors)
+      return;
+
+    --cursors->ref;
+    if (cursors->ref > 0)
+       return;
+    
+    for (n = 0; n < cursors->ncursor; n++)
+       XFreeCursor (cursors->dpy, cursors->cursors[n]);
+    free (cursors);
+}
+
+XcursorAnimate *
+XcursorAnimateCreate (XcursorCursors *cursors)
+{
+    XcursorAnimate  *animate;
+
+    animate = malloc (sizeof (XcursorAnimate));
+    if (!animate)
+       return NULL;
+    animate->cursors = cursors;
+    cursors->ref++;
+    animate->sequence = 0;
+    return animate;
+}
+
+void
+XcursorAnimateDestroy (XcursorAnimate *animate)
+{
+    if (!animate)
+      return;
+
+    XcursorCursorsDestroy (animate->cursors);
+    free (animate);
+}
+
+Cursor
+XcursorAnimateNext (XcursorAnimate *animate)
+{
+    Cursor  cursor = animate->cursors->cursors[animate->sequence++];
+
+    if (animate->sequence >= animate->cursors->ncursor)
+       animate->sequence = 0;
+    return cursor;
+}
+
+static int
+nativeByteOrder (void)
+{
+    int        x = 1;
+
+    return (*((char *) &x) == 1) ? LSBFirst : MSBFirst;
+}
+
+static XcursorUInt
+_XcursorPixelBrightness (XcursorPixel p)
+{
+    XcursorPixel    alpha = p >> 24;
+    XcursorPixel    r, g, b;
+
+    if (!alpha)
+       return 0;
+    r = ((p >> 8) & 0xff00) / alpha;
+    if (r > 0xff) r = 0xff;
+    g = ((p >> 0) & 0xff00) / alpha;
+    if (g > 0xff) g = 0xff;
+    b = ((p << 8) & 0xff00) / alpha;
+    if (b > 0xff) b = 0xff;
+    return (r * 153 + g * 301 + b * 58) >> 9;
+}
+
+static unsigned short
+_XcursorDivideAlpha (XcursorUInt value, XcursorUInt alpha)
+{
+    if (!alpha)
+       return 0;
+    value = value * 255 / alpha;
+    if (value > 255)
+       value = 255;
+    return value | (value << 8);
+}
+
+static void
+_XcursorPixelToColor (XcursorPixel p, XColor *color)
+{
+    XcursorPixel    alpha = p >> 24;
+
+    color->pixel = 0;
+    color->red =   _XcursorDivideAlpha ((p >> 16) & 0xff, alpha);
+    color->green = _XcursorDivideAlpha ((p >>  8) & 0xff, alpha);
+    color->blue =  _XcursorDivideAlpha ((p >>  0) & 0xff, alpha);
+    color->flags = DoRed|DoGreen|DoBlue;
+}
+
+#undef DEBUG_IMAGE
+#ifdef DEBUG_IMAGE
+static void
+_XcursorDumpImage (XImage *image)
+{
+    FILE    *f = fopen ("/tmp/images", "a");
+    int            x, y;
+    if (!f)
+       return;
+    fprintf (f, "%d x %x\n", image->width, image->height);
+    for (y = 0; y < image->height; y++)
+    {
+       for (x = 0; x < image->width; x++)
+           fprintf (f, "%c", XGetPixel (image, x, y) ? '*' : ' ');
+       fprintf (f, "\n");
+    }
+    fflush (f);
+    fclose (f);
+}
+
+static void
+_XcursorDumpColor (XColor *color, char *name)
+{
+    FILE    *f = fopen ("/tmp/images", "a");
+    fprintf (f, "%s: %x %x %x\n", name,
+            color->red, color->green, color->blue);
+    fflush (f);
+    fclose (f);
+}
+#endif
+
+static int
+_XcursorCompareRed (const void *a, const void *b)
+{
+    const XcursorPixel    *ap = a, *bp = b;
+
+    return (int) (((*ap >> 16) & 0xff) - ((*bp >> 16) & 0xff));
+}
+
+static int
+_XcursorCompareGreen (const void *a, const void *b)
+{
+    const XcursorPixel    *ap = a, *bp = b;
+
+    return (int) (((*ap >> 8) & 0xff) - ((*bp >> 8) & 0xff));
+}
+
+static int
+_XcursorCompareBlue (const void *a, const void *b)
+{
+    const XcursorPixel    *ap = a, *bp = b;
+
+    return (int) (((*ap >> 0) & 0xff) - ((*bp >> 0) & 0xff));
+}
+
+static XcursorPixel
+_XcursorAverageColor (XcursorPixel *pixels, int npixels)
+{
+    XcursorPixel    p;
+    XcursorPixel    red, green, blue;
+    int                    n = npixels;
+
+    blue = green = red = 0;
+    while (n--)
+    {
+       p = *pixels++;
+       red += (p >> 16) & 0xff;
+       green += (p >> 8) & 0xff;
+       blue += (p >> 0) & 0xff;
+    }
+    if (!n)
+       return 0;
+    return (0xff << 24) | ((red/npixels) << 16) | ((green/npixels) << 8) | (blue/npixels);
+}
+
+typedef struct XcursorCoreCursor {
+    XImage  *src_image;
+    XImage  *msk_image;
+    XColor  on_color;
+    XColor  off_color;
+} XcursorCoreCursor;
+
+static Bool
+_XcursorHeckbertMedianCut (const XcursorImage *image, XcursorCoreCursor *core)
+{
+    XImage         *src_image = core->src_image, *msk_image = core->msk_image;
+    int                    npixels = image->width * image->height;
+    int                    ncolors;
+    int                    n;
+    XcursorPixel    *po, *pn, *pc;
+    XcursorPixel    p;
+    XcursorPixel    red, green, blue, alpha;
+    XcursorPixel    max_red, min_red, max_green, min_green, max_blue, min_blue;
+    XcursorPixel    *temp, *pixels, *colors;
+    int                    split;
+    XcursorPixel    leftColor, centerColor, rightColor;
+    int                    (*compare) (const void *, const void *);
+    int                    x, y;
+    
+    /*
+     * Temp space for converted image and converted colors
+     */
+    temp = malloc (npixels * sizeof (XcursorPixel) * 2);
+    if (!temp)
+       return False;
+    
+    pixels = temp;
+    colors = pixels + npixels;
+    
+    /*
+     * Convert to 2-value alpha and build
+     * array of opaque color values and an
+     */
+    po = image->pixels;
+    pn = pixels;
+    pc = colors;
+    max_blue = max_green = max_red = 0;
+    min_blue = min_green = min_red = 255;
+    n = npixels;
+    while (n--)
+    {
+       p = *po++;
+       alpha = (p >> 24) & 0xff;
+       red = (p >> 16) & 0xff;
+       green = (p >> 8) & 0xff;
+       blue = (p >> 0) & 0xff;
+       if (alpha >= 0x80)
+       {
+           red = red * 255 / alpha;
+           green = green * 255 / alpha;
+           blue = blue * 255 / alpha;
+           if (red < min_red) min_red = red;
+           if (red > max_red) max_red = red;
+           if (green < min_green) min_green = green;
+           if (green > max_green) max_green = green;
+           if (blue < min_blue) min_blue = blue;
+           if (blue > max_blue) max_blue = blue;
+           p = ((0xff << 24) | (red << 16) | 
+                (green << 8) | (blue << 0));
+           *pc++ = p;
+       }
+       else
+           p = 0;
+       *pn++ = p;
+    }
+    ncolors = pc - colors;
+    
+    /*
+     * Compute longest dimension and sort
+     */
+    if ((max_green - min_green) >= (max_red - min_red) &&
+       (max_green - min_green) >= (max_blue - min_blue))
+       compare = _XcursorCompareGreen;
+    else if ((max_red - min_red) >= (max_blue - min_blue))
+       compare = _XcursorCompareRed;
+    else
+       compare = _XcursorCompareBlue;
+    qsort (colors, ncolors, sizeof (XcursorPixel), compare);
+    /*
+     * Compute average colors on both sides of the cut
+     */
+    split = ncolors >> 1;
+    leftColor  = _XcursorAverageColor (colors, split);
+    centerColor = colors[split];
+    rightColor = _XcursorAverageColor (colors + split, ncolors - split);
+    /*
+     * Select best color for each pixel
+     */
+    pn = pixels;
+    for (y = 0; y < image->height; y++)
+       for (x = 0; x < image->width; x++)
+       {
+           p = *pn++;
+           if (p & 0xff000000)
+           {
+               XPutPixel (msk_image, x, y, 1);
+               if ((*compare) (&p, &centerColor) >= 0)
+                   XPutPixel (src_image, x, y, 0);
+               else
+                   XPutPixel (src_image, x, y, 1);
+           }
+           else
+           {
+               XPutPixel (msk_image, x, y, 0);
+               XPutPixel (src_image, x, y, 0);
+           }
+       }
+    free (temp);
+    _XcursorPixelToColor (rightColor, &core->off_color);
+    _XcursorPixelToColor (leftColor, &core->on_color);
+    return True;
+}
+
+#if 0
+#define DITHER_DIM  4
+static XcursorPixel orderedDither[4][4] = {
+    {  1,  9,  3, 11 },
+    { 13,  5, 15,  7 },
+    {  4, 12,  2, 10 },
+    { 16,  8, 14,  6 }
+};
+#else
+#define DITHER_DIM 2
+static XcursorPixel orderedDither[2][2] = {
+    {  1,  3,  },
+    {  4,  2,  },
+};
+#endif
+
+#define DITHER_SIZE  ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1)
+
+static Bool
+_XcursorBayerOrderedDither (const XcursorImage *image, XcursorCoreCursor *core)
+{
+    int                    x, y;
+    XcursorPixel    *pixel, p;
+    XcursorPixel    a, i, d;
+
+    pixel = image->pixels;
+    for (y = 0; y < image->height; y++)
+       for (x = 0; x < image->width; x++)
+       {
+           p = *pixel++;
+           a = ((p >> 24) * DITHER_SIZE + 127) / 255;
+           i = (_XcursorPixelBrightness (p) * DITHER_SIZE + 127) / 255;
+           d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)];
+           if (a > d)
+           {
+               XPutPixel (core->msk_image, x, y, 1);
+               if (i > d)
+                   XPutPixel (core->src_image, x, y, 0);   /* white */
+               else
+                   XPutPixel (core->src_image, x, y, 1);   /* black */
+           }
+           else
+           {
+               XPutPixel (core->msk_image, x, y, 0);
+               XPutPixel (core->src_image, x, y, 0);
+           }
+       }
+    core->on_color.red = 0;
+    core->on_color.green = 0;
+    core->on_color.blue = 0;
+    core->off_color.red = 0xffff;
+    core->off_color.green = 0xffff;
+    core->off_color.blue = 0xffff;
+    return True;
+}
+
+static Bool
+_XcursorFloydSteinberg (const XcursorImage *image, XcursorCoreCursor *core)
+{
+    int                    *aPicture, *iPicture, *aP, *iP;
+    XcursorPixel    *pixel, p;
+    int                    aR, iR, aA, iA;
+    int                    npixels = image->width * image->height;
+    int                    n;
+    int                    right = 1;
+    int                    belowLeft = image->width - 1;
+    int                    below = image->width;
+    int                    belowRight = image->width + 1;
+    int                    iError, aError;
+    int                    iErrorRight, aErrorRight;
+    int                    iErrorBelowLeft, aErrorBelowLeft;
+    int                    iErrorBelow, aErrorBelow;
+    int                    iErrorBelowRight, aErrorBelowRight;
+    int                    x, y;
+    int                    max_inten, min_inten, mean_inten;
+
+    iPicture = malloc (npixels * sizeof (int) * 2);
+    if (!iPicture)
+       return False;
+    aPicture = iPicture + npixels;
+
+    /*
+     * Compute raw gray and alpha arrays
+     */
+    pixel = image->pixels;
+    iP = iPicture;
+    aP = aPicture;
+    n = npixels;
+    max_inten = 0;
+    min_inten = 0xff;
+    while (n--)
+    {
+       p = *pixel++;
+       *aP++ = (int) (p >> 24);
+       iR = (int) _XcursorPixelBrightness (p);
+       if (iR > max_inten) max_inten = iR;
+       if (iR < min_inten) min_inten = iR;
+       *iP++ = iR;
+    }
+    /*
+     * Draw the image while diffusing the error
+     */
+    iP = iPicture;
+    aP = aPicture;
+    mean_inten = (max_inten + min_inten + 1) >> 1;
+    for (y = 0; y < image->height; y++)
+       for (x = 0; x < image->width; x++)
+       {
+           aR = *aP;
+           iR = *iP;
+           if (aR >= 0x80)
+           {
+               XPutPixel (core->msk_image, x, y, 1);
+               aA = 0xff;
+           }
+           else
+           {
+               XPutPixel (core->msk_image, x, y, 0);
+               aA = 0x00;
+           }
+           if (iR >= mean_inten)
+           {
+               XPutPixel (core->src_image, x, y, 0);
+               iA = max_inten;
+           }
+           else
+           {
+               XPutPixel (core->src_image, x, y, 1);
+               iA = min_inten;
+           }
+           iError = iR - iA;
+           aError = aR - aA;
+           iErrorRight = (iError * 7) >> 4;
+           iErrorBelowLeft = (iError * 3) >> 4;
+           iErrorBelow = (iError * 5) >> 4;
+           iErrorBelowRight = (iError - iErrorRight - 
+                               iErrorBelowLeft - iErrorBelow);
+           aErrorRight = (aError * 7) >> 4;
+           aErrorBelowLeft = (aError * 3) >> 4;
+           aErrorBelow = (aError * 5) >> 4;
+           aErrorBelowRight = (aError - aErrorRight - 
+                               aErrorBelowLeft - aErrorBelow);
+           if (x < image->width - 1)
+           {
+               iP[right] += iErrorRight; 
+               aP[right] += aErrorRight;
+           }
+           if (y < image->height - 1)
+           {
+               if (x)
+               {
+                   iP[belowLeft] += iErrorBelowLeft;
+                   aP[belowLeft] += aErrorBelowLeft;
+               }
+               iP[below] += iErrorBelow;
+               aP[below] += aErrorBelow;
+               if (x < image->width - 1)
+               {
+                   iP[belowRight] += iErrorBelowRight;
+                   aP[belowRight] += aErrorBelowRight;
+               }
+           }
+           aP++;
+           iP++;
+       }
+    free (iPicture);
+    core->on_color.red =
+    core->on_color.green = 
+    core->on_color.blue = (min_inten | min_inten << 8);
+    core->off_color.red = 
+    core->off_color.green =
+    core->off_color.blue = (max_inten | max_inten << 8);
+    return True;
+}
+
+static Bool
+_XcursorThreshold (const XcursorImage *image, XcursorCoreCursor *core)
+{
+    XcursorPixel    *pixel, p;
+    int                    x, y;
+
+    /*
+     * Draw the image, picking black for dark pixels and white for light
+     */
+    pixel = image->pixels;
+    for (y = 0; y < image->height; y++)
+       for (x = 0; x < image->width; x++)
+       {
+           p = *pixel++;
+           if ((p >> 24) >= 0x80)
+           {
+               XPutPixel (core->msk_image, x, y, 1);
+               if (_XcursorPixelBrightness (p) > 0x80)
+                   XPutPixel (core->src_image, x, y, 0);
+               else
+                   XPutPixel (core->src_image, x, y, 1);
+           }
+           else
+           {
+               XPutPixel (core->msk_image, x, y, 0);
+               XPutPixel (core->src_image, x, y, 0);
+           }
+       }
+    core->on_color.red =
+    core->on_color.green = 
+    core->on_color.blue = 0;
+    core->off_color.red = 
+    core->off_color.green =
+    core->off_color.blue = 0xffff;
+    return True;
+}
+
+Cursor
+XcursorImageLoadCursor (Display *dpy, const XcursorImage *image)
+{
+    Cursor  cursor;
+    
+#if RENDER_MAJOR > 0 || RENDER_MINOR >= 5
+    if (XcursorSupportsARGB (dpy))
+    {
+       XImage              ximage;
+       int                 screen = DefaultScreen (dpy);
+       Pixmap              pixmap;
+       Picture             picture;
+       GC                  gc;
+       XRenderPictFormat   *format;
+
+       ximage.width = image->width;
+       ximage.height = image->height;
+       ximage.xoffset = 0;
+       ximage.format = ZPixmap;
+       ximage.data = (char *) image->pixels;
+       ximage.byte_order = nativeByteOrder ();
+       ximage.bitmap_unit = 32;
+       ximage.bitmap_bit_order = ximage.byte_order;
+       ximage.bitmap_pad = 32;
+       ximage.depth = 32;
+       ximage.bits_per_pixel = 32;
+       ximage.bytes_per_line = image->width * 4;
+       ximage.red_mask = 0xff0000;
+       ximage.green_mask = 0x00ff00;
+       ximage.blue_mask = 0x0000ff;
+       ximage.obdata = NULL;
+       if (!XInitImage (&ximage))
+           return None;
+       pixmap = XCreatePixmap (dpy, RootWindow (dpy, screen),
+                               image->width, image->height, 32);
+       gc = XCreateGC (dpy, pixmap, 0, NULL);
+       XPutImage (dpy, pixmap, gc, &ximage, 
+                  0, 0, 0, 0, image->width, image->height);
+       XFreeGC (dpy, gc);
+       format = XRenderFindStandardFormat (dpy, PictStandardARGB32);
+       picture = XRenderCreatePicture (dpy, pixmap, format, 0, NULL);
+       XFreePixmap (dpy, pixmap);
+       cursor = XRenderCreateCursor (dpy, picture, 
+                                     image->xhot, image->yhot);
+       XRenderFreePicture (dpy, picture);
+    }
+    else
+#endif
+    {
+       XcursorDisplayInfo  *info = _XcursorGetDisplayInfo (dpy);
+       int                 screen = DefaultScreen (dpy);
+       XcursorCoreCursor   core;
+       Pixmap              src_pixmap, msk_pixmap;
+       GC                  gc;
+       XGCValues           gcv;
+
+       core.src_image = XCreateImage (dpy, NULL, 1, ZPixmap,
+                                      0, NULL, image->width, image->height,
+                                      32, 0);
+       core.src_image->data = Xmalloc (image->height * 
+                                       core.src_image->bytes_per_line);
+       core.msk_image = XCreateImage (dpy, NULL, 1, ZPixmap,
+                                      0, NULL, image->width, image->height,
+                                      32, 0);
+       core.msk_image->data = Xmalloc (image->height * 
+                                       core.msk_image->bytes_per_line);
+
+       switch (info->dither) {
+       case XcursorDitherThreshold:
+           if (!_XcursorThreshold (image, &core))
+               return 0;
+           break;
+       case XcursorDitherMedian:
+           if (!_XcursorHeckbertMedianCut (image, &core))
+               return 0;
+           break;
+       case XcursorDitherOrdered:
+           if (!_XcursorBayerOrderedDither (image, &core))
+               return 0;
+           break;
+       case XcursorDitherDiffuse:
+           if (!_XcursorFloydSteinberg (image, &core))
+               return 0;
+           break;
+       default:
+           return 0;
+       }
+
+       /*
+        * Create the cursor
+        */
+       src_pixmap = XCreatePixmap (dpy, RootWindow (dpy, screen),
+                                   image->width, image->height, 1);
+       msk_pixmap = XCreatePixmap (dpy, RootWindow (dpy, screen),
+                                   image->width, image->height, 1);
+       gcv.foreground = 1;
+       gcv.background = 0;
+       gc = XCreateGC (dpy, src_pixmap, 
+                       GCForeground|GCBackground,
+                       &gcv);
+       XPutImage (dpy, src_pixmap, gc, core.src_image,
+                  0, 0, 0, 0, image->width, image->height);
+       
+       XPutImage (dpy, msk_pixmap, gc, core.msk_image,
+                  0, 0, 0, 0, image->width, image->height);
+       XFreeGC (dpy, gc);
+       
+#ifdef DEBUG_IMAGE
+       _XcursorDumpColor (&core.on_color, "on_color");
+       _XcursorDumpColor (&core.off_color, "off_color");
+       _XcursorDumpImage (core.src_image);
+       _XcursorDumpImage (core.msk_image);
+#endif
+       XDestroyImage (core.src_image);
+       XDestroyImage (core.msk_image);
+
+       cursor = XCreatePixmapCursor (dpy, src_pixmap, msk_pixmap,
+                                     &core.on_color, &core.off_color,
+                                     image->xhot, image->yhot);
+       XFreePixmap (dpy, src_pixmap);
+       XFreePixmap (dpy, msk_pixmap);
+    }
+    return cursor;
+}
+
+XcursorCursors *
+XcursorImagesLoadCursors (Display *dpy, const XcursorImages *images)
+{
+    XcursorCursors  *cursors = XcursorCursorsCreate (dpy, images->nimage);
+    int                    n;
+
+    if (!cursors)
+       return NULL;
+    for (n = 0; n < images->nimage; n++)
+    {
+       cursors->cursors[n] = XcursorImageLoadCursor (dpy, images->images[n]);
+       if (!cursors->cursors[n])
+       {
+           XcursorCursorsDestroy (cursors);
+           return NULL;
+       }
+       cursors->ncursor++;
+    }
+    return cursors;
+}
+
+Cursor
+XcursorImagesLoadCursor (Display *dpy, const XcursorImages *images)
+{
+    Cursor  cursor;
+    if (images->nimage == 1 || !XcursorSupportsAnim (dpy))
+       cursor = XcursorImageLoadCursor (dpy, images->images[0]);
+    else
+    {
+       XcursorCursors  *cursors = XcursorImagesLoadCursors (dpy, images);
+       XAnimCursor     *anim;
+       int             n;
+       
+       if (!cursors)
+           return 0;
+       anim = malloc (cursors->ncursor * sizeof (XAnimCursor));
+       if (!anim)
+       {
+           XcursorCursorsDestroy (cursors);
+           return 0;
+       }
+       for (n = 0; n < cursors->ncursor; n++)
+       {
+           anim[n].cursor = cursors->cursors[n];
+           anim[n].delay = images->images[n]->delay;
+       }
+       cursor = XRenderCreateAnimCursor (dpy, cursors->ncursor, anim);
+       XcursorCursorsDestroy(cursors);
+       free (anim);
+    }
+#if defined HAVE_XFIXES && XFIXES_MAJOR >= 2
+    if (images->name)
+       XFixesSetCursorName (dpy, cursor, images->name);
+#endif
+    return cursor;
+}
+
+
+Cursor
+XcursorFilenameLoadCursor (Display *dpy, const char *file)
+{
+    int                    size = XcursorGetDefaultSize (dpy);
+    XcursorImages   *images = XcursorFilenameLoadImages (file, size);
+    Cursor         cursor;
+    
+    if (!images)
+       return None;
+    cursor = XcursorImagesLoadCursor (dpy, images);
+    XcursorImagesDestroy (images);
+    return cursor;
+}
+
+XcursorCursors *
+XcursorFilenameLoadCursors (Display *dpy, const char *file)
+{
+    int                    size = XcursorGetDefaultSize (dpy);
+    XcursorImages   *images = XcursorFilenameLoadImages (file, size);
+    XcursorCursors  *cursors;
+    
+    if (!images)
+       return NULL;
+    cursors = XcursorImagesLoadCursors (dpy, images);
+    XcursorImagesDestroy (images);
+    return cursors;
+}
+
+/*
+ * Stolen from XCreateGlyphCursor (which we cruelly override)
+ */
+
+Cursor
+_XcursorCreateGlyphCursor(Display          *dpy,
+                         Font              source_font,
+                         Font              mask_font,
+                         unsigned int      source_char,
+                         unsigned int      mask_char,
+                         XColor _Xconst    *foreground,
+                         XColor _Xconst    *background)
+{       
+    Cursor cid;
+    register xCreateGlyphCursorReq *req;
+
+    LockDisplay(dpy);
+    GetReq(CreateGlyphCursor, req);
+    cid = req->cid = XAllocID(dpy);
+    req->source = source_font;
+    req->mask = mask_font;
+    req->sourceChar = source_char;
+    req->maskChar = mask_char;
+    req->foreRed = foreground->red;
+    req->foreGreen = foreground->green;
+    req->foreBlue = foreground->blue;
+    req->backRed = background->red;
+    req->backGreen = background->green;
+    req->backBlue = background->blue;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    return (cid);
+}
+
+/*
+ * Stolen from XCreateFontCursor (which we cruelly override)
+ */
+
+Cursor
+_XcursorCreateFontCursor (Display *dpy, unsigned int shape)
+{
+    static XColor _Xconst foreground = { 0,    0,     0,     0  };  /* black */
+    static XColor _Xconst background = { 0, 65535, 65535, 65535 };  /* white */
+
+    /* 
+     * the cursor font contains the shape glyph followed by the mask
+     * glyph; so character position 0 contains a shape, 1 the mask for 0,
+     * 2 a shape, etc.  <X11/cursorfont.h> contains hash define names
+     * for all of these.
+     */
+
+    if (dpy->cursor_font == None) 
+    {
+       dpy->cursor_font = XLoadFont (dpy, CURSORFONT);
+       if (dpy->cursor_font == None)
+           return None;
+    }
+
+    return _XcursorCreateGlyphCursor (dpy, dpy->cursor_font, dpy->cursor_font, 
+                                     shape, shape + 1, &foreground, &background);
+}
+
diff --git a/src/display.c b/src/display.c
new file mode 100644 (file)
index 0000000..c296807
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xcursorint.h"
+#include <X11/Xlibint.h>
+#include <ctype.h>
+
+static XcursorDisplayInfo *_XcursorDisplayInfo;
+
+static void
+_XcursorFreeDisplayInfo (XcursorDisplayInfo *info)
+{
+    if (info->theme)
+       free (info->theme);
+
+    if (info->theme_from_config)
+       free (info->theme_from_config);
+
+    free (info);
+}
+
+static int
+_XcursorCloseDisplay (Display *dpy, XExtCodes *codes)
+{
+    XcursorDisplayInfo  *info, **prev;
+
+    /*
+     * Unhook from the global list
+     */
+    _XLockMutex (_Xglobal_lock);
+    for (prev = &_XcursorDisplayInfo; (info = *prev); prev = &(*prev)->next)
+       if (info->display == dpy)
+       {
+            *prev = info->next;
+           break;
+       }
+    _XUnlockMutex (_Xglobal_lock);
+
+    if (info)
+       _XcursorFreeDisplayInfo (info);
+    return 0;
+}
+
+static int
+_XcursorDefaultParseBool (char *v)
+{
+    char    c0, c1;
+
+    c0 = *v;
+    if (isupper ((int)c0))
+       c0 = tolower (c0);
+    if (c0 == 't' || c0 == 'y' || c0 == '1')
+       return 1;
+    if (c0 == 'f' || c0 == 'n' || c0 == '0')
+       return 0;
+    if (c0 == 'o')
+    {
+       c1 = v[1];
+       if (isupper ((int)c1))
+           c1 = tolower (c1);
+       if (c1 == 'n')
+           return 1;
+       if (c1 == 'f')
+           return 0;
+    }
+    return -1;
+}
+
+XcursorDisplayInfo *
+_XcursorGetDisplayInfo (Display *dpy)
+{
+    XcursorDisplayInfo *info, **prev, *old;
+    int                        event_base, error_base;
+    int                        major, minor;
+    char               *v;
+    int                        i;
+
+    _XLockMutex (_Xglobal_lock);
+    for (prev = &_XcursorDisplayInfo; (info = *prev); prev = &(*prev)->next)
+    {
+       if (info->display == dpy)
+       {
+           /*
+            * MRU the list
+            */
+           if (prev != &_XcursorDisplayInfo)
+           {
+               *prev = info->next;
+               info->next = _XcursorDisplayInfo;
+               _XcursorDisplayInfo = info;
+           }
+           break;
+       }
+    }
+    _XUnlockMutex (_Xglobal_lock);
+    if (info)
+        return info;
+    info = (XcursorDisplayInfo *) malloc (sizeof (XcursorDisplayInfo));
+    if (!info)
+       return NULL;
+    info->next = NULL;
+    info->display = dpy;
+    
+    info->codes = XAddExtension (dpy);
+    if (!info->codes)
+    {
+       free (info);
+       return NULL;
+    }
+    (void) XESetCloseDisplay (dpy, info->codes->extension, _XcursorCloseDisplay);
+
+    /*
+     * Check whether the display supports the Render CreateCursor request
+     */
+    info->has_render_cursor = XcursorFalse;
+    info->has_anim_cursor = XcursorFalse;
+    if (XRenderQueryExtension (dpy, &event_base, &error_base) &&
+       XRenderQueryVersion (dpy, &major, &minor))
+    {
+       if (major > 0 || minor >= 5)
+       {
+           info->has_render_cursor = XcursorTrue;
+           v = getenv ("XCURSOR_CORE");
+           if (!v)
+               v = XGetDefault (dpy, "Xcursor", "core");
+           if (v && _XcursorDefaultParseBool (v) == 1)
+               info->has_render_cursor = XcursorFalse;
+       }
+       if (info->has_render_cursor && (major > 0 || minor >= 8))
+       {
+           info->has_anim_cursor = XcursorTrue;
+           v = getenv ("XCURSOR_ANIM");
+           if (!v)
+               v = XGetDefault (dpy, "Xcursor", "anim");
+           if (v && _XcursorDefaultParseBool (v) == 0)
+               info->has_anim_cursor = XcursorFalse;
+       }
+    }
+    
+    info->size = 0;
+
+    /*
+     * Get desired cursor size
+     */
+    v = getenv ("XCURSOR_SIZE");
+    if (!v)
+       v = XGetDefault (dpy, "Xcursor", "size");
+    if (v)
+       info->size = atoi (v);
+    
+    /*
+     * Use the Xft size to guess a size; make cursors 16 "points" tall
+     */
+    if (info->size == 0)
+    {
+       int dpi = 0;
+       v = XGetDefault (dpy, "Xft", "dpi");
+       if (v)
+           dpi = atoi (v);
+       if (dpi)
+           info->size = dpi * 16 / 72;
+    }
+    
+    /*
+     * Use display size to guess a size
+     */
+    if (info->size == 0)
+    {
+       int dim;
+           
+       if (DisplayHeight (dpy, DefaultScreen (dpy)) < 
+           DisplayWidth (dpy, DefaultScreen (dpy)))
+           dim = DisplayHeight (dpy, DefaultScreen (dpy));
+       else
+           dim = DisplayWidth (dpy, DefaultScreen (dpy));
+       /*
+        * 16 pixels on a display of dimension 768
+        */
+       info->size = dim / 48;
+    }
+    
+    info->theme = NULL;
+    info->theme_from_config = NULL;
+
+    /*
+     * Get the desired theme
+     */
+    v = getenv ("XCURSOR_THEME");
+    if (!v)
+       v = XGetDefault (dpy, "Xcursor", "theme");
+    if (v)
+    {
+       int len;
+
+       len = strlen (v) + 1;
+
+       info->theme = malloc (len);
+       if (info->theme)
+           strcpy (info->theme, v);
+
+       info->theme_from_config = malloc (len);
+       if (info->theme_from_config)
+           strcpy (info->theme_from_config, v);
+    }
+
+    /*
+     * Get the desired dither
+     */
+    info->dither = XcursorDitherThreshold;
+    v = getenv ("XCURSOR_DITHER");
+    if (!v)
+       v = XGetDefault (dpy, "Xcursor", "dither");
+    if (v)
+    {
+       if (!strcmp (v, "threshold"))
+           info->dither = XcursorDitherThreshold;
+       if (!strcmp (v, "median"))
+           info->dither = XcursorDitherMedian;
+       if (!strcmp (v, "ordered"))
+           info->dither = XcursorDitherOrdered;
+       if (!strcmp (v, "diffuse"))
+           info->dither = XcursorDitherDiffuse;
+    }
+
+    info->theme_core = False;
+    /*
+     * Find out if core cursors should
+     * be themed
+     */
+    v = getenv ("XCURSOR_THEME_CORE");
+    if (!v)
+       v = XGetDefault (dpy, "Xcursor", "theme_core");
+    if (v)
+    {
+       i = _XcursorDefaultParseBool (v);
+       if (i >= 0)
+           info->theme_core = i;
+    }
+
+    info->fonts = NULL;
+    for (i = 0; i < NUM_BITMAPS; i++)
+       info->bitmaps[i].bitmap = None;
+
+    /*
+     * Link new info info list, making sure another
+     * thread hasn't inserted something into the list while
+     * this one was busy setting up the data
+     */
+    _XLockMutex (_Xglobal_lock);
+    for (old = _XcursorDisplayInfo; old; old = old->next)
+       if (old->display == dpy)
+           break;
+    if (old)
+    {
+       _XcursorFreeDisplayInfo (info);
+       info = old;
+    }
+    else
+    {
+       info->next = _XcursorDisplayInfo;
+       _XcursorDisplayInfo = info;
+    }
+    _XUnlockMutex (_Xglobal_lock);
+    
+    return info;
+}
+
+XcursorBool
+XcursorSupportsARGB (Display *dpy)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    return info && info->has_render_cursor;
+}
+
+XcursorBool
+XcursorSupportsAnim (Display *dpy)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    return info && info->has_anim_cursor;
+}
+
+XcursorBool
+XcursorSetDefaultSize (Display *dpy, int size)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    if (!info)
+       return XcursorFalse;
+    info->size = size;
+    return XcursorTrue;
+}
+
+int
+XcursorGetDefaultSize (Display *dpy)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    if (!info)
+       return 0;
+    return info->size;
+}
+
+XcursorBool
+XcursorSetTheme (Display *dpy, const char *theme)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+    char               *copy;
+
+    if (!info)
+       return XcursorFalse;
+
+    if (!theme)
+       theme = info->theme_from_config;
+
+    if (theme)
+    {
+       copy = malloc (strlen (theme) + 1);
+       if (!copy)
+           return XcursorFalse;
+       strcpy (copy, theme);
+    }
+    else
+       copy = NULL;
+    if (info->theme)
+       free (info->theme);
+    info->theme = copy;
+    return XcursorTrue;
+}
+
+char *
+XcursorGetTheme (Display *dpy)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    if (!info)
+       return NULL;
+    return info->theme;
+}
+
+XcursorBool
+XcursorGetThemeCore (Display *dpy)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    if (!info)
+       return XcursorFalse;
+    return info->theme_core;
+    
+}
+
+XcursorBool
+XcursorSetThemeCore (Display *dpy, XcursorBool theme_core)
+{
+    XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
+
+    if (!info)
+       return XcursorFalse;
+    info->theme_core = theme_core;
+    return XcursorTrue;
+}
diff --git a/src/file.c b/src/file.c
new file mode 100644 (file)
index 0000000..6c4f1bb
--- /dev/null
@@ -0,0 +1,1102 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xcursorint.h"
+#include <stdlib.h>
+#include <string.h>
+
+XcursorImage *
+XcursorImageCreate (int width, int height)
+{
+    XcursorImage    *image;
+
+    image = malloc (sizeof (XcursorImage) +
+                   width * height * sizeof (XcursorPixel));
+    if (!image)
+       return NULL;
+    image->version = XCURSOR_IMAGE_VERSION;
+    image->pixels = (XcursorPixel *) (image + 1);
+    image->size = width > height ? width : height;
+    image->width = width;
+    image->height = height;
+    image->delay = 0;
+    return image;
+}
+
+void
+XcursorImageDestroy (XcursorImage *image)
+{
+    free (image);
+}
+
+XcursorImages *
+XcursorImagesCreate (int size)
+{
+    XcursorImages   *images;
+
+    images = malloc (sizeof (XcursorImages) + 
+                    size * sizeof (XcursorImage *));
+    if (!images)
+       return NULL;
+    images->nimage = 0;
+    images->images = (XcursorImage **) (images + 1);
+    images->name = NULL;
+    return images;
+}
+
+void
+XcursorImagesDestroy (XcursorImages *images)
+{
+    int        n;
+
+    if (!images)
+        return;
+
+    for (n = 0; n < images->nimage; n++)
+       XcursorImageDestroy (images->images[n]);
+    if (images->name)
+       free (images->name);
+    free (images);
+}
+
+void
+XcursorImagesSetName (XcursorImages *images, const char *name)
+{
+    char    *new;
+    
+    if (!images || !name)
+        return;
+    
+    new = malloc (strlen (name) + 1);
+
+    if (!new)
+       return;
+
+    strcpy (new, name);
+    if (images->name)
+       free (images->name);
+    images->name = new;
+}
+
+XcursorComment *
+XcursorCommentCreate (XcursorUInt comment_type, int length)
+{
+    XcursorComment  *comment;
+
+    if (length > XCURSOR_COMMENT_MAX_LEN)
+       return NULL;
+
+    comment = malloc (sizeof (XcursorComment) + length + 1);
+    if (!comment)
+       return NULL;
+    comment->version = XCURSOR_COMMENT_VERSION;
+    comment->comment_type = comment_type;
+    comment->comment = (char *) (comment + 1);
+    comment->comment[0] = '\0';
+    return comment;
+}
+
+void
+XcursorCommentDestroy (XcursorComment *comment)
+{
+    free (comment);
+}
+
+XcursorComments *
+XcursorCommentsCreate (int size)
+{
+    XcursorComments *comments;
+
+    comments = malloc (sizeof (XcursorComments) +
+                      size * sizeof (XcursorComment *));
+    if (!comments)
+       return NULL;
+    comments->ncomment = 0;
+    comments->comments = (XcursorComment **) (comments + 1);
+    return comments;
+}
+
+void
+XcursorCommentsDestroy (XcursorComments *comments)
+{
+    int        n;
+
+    if (!comments)
+        return;
+
+    for (n = 0; n < comments->ncomment; n++)
+       XcursorCommentDestroy (comments->comments[n]);
+    free (comments);
+}
+
+static XcursorBool
+_XcursorReadUInt (XcursorFile *file, XcursorUInt *u)
+{
+    unsigned char   bytes[4];
+
+    if (!file || !u)
+        return XcursorFalse;
+
+    if ((*file->read) (file, bytes, 4) != 4)
+       return XcursorFalse;
+    *u = ((bytes[0] << 0) |
+         (bytes[1] << 8) |
+         (bytes[2] << 16) |
+         (bytes[3] << 24));
+    return XcursorTrue;
+}
+
+static XcursorBool
+_XcursorReadBytes (XcursorFile *file, char *bytes, int length)
+{
+    if (!file || !bytes || (*file->read) (file, (unsigned char *) bytes, length) != length)
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+static XcursorBool
+_XcursorWriteUInt (XcursorFile *file, XcursorUInt u)
+{
+    unsigned char   bytes[4];
+
+    if (!file)
+        return XcursorFalse;
+    
+    bytes[0] = u;
+    bytes[1] = u >>  8;
+    bytes[2] = u >> 16;
+    bytes[3] = u >> 24;
+    if ((*file->write) (file, bytes, 4) != 4)
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+static XcursorBool
+_XcursorWriteBytes (XcursorFile *file, char *bytes, int length)
+{
+    if (!file || !bytes || (*file->write) (file, (unsigned char *) bytes, length) != length)
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+static void
+_XcursorFileHeaderDestroy (XcursorFileHeader *fileHeader)
+{
+    free (fileHeader);
+}
+
+static XcursorFileHeader *
+_XcursorFileHeaderCreate (int ntoc)
+{
+    XcursorFileHeader  *fileHeader;
+
+    if (ntoc > 0x10000)
+       return NULL;
+    fileHeader = malloc (sizeof (XcursorFileHeader) +
+                        ntoc * sizeof (XcursorFileToc));
+    if (!fileHeader)
+       return NULL;
+    fileHeader->magic = XCURSOR_MAGIC;
+    fileHeader->header = XCURSOR_FILE_HEADER_LEN;
+    fileHeader->version = XCURSOR_FILE_VERSION;
+    fileHeader->ntoc = ntoc;
+    fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1);
+    return fileHeader;
+}
+
+static XcursorFileHeader *
+_XcursorReadFileHeader (XcursorFile *file)
+{
+    XcursorFileHeader  head, *fileHeader;
+    XcursorUInt                skip;
+    int                        n;
+
+    if (!file)
+        return NULL;
+    
+    if (!_XcursorReadUInt (file, &head.magic))
+       return NULL;
+    if (head.magic != XCURSOR_MAGIC)
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.header))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.version))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.ntoc))
+       return NULL;
+    skip = head.header - XCURSOR_FILE_HEADER_LEN;
+    if (skip)
+       if ((*file->seek) (file, skip, SEEK_CUR) == EOF)
+           return NULL;
+    fileHeader = _XcursorFileHeaderCreate (head.ntoc);
+    if (!fileHeader)
+       return NULL;
+    fileHeader->magic = head.magic;
+    fileHeader->header = head.header;
+    fileHeader->version = head.version;
+    fileHeader->ntoc = head.ntoc;
+    for (n = 0; n < fileHeader->ntoc; n++)
+    {
+       if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type))
+           break;
+       if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype))
+           break;
+       if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position))
+           break;
+    }
+    if (n != fileHeader->ntoc)
+    {
+       _XcursorFileHeaderDestroy (fileHeader);
+       return NULL;
+    }
+    return fileHeader;
+}
+
+static XcursorUInt
+_XcursorFileHeaderLength (XcursorFileHeader *fileHeader)
+{
+    return (XCURSOR_FILE_HEADER_LEN + 
+           fileHeader->ntoc * XCURSOR_FILE_TOC_LEN);
+}
+
+static XcursorBool
+_XcursorWriteFileHeader (XcursorFile *file, XcursorFileHeader *fileHeader)
+{
+    int        toc;
+
+    if (!file || !fileHeader)
+        return XcursorFalse;
+    
+    if (!_XcursorWriteUInt (file, fileHeader->magic))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, fileHeader->header))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, fileHeader->version))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, fileHeader->ntoc))
+       return XcursorFalse;
+    for (toc = 0; toc < fileHeader->ntoc; toc++)
+    {
+       if (!_XcursorWriteUInt (file, fileHeader->tocs[toc].type))
+           return XcursorFalse;
+       if (!_XcursorWriteUInt (file, fileHeader->tocs[toc].subtype))
+           return XcursorFalse;
+       if (!_XcursorWriteUInt (file, fileHeader->tocs[toc].position))
+           return XcursorFalse;
+    }
+    return XcursorTrue;
+}
+
+static XcursorBool
+_XcursorSeekToToc (XcursorFile         *file, 
+                  XcursorFileHeader    *fileHeader,
+                  int                  toc)
+{
+    if (!file || !fileHeader || \
+        (*file->seek) (file, fileHeader->tocs[toc].position, SEEK_SET) == EOF)
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+static XcursorBool
+_XcursorFileReadChunkHeader (XcursorFile       *file,
+                            XcursorFileHeader  *fileHeader,
+                            int                toc,
+                            XcursorChunkHeader *chunkHeader)
+{
+    if (!file || !fileHeader || !chunkHeader)
+        return XcursorFalse;
+    if (!_XcursorSeekToToc (file, fileHeader, toc))
+       return XcursorFalse;
+    if (!_XcursorReadUInt (file, &chunkHeader->header))
+       return XcursorFalse;
+    if (!_XcursorReadUInt (file, &chunkHeader->type))
+       return XcursorFalse;
+    if (!_XcursorReadUInt (file, &chunkHeader->subtype))
+       return XcursorFalse;
+    if (!_XcursorReadUInt (file, &chunkHeader->version))
+       return XcursorFalse;
+    /* sanity check */
+    if (chunkHeader->type != fileHeader->tocs[toc].type ||
+       chunkHeader->subtype != fileHeader->tocs[toc].subtype)
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+static XcursorBool
+_XcursorFileWriteChunkHeader (XcursorFile          *file,
+                             XcursorFileHeader     *fileHeader,
+                             int                   toc,
+                             XcursorChunkHeader    *chunkHeader)
+{
+    if (!file || !fileHeader || !chunkHeader)
+        return XcursorFalse;
+    if (!_XcursorSeekToToc (file, fileHeader, toc))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, chunkHeader->header))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, chunkHeader->type))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, chunkHeader->subtype))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, chunkHeader->version))
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+#define dist(a,b)   ((a) > (b) ? (a) - (b) : (b) - (a))
+
+static XcursorDim
+_XcursorFindBestSize (XcursorFileHeader *fileHeader,
+                     XcursorDim        size,
+                     int               *nsizesp)
+{
+    int                n;
+    int                nsizes = 0;
+    XcursorDim bestSize = 0;
+    XcursorDim thisSize;
+
+    if (!fileHeader || !nsizesp)
+        return 0;
+
+    for (n = 0; n < fileHeader->ntoc; n++)
+    {
+       if (fileHeader->tocs[n].type != XCURSOR_IMAGE_TYPE)
+           continue;
+       thisSize = fileHeader->tocs[n].subtype;
+       if (!bestSize || dist (thisSize, size) < dist (bestSize, size))
+       {
+           bestSize = thisSize;
+           nsizes = 1;
+       }
+       else if (thisSize == bestSize)
+           nsizes++;
+    }
+    *nsizesp = nsizes;
+    return bestSize;
+}
+
+static int
+_XcursorFindImageToc (XcursorFileHeader        *fileHeader,
+                     XcursorDim        size,
+                     int               count)
+{
+    int                        toc;
+    XcursorDim         thisSize;
+
+    if (!fileHeader)
+        return 0;
+
+    for (toc = 0; toc < fileHeader->ntoc; toc++)
+    {
+       if (fileHeader->tocs[toc].type != XCURSOR_IMAGE_TYPE)
+           continue;
+       thisSize = fileHeader->tocs[toc].subtype;
+       if (thisSize != size)
+           continue;
+       if (!count)
+           break;
+       count--;
+    }
+    if (toc == fileHeader->ntoc)
+       return -1;
+    return toc;
+}
+
+static XcursorImage *
+_XcursorReadImage (XcursorFile         *file, 
+                  XcursorFileHeader    *fileHeader,
+                  int                  toc)
+{
+    XcursorChunkHeader chunkHeader;
+    XcursorImage       head;
+    XcursorImage       *image;
+    int                        n;
+    XcursorPixel       *p;
+
+    if (!file || !fileHeader)
+        return NULL;
+
+    if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.width))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.height))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.xhot))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.yhot))
+       return NULL;
+    if (!_XcursorReadUInt (file, &head.delay))
+       return NULL;
+    /* sanity check data */
+    if (head.width >= 0x10000 || head.height > 0x10000)
+       return NULL;
+    if (head.width == 0 || head.height == 0)
+       return NULL;
+    if (head.xhot > head.width || head.yhot > head.height)
+       return NULL;
+    
+    /* Create the image and initialize it */
+    image = XcursorImageCreate (head.width, head.height);
+    if (chunkHeader.version < image->version)
+       image->version = chunkHeader.version;
+    image->size = chunkHeader.subtype;
+    image->xhot = head.xhot;
+    image->yhot = head.yhot;
+    image->delay = head.delay;
+    n = image->width * image->height;
+    p = image->pixels;
+    while (n--)
+    {
+       if (!_XcursorReadUInt (file, p))
+       {
+           XcursorImageDestroy (image);
+           return NULL;
+       }
+       p++;
+    }
+    return image;
+}
+
+static XcursorUInt
+_XcursorImageLength (XcursorImage   *image)
+{
+    if (!image)
+        return 0;
+
+    return XCURSOR_IMAGE_HEADER_LEN + (image->width * image->height) * 4;
+}
+
+static XcursorBool
+_XcursorWriteImage (XcursorFile                *file, 
+                   XcursorFileHeader   *fileHeader,
+                   int                 toc,
+                   XcursorImage        *image)
+{
+    XcursorChunkHeader chunkHeader;
+    int                        n;
+    XcursorPixel       *p;
+
+    if (!file || !fileHeader || !image)
+        return XcursorFalse;
+
+    /* sanity check data */
+    if (image->width > XCURSOR_IMAGE_MAX_SIZE  ||
+       image->height > XCURSOR_IMAGE_MAX_SIZE)
+       return XcursorFalse;
+    if (image->width == 0 || image->height == 0)
+       return XcursorFalse;
+    if (image->xhot > image->width || image->yhot > image->height)
+       return XcursorFalse;
+    
+    /* write chunk header */
+    chunkHeader.header = XCURSOR_IMAGE_HEADER_LEN;
+    chunkHeader.type = XCURSOR_IMAGE_TYPE;
+    chunkHeader.subtype = image->size;
+    chunkHeader.version = XCURSOR_IMAGE_VERSION;
+    
+    if (!_XcursorFileWriteChunkHeader (file, fileHeader, toc, &chunkHeader))
+       return XcursorFalse;
+    
+    /* write extra image header fields */
+    if (!_XcursorWriteUInt (file, image->width))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, image->height))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, image->xhot))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, image->yhot))
+       return XcursorFalse;
+    if (!_XcursorWriteUInt (file, image->delay))
+       return XcursorFalse;
+    
+    /* write the image */
+    n = image->width * image->height;
+    p = image->pixels;
+    while (n--)
+    {
+       if (!_XcursorWriteUInt (file, *p))
+           return XcursorFalse;
+       p++;
+    }
+    return XcursorTrue;
+}
+
+static XcursorComment *
+_XcursorReadComment (XcursorFile           *file, 
+                    XcursorFileHeader      *fileHeader,
+                    int                    toc)
+{
+    XcursorChunkHeader chunkHeader;
+    XcursorUInt                length;
+    XcursorComment     *comment;
+
+    if (!file || !fileHeader)
+        return NULL;
+
+    /* read chunk header */
+    if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader))
+       return NULL;
+    /* read extra comment header fields */
+    if (!_XcursorReadUInt (file, &length))
+       return NULL;
+    comment = XcursorCommentCreate (chunkHeader.subtype, length);
+    if (!comment)
+       return NULL;
+    if (!_XcursorReadBytes (file, comment->comment, length))
+    {
+       XcursorCommentDestroy (comment);
+       return NULL;
+    }
+    comment->comment[length] = '\0';
+    return comment;
+}
+
+static XcursorUInt
+_XcursorCommentLength (XcursorComment      *comment)
+{
+    return XCURSOR_COMMENT_HEADER_LEN + strlen (comment->comment);
+}
+
+static XcursorBool
+_XcursorWriteComment (XcursorFile          *file, 
+                     XcursorFileHeader     *fileHeader,
+                     int                   toc,
+                     XcursorComment        *comment)
+{
+    XcursorChunkHeader chunkHeader;
+    XcursorUInt                length;
+
+    if (!file || !fileHeader || !comment || !comment->comment)
+        return XcursorFalse;
+
+    length = strlen (comment->comment);
+    
+    /* sanity check data */
+    if (length > XCURSOR_COMMENT_MAX_LEN)
+       return XcursorFalse;
+    
+    /* read chunk header */
+    chunkHeader.header = XCURSOR_COMMENT_HEADER_LEN;
+    chunkHeader.type = XCURSOR_COMMENT_TYPE;
+    chunkHeader.subtype = comment->comment_type;
+    chunkHeader.version = XCURSOR_COMMENT_VERSION;
+    
+    if (!_XcursorFileWriteChunkHeader (file, fileHeader, toc, &chunkHeader))
+       return XcursorFalse;
+    
+    /* write extra comment header fields */
+    if (!_XcursorWriteUInt (file, length))
+       return XcursorFalse;
+    
+    if (!_XcursorWriteBytes (file, comment->comment, length))
+       return XcursorFalse;
+    return XcursorTrue;
+}
+
+XcursorImage *
+XcursorXcFileLoadImage (XcursorFile *file, int size)
+{
+    XcursorFileHeader  *fileHeader;
+    XcursorDim         bestSize;
+    int                        nsize;
+    int                        toc;
+    XcursorImage       *image;
+    
+    if (size < 0)
+       return NULL;
+    fileHeader = _XcursorReadFileHeader (file);
+    if (!fileHeader)
+       return NULL;
+    bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize);
+    if (!bestSize)
+       return NULL;
+    toc = _XcursorFindImageToc (fileHeader, bestSize, 0);
+    if (toc < 0)
+       return NULL;
+    image = _XcursorReadImage (file, fileHeader, toc);
+    _XcursorFileHeaderDestroy (fileHeader);
+    return image;
+}
+
+XcursorImages *
+XcursorXcFileLoadImages (XcursorFile *file, int size)
+{
+    XcursorFileHeader  *fileHeader;
+    XcursorDim         bestSize;
+    int                        nsize;
+    XcursorImages      *images;
+    int                        n;
+    int                        toc;
+    
+    if (!file || size < 0)
+       return NULL;
+    fileHeader = _XcursorReadFileHeader (file);
+    if (!fileHeader)
+       return NULL;
+    bestSize = _XcursorFindBestSize (fileHeader, (XcursorDim) size, &nsize);
+    if (!bestSize)
+    {
+        _XcursorFileHeaderDestroy (fileHeader);
+       return NULL;
+    }
+    images = XcursorImagesCreate (nsize);
+    if (!images)
+    {
+        _XcursorFileHeaderDestroy (fileHeader);
+       return NULL;
+    }
+    for (n = 0; n < nsize; n++)
+    {
+       toc = _XcursorFindImageToc (fileHeader, bestSize, n);
+       if (toc < 0)
+           break;
+       images->images[images->nimage] = _XcursorReadImage (file, fileHeader, 
+                                                           toc);
+       if (!images->images[images->nimage])
+           break;
+       images->nimage++;
+    }
+    _XcursorFileHeaderDestroy (fileHeader);
+    if (images->nimage != nsize)
+    {
+       XcursorImagesDestroy (images);
+       images = NULL;
+    }
+    return images;
+}
+
+XcursorImages *
+XcursorXcFileLoadAllImages (XcursorFile *file)
+{
+    XcursorFileHeader  *fileHeader;
+    XcursorImage       *image;
+    XcursorImages      *images;
+    int                        nimage;
+    int                        n;
+    int                        toc;
+    
+    if (!file)
+        return NULL;
+    
+    fileHeader = _XcursorReadFileHeader (file);
+    if (!fileHeader)
+       return NULL;
+    nimage = 0;
+    for (n = 0; n < fileHeader->ntoc; n++)
+    {
+       switch (fileHeader->tocs[n].type) {
+       case XCURSOR_IMAGE_TYPE:
+           nimage++;
+           break;
+       }
+    }
+    images = XcursorImagesCreate (nimage);
+    if (!images)
+       return NULL;
+    for (toc = 0; toc < fileHeader->ntoc; toc++)
+    {
+       switch (fileHeader->tocs[toc].type) {
+       case XCURSOR_IMAGE_TYPE:
+           image = _XcursorReadImage (file, fileHeader, toc);
+           if (image)
+           {
+               images->images[images->nimage] = image;
+               images->nimage++;
+           }
+           break;
+       }
+    }
+    _XcursorFileHeaderDestroy (fileHeader);
+    if (images->nimage != nimage)
+    {
+       XcursorImagesDestroy (images);
+       images = NULL;
+    }
+    return images;
+}
+
+XcursorBool
+XcursorXcFileLoad (XcursorFile     *file,
+                  XcursorComments  **commentsp,
+                  XcursorImages    **imagesp)
+{
+    XcursorFileHeader  *fileHeader;
+    int                        nimage;
+    int                        ncomment;
+    XcursorImages      *images;
+    XcursorImage       *image;
+    XcursorComment     *comment;
+    XcursorComments    *comments;
+    int                        toc;
+    
+    if (!file)
+        return 0;
+    fileHeader = _XcursorReadFileHeader (file);
+    if (!fileHeader)
+       return 0;
+    nimage = 0;
+    ncomment = 0;
+    for (toc = 0; toc < fileHeader->ntoc; toc++)
+    {
+       switch (fileHeader->tocs[toc].type) {
+       case XCURSOR_COMMENT_TYPE:
+           ncomment++;
+           break;
+       case XCURSOR_IMAGE_TYPE:
+           nimage++;
+           break;
+       }
+    }
+    images = XcursorImagesCreate (nimage);
+    if (!images)
+       return 0;
+    comments = XcursorCommentsCreate (ncomment);
+    if (!comments)
+    {
+       XcursorImagesDestroy (images);
+       return 0;
+    }
+    for (toc = 0; toc < fileHeader->ntoc; toc++)
+    {
+       switch (fileHeader->tocs[toc].type) {
+       case XCURSOR_COMMENT_TYPE:
+           comment = _XcursorReadComment (file, fileHeader, toc);
+           if (comment)
+           {
+               comments->comments[comments->ncomment] = comment;
+               comments->ncomment++;
+           }
+           break;
+       case XCURSOR_IMAGE_TYPE:
+           image = _XcursorReadImage (file, fileHeader, toc);
+           if (image)
+           {
+               images->images[images->nimage] = image;
+               images->nimage++;
+           }
+           break;
+       }
+    }
+    _XcursorFileHeaderDestroy (fileHeader);
+    if (images->nimage != nimage || comments->ncomment != ncomment)
+    {
+       XcursorImagesDestroy (images);
+       XcursorCommentsDestroy (comments);
+       images = NULL;
+       comments = NULL;
+       return XcursorFalse;
+    }
+    *imagesp = images;
+    *commentsp = comments;
+    return XcursorTrue;
+}
+
+XcursorBool
+XcursorXcFileSave (XcursorFile             *file, 
+                  const XcursorComments    *comments,
+                  const XcursorImages      *images)
+{
+    XcursorFileHeader  *fileHeader;
+    XcursorUInt                position;
+    int                        n;
+    int                        toc;
+    
+    if (!file || !comments || !images)
+        return XcursorFalse;
+    
+    fileHeader = _XcursorFileHeaderCreate (comments->ncomment + images->nimage);
+    if (!fileHeader)
+       return XcursorFalse;
+    
+    position = _XcursorFileHeaderLength (fileHeader);
+
+    /*
+     * Compute the toc.  Place the images before the comments
+     * as they're more often read
+     */
+    
+    toc = 0;
+    for (n = 0; n < images->nimage; n++)
+    {
+       fileHeader->tocs[toc].type = XCURSOR_IMAGE_TYPE;
+       fileHeader->tocs[toc].subtype = images->images[n]->size;
+       fileHeader->tocs[toc].position = position;
+       position += _XcursorImageLength (images->images[n]);
+       toc++;
+    }
+    
+    for (n = 0; n < comments->ncomment; n++)
+    {
+       fileHeader->tocs[toc].type = XCURSOR_COMMENT_TYPE;
+       fileHeader->tocs[toc].subtype = comments->comments[n]->comment_type;
+       fileHeader->tocs[toc].position = position;
+       position += _XcursorCommentLength (comments->comments[n]);
+       toc++;
+    }
+    
+    /*
+     * Write the header and the toc
+     */
+    if (!_XcursorWriteFileHeader (file, fileHeader))
+       goto bail;
+    
+    /*
+     * Write the images
+     */
+    toc = 0;
+    for (n = 0; n < images->nimage; n++)
+    {
+       if (!_XcursorWriteImage (file, fileHeader, toc, images->images[n]))
+           goto bail;
+       toc++;
+    }
+    
+    /*
+     * Write the comments
+     */
+    for (n = 0; n < comments->ncomment; n++)
+    {
+       if (!_XcursorWriteComment (file, fileHeader, toc, comments->comments[n]))
+           goto bail;
+       toc++;
+    }
+    
+    _XcursorFileHeaderDestroy (fileHeader);
+    return XcursorTrue;
+bail:
+    _XcursorFileHeaderDestroy (fileHeader);
+    return XcursorFalse;
+}
+
+static int
+_XcursorStdioFileRead (XcursorFile *file, unsigned char *buf, int len)
+{
+    FILE    *f = file->closure;
+    return fread (buf, 1, len, f);
+}
+
+static int
+_XcursorStdioFileWrite (XcursorFile *file, unsigned char *buf, int len)
+{
+    FILE    *f = file->closure;
+    return fwrite (buf, 1, len, f);
+}
+
+static int
+_XcursorStdioFileSeek (XcursorFile *file, long offset, int whence)
+{
+    FILE    *f = file->closure;
+    return fseek (f, offset, whence);
+}
+
+static void
+_XcursorStdioFileInitialize (FILE *stdfile, XcursorFile *file)
+{
+    file->closure = stdfile;
+    file->read = _XcursorStdioFileRead;
+    file->write = _XcursorStdioFileWrite;
+    file->seek = _XcursorStdioFileSeek;
+}
+
+XcursorImage *
+XcursorFileLoadImage (FILE *file, int size)
+{
+    XcursorFile        f;
+
+    if (!file)
+        return NULL;
+
+    _XcursorStdioFileInitialize (file, &f);
+    return XcursorXcFileLoadImage (&f, size);
+}
+
+XcursorImages *
+XcursorFileLoadImages (FILE *file, int size)
+{
+    XcursorFile        f;
+
+    if (!file)
+        return NULL;
+
+    _XcursorStdioFileInitialize (file, &f);
+    return XcursorXcFileLoadImages (&f, size);
+}
+
+XcursorImages *
+XcursorFileLoadAllImages (FILE *file)
+{
+    XcursorFile        f;
+
+    if (!file)
+        return NULL;
+
+    _XcursorStdioFileInitialize (file, &f);
+    return XcursorXcFileLoadAllImages (&f);
+}
+
+XcursorBool
+XcursorFileLoad (FILE              *file, 
+                XcursorComments    **commentsp, 
+                XcursorImages      **imagesp)
+{
+    XcursorFile        f;
+
+    if (!file || !commentsp || !imagesp)
+        return XcursorFalse;
+
+    _XcursorStdioFileInitialize (file, &f);
+    return XcursorXcFileLoad (&f, commentsp, imagesp);
+}
+
+XcursorBool
+XcursorFileSaveImages (FILE *file, const XcursorImages *images)
+{
+    XcursorComments *comments = XcursorCommentsCreate (0);
+    XcursorFile            f;
+    XcursorBool            ret;
+    if (!comments || !file || !images)
+       return 0;
+    _XcursorStdioFileInitialize (file, &f);
+    ret = XcursorXcFileSave (&f, comments, images) && fflush (file) != EOF;
+    XcursorCommentsDestroy (comments);
+    return ret;
+}
+
+XcursorBool
+XcursorFileSave (FILE *                        file, 
+                const XcursorComments  *comments,
+                const XcursorImages    *images)
+{
+    XcursorFile            f;
+
+    if (!file || !comments || !images)
+        return XcursorFalse;
+    
+    _XcursorStdioFileInitialize (file, &f);
+    return XcursorXcFileSave (&f, comments, images) && fflush (file) != EOF;
+}
+
+XcursorImage *
+XcursorFilenameLoadImage (const char *file, int size)
+{
+    FILE           *f;
+    XcursorImage    *image;
+
+    if (!file || size < 0)
+        return NULL;
+
+    f = fopen (file, "r");
+    if (!f)
+       return NULL;
+    image = XcursorFileLoadImage (f, size);
+    fclose (f);
+    return image;
+}
+
+XcursorImages *
+XcursorFilenameLoadImages (const char *file, int size)
+{
+    FILE           *f;
+    XcursorImages   *images;
+
+    if (!file || size < 0)
+        return NULL;
+    
+    f = fopen (file, "r");
+    if (!f)
+       return NULL;
+    images = XcursorFileLoadImages (f, size);
+    fclose (f);
+    return images;
+}
+
+XcursorImages *
+XcursorFilenameLoadAllImages (const char *file)
+{
+    FILE           *f;
+    XcursorImages   *images;
+
+    if (!file)
+        return NULL;
+
+    f = fopen (file, "r");
+    if (!f)
+       return NULL;
+    images = XcursorFileLoadAllImages (f);
+    fclose (f);
+    return images;
+}
+
+XcursorBool
+XcursorFilenameLoad (const char                *file,
+                    XcursorComments    **commentsp,
+                    XcursorImages      **imagesp)
+{
+    FILE           *f;
+    XcursorBool            ret;
+
+    if (!file)
+        return XcursorFalse;
+
+    f = fopen (file, "r");
+    if (!f)
+       return 0;
+    ret = XcursorFileLoad (f, commentsp, imagesp);
+    fclose (f);
+    return ret;
+}
+
+XcursorBool
+XcursorFilenameSaveImages (const char *file, const XcursorImages *images)
+{
+    FILE           *f;
+    XcursorBool            ret;
+
+    if (!file || !images)
+        return XcursorFalse;
+
+    f = fopen (file, "w");
+    if (!f)
+       return 0;
+    ret = XcursorFileSaveImages (f, images);
+    return fclose (f) != EOF && ret;
+}
+
+XcursorBool
+XcursorFilenameSave (const char                    *file, 
+                    const XcursorComments  *comments,
+                    const XcursorImages    *images)
+{
+    FILE           *f;
+    XcursorBool            ret;
+
+    if (!file || !comments || !images)
+        return XcursorFalse;
+
+    f = fopen (file, "w");
+    if (!f)
+       return 0;
+    ret = XcursorFileSave (f, comments, images);
+    return fclose (f) != EOF && ret;
+}
diff --git a/src/library.c b/src/library.c
new file mode 100644 (file)
index 0000000..86f2d76
--- /dev/null
@@ -0,0 +1,550 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xcursorint.h"
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef ICONDIR
+#define ICONDIR "/usr/X11R6/lib/X11/icons"
+#endif
+
+#ifndef XCURSORPATH
+#define XCURSORPATH "~/.icons:/usr/share/icons:/usr/share/pixmaps:"ICONDIR
+#endif
+
+const char *
+XcursorLibraryPath (void)
+{
+    static const char  *path;
+
+    if (!path)
+    {
+       path = getenv ("XCURSOR_PATH");
+       if (!path)
+           path = XCURSORPATH;
+    }
+    return path;
+}
+
+static  void
+_XcursorAddPathElt (char *path, const char *elt, int len)
+{
+    int            pathlen = strlen (path);
+    
+    /* append / if the path doesn't currently have one */
+    if (path[0] == '\0' || path[pathlen - 1] != '/')
+    {
+       strcat (path, "/");
+       pathlen++;
+    }
+    if (len == -1)
+       len = strlen (elt);
+    /* strip leading slashes */
+    while (len && elt[0] == '/')
+    {
+       elt++;
+       len--;
+    }
+    strncpy (path + pathlen, elt, len);
+    path[pathlen + len] = '\0';
+}
+
+static char *
+_XcursorBuildThemeDir (const char *dir, const char *theme)
+{
+    const char     *colon;
+    const char     *tcolon;
+    char           *full;
+    char           *home;
+    int                    dirlen;
+    int                    homelen;
+    int                    themelen;
+    int                    len;
+
+    if (!dir || !theme)
+        return NULL;
+    
+    colon = strchr (dir, ':');
+    if (!colon)
+       colon = dir + strlen (dir);
+    
+    dirlen = colon - dir;
+
+    tcolon = strchr (theme, ':');
+    if (!tcolon)
+       tcolon = theme + strlen (theme);
+
+    themelen = tcolon - theme;
+    
+    home = NULL;
+    homelen = 0;
+    if (*dir == '~')
+    {
+       home = getenv ("HOME");
+       if (!home)
+           return NULL;
+       homelen = strlen (home);
+       dir++;
+       dirlen--;
+    }
+
+    /*
+     * add space for any needed directory separators, one per component,
+     * and one for the trailing null
+     */
+    len = 1 + homelen + 1 + dirlen + 1 + themelen + 1;
+    
+    full = malloc (len);
+    if (!full)
+       return NULL;
+    full[0] = '\0';
+
+    if (home)
+       _XcursorAddPathElt (full, home, -1);
+    _XcursorAddPathElt (full, dir, dirlen);
+    _XcursorAddPathElt (full, theme, themelen);
+    return full;
+}
+
+static char *
+_XcursorBuildFullname (const char *dir, const char *subdir, const char *file)
+{
+    char    *full;
+
+    if (!dir || !subdir || !file)
+        return NULL;
+
+    full = malloc (strlen (dir) + 1 + strlen (subdir) + 1 + strlen (file) + 1);
+    if (!full)
+       return NULL;
+    full[0] = '\0';
+    _XcursorAddPathElt (full, dir, -1);
+    _XcursorAddPathElt (full, subdir, -1);
+    _XcursorAddPathElt (full, file, -1);
+    return full;
+}
+
+static const char *
+_XcursorNextPath (const char *path)
+{
+    char    *colon = strchr (path, ':');
+
+    if (!colon)
+       return NULL;
+    return colon + 1;
+}
+
+#define XcursorWhite(c)        ((c) == ' ' || (c) == '\t' || (c) == '\n')
+#define XcursorSep(c) ((c) == ';' || (c) == ',')
+
+static char *
+_XcursorThemeInherits (const char *full)
+{
+    char    line[8192];
+    char    *result = NULL;
+    FILE    *f;
+
+    if (!full)
+        return NULL;
+
+    f = fopen (full, "r");
+    if (f)
+    {
+       while (fgets (line, sizeof (line), f))
+       {
+           if (!strncmp (line, "Inherits", 8))
+           {
+               char    *l = line + 8;
+               char    *r;
+               while (*l == ' ') l++;
+               if (*l != '=') continue;
+               l++;
+               while (*l == ' ') l++;
+               result = malloc (strlen (l));
+               if (result)
+               {
+                   r = result;
+                   while (*l) 
+                   {
+                       while (XcursorSep(*l) || XcursorWhite (*l)) l++;
+                       if (!*l)
+                           break;
+                       if (r != result)
+                           *r++ = ':';
+                       while (*l && !XcursorWhite(*l) && 
+                              !XcursorSep(*l))
+                           *r++ = *l++;
+                   }
+                   *r++ = '\0';
+               }
+               break;
+           }
+       }
+       fclose (f);
+    }
+    return result;
+}
+
+#define XCURSOR_SCAN_CORE   ((FILE *) 1)
+
+static FILE *
+XcursorScanTheme (const char *theme, const char *name)
+{
+    FILE       *f = NULL;
+    char       *full;
+    char       *dir;
+    const char  *path;
+    char       *inherits = NULL;
+    const char *i;
+
+    if (!theme || !name)
+        return NULL;
+
+    /*
+     * XCURSOR_CORE_THEME is a magic name; cursors from the core set
+     * are never found in any directory.  Instead, a magic value is
+     * returned which truncates any search so that overlying functions
+     * can switch to equivalent core cursors
+     */
+    if (!strcmp (theme, XCURSOR_CORE_THEME) && XcursorLibraryShape (name) >= 0)
+       return XCURSOR_SCAN_CORE;
+    /*
+     * Scan this theme
+     */
+    for (path = XcursorLibraryPath ();
+        path && f == NULL;
+        path = _XcursorNextPath (path))
+    {
+       dir = _XcursorBuildThemeDir (path, theme);
+       if (dir)
+       {
+           full = _XcursorBuildFullname (dir, "cursors", name);
+           if (full)
+           {
+               f = fopen (full, "r");
+               free (full);
+           }
+           if (!f && !inherits)
+           {
+               full = _XcursorBuildFullname (dir, "", "index.theme");
+               if (full)
+               {
+                   inherits = _XcursorThemeInherits (full);
+                   free (full);
+               }
+           }
+           free (dir);
+       }
+    }
+    /*
+     * Recurse to scan inherited themes
+     */
+    for (i = inherits; i && f == NULL; i = _XcursorNextPath (i))
+       f = XcursorScanTheme (i, name);
+    if (inherits != NULL)
+       free (inherits);
+    return f;
+}
+
+XcursorImage *
+XcursorLibraryLoadImage (const char *file, const char *theme, int size)
+{
+    FILE           *f = NULL;
+    XcursorImage    *image = NULL;
+
+    if (!file)
+        return NULL;
+
+    if (theme)
+       f = XcursorScanTheme (theme, file);
+    if (!f)
+       f = XcursorScanTheme ("default", file);
+    if (f == XCURSOR_SCAN_CORE)
+       return NULL;
+    if (f)
+    {
+       image = XcursorFileLoadImage (f, size);
+       fclose (f);
+    }
+    return image;
+}
+
+XcursorImages *
+XcursorLibraryLoadImages (const char *file, const char *theme, int size)
+{
+    FILE           *f = NULL;
+    XcursorImages   *images = NULL;
+
+    if (!file)
+        return NULL;
+
+    if (theme)
+       f = XcursorScanTheme (theme, file);
+    if (!f)
+       f = XcursorScanTheme ("default", file);
+    if (f == XCURSOR_SCAN_CORE)
+       return NULL;
+    if (f)
+    {
+       images = XcursorFileLoadImages (f, size);
+       if (images)
+           XcursorImagesSetName (images, file);
+       fclose (f);
+    }
+    return images;
+}
+
+Cursor
+XcursorLibraryLoadCursor (Display *dpy, const char *file)
+{
+    int                    size = XcursorGetDefaultSize (dpy);
+    char           *theme = XcursorGetTheme (dpy);
+    XcursorImages   *images = XcursorLibraryLoadImages (file, theme, size);
+    Cursor         cursor;
+
+    if (!file)
+        return 0;
+    
+    if (!images)
+    {
+       int id = XcursorLibraryShape (file);
+
+       if (id >= 0)
+           return _XcursorCreateFontCursor (dpy, id);
+       else
+           return 0;
+    }
+    cursor = XcursorImagesLoadCursor (dpy, images);
+    XcursorImagesDestroy (images);
+#if defined HAVE_XFIXES && XFIXES_MAJOR >= 2
+    XFixesSetCursorName (dpy, cursor, file);
+#endif
+    return cursor;
+}
+
+XcursorCursors *
+XcursorLibraryLoadCursors (Display *dpy, const char *file)
+{
+    int                    size = XcursorGetDefaultSize (dpy);
+    char           *theme = XcursorGetTheme (dpy);
+    XcursorImages   *images = XcursorLibraryLoadImages (file, theme, size);
+    XcursorCursors  *cursors;
+    
+    if (!file)
+        return NULL;
+    
+    if (!images)
+    {
+       int id = XcursorLibraryShape (file);
+
+       if (id >= 0)
+       {
+           cursors = XcursorCursorsCreate (dpy, 1);
+           if (cursors)
+           {
+               cursors->cursors[0] = _XcursorCreateFontCursor (dpy, id);
+               if (cursors->cursors[0] == None)
+               {
+                   XcursorCursorsDestroy (cursors);
+                   cursors = NULL;
+               }
+               else
+                   cursors->ncursor = 1;
+           }
+       }
+       else
+           cursors = NULL;
+    }
+    else
+    {
+       cursors = XcursorImagesLoadCursors (dpy, images);
+       XcursorImagesDestroy (images);
+    }
+    return cursors;
+}
+
+static const char _XcursorStandardNames[] =
+       "X_cursor\0"
+       "arrow\0"
+       "based_arrow_down\0"
+       "based_arrow_up\0"
+       "boat\0"
+       "bogosity\0"
+       "bottom_left_corner\0"
+       "bottom_right_corner\0"
+       "bottom_side\0"
+       "bottom_tee\0"
+       "box_spiral\0"
+       "center_ptr\0"
+       "circle\0"
+       "clock\0"
+       "coffee_mug\0"
+       "cross\0"
+       "cross_reverse\0"
+       "crosshair\0"
+       "diamond_cross\0"
+       "dot\0"
+       "dotbox\0"
+       "double_arrow\0"
+       "draft_large\0"
+       "draft_small\0"
+       "draped_box\0"
+       "exchange\0"
+       "fleur\0"
+       "gobbler\0"
+       "gumby\0"
+       "hand1\0"
+       "hand2\0"
+       "heart\0"
+       "icon\0"
+       "iron_cross\0"
+       "left_ptr\0"
+       "left_side\0"
+       "left_tee\0"
+       "leftbutton\0"
+       "ll_angle\0"
+       "lr_angle\0"
+       "man\0"
+       "middlebutton\0"
+       "mouse\0"
+       "pencil\0"
+       "pirate\0"
+       "plus\0"
+       "question_arrow\0"
+       "right_ptr\0"
+       "right_side\0"
+       "right_tee\0"
+       "rightbutton\0"
+       "rtl_logo\0"
+       "sailboat\0"
+       "sb_down_arrow\0"
+       "sb_h_double_arrow\0"
+       "sb_left_arrow\0"
+       "sb_right_arrow\0"
+       "sb_up_arrow\0"
+       "sb_v_double_arrow\0"
+       "shuttle\0"
+       "sizing\0"
+       "spider\0"
+       "spraycan\0"
+       "star\0"
+       "target\0"
+       "tcross\0"
+       "top_left_arrow\0"
+       "top_left_corner\0"
+       "top_right_corner\0"
+       "top_side\0"
+       "top_tee\0"
+       "trek\0"
+       "ul_angle\0"
+       "umbrella\0"
+       "ur_angle\0"
+       "watch\0"
+       "xterm";
+
+static const unsigned short _XcursorStandardNameOffsets[] = {
+       0, 9, 15, 32, 47, 52, 61, 80, 100, 112, 123, 134, 145, 152, 158,
+       169, 175, 189, 199, 213, 217, 224, 237, 249, 261, 272, 281, 287,
+       295, 301, 307, 313, 319, 324, 335, 344, 354, 363, 374, 383, 392,
+       396, 409, 415, 422, 429, 434, 449, 459, 470, 480, 492, 501, 510,
+       524, 542, 556, 571, 583, 601, 609, 616, 623, 632, 637, 644, 651,
+       666, 682, 699, 708, 716, 721, 730, 739, 748, 754
+};
+
+#define NUM_STANDARD_NAMES  (sizeof _XcursorStandardNameOffsets / sizeof _XcursorStandardNameOffsets[0])
+
+#define STANDARD_NAME(id) \
+    _XcursorStandardNames + _XcursorStandardNameOffsets[id]
+
+XcursorImage *
+XcursorShapeLoadImage (unsigned int shape, const char *theme, int size)
+{
+    unsigned int    id = shape >> 1;
+
+    if (id < NUM_STANDARD_NAMES)
+       return XcursorLibraryLoadImage (STANDARD_NAME (id), theme, size);
+    else
+       return NULL;
+}
+
+XcursorImages *
+XcursorShapeLoadImages (unsigned int shape, const char *theme, int size)
+{
+    unsigned int    id = shape >> 1;
+
+    if (id < NUM_STANDARD_NAMES)
+       return XcursorLibraryLoadImages (STANDARD_NAME (id), theme, size);
+    else
+       return NULL;
+}
+
+Cursor
+XcursorShapeLoadCursor (Display *dpy, unsigned int shape)
+{
+    unsigned int    id = shape >> 1;
+
+    if (id < NUM_STANDARD_NAMES)
+       return XcursorLibraryLoadCursor (dpy, STANDARD_NAME (id));
+    else
+       return 0;
+}
+
+XcursorCursors *
+XcursorShapeLoadCursors (Display *dpy, unsigned int shape)
+{
+    unsigned int    id = shape >> 1;
+
+    if (id < NUM_STANDARD_NAMES)
+       return XcursorLibraryLoadCursors (dpy, STANDARD_NAME (id));
+    else
+       return NULL;
+}
+
+int
+XcursorLibraryShape (const char *library)
+{
+    int        low, high;
+    int        mid;
+    int        c;
+
+    low = 0;
+    high = NUM_STANDARD_NAMES - 1;
+    while (low < high - 1)
+    {
+       mid = (low + high) >> 1;
+       c = strcmp (library, STANDARD_NAME (mid));
+       if (c == 0)
+           return (mid << 1);
+       if (c > 0)
+           low = mid;
+       else
+           high = mid;
+    }
+    while (low <= high)
+    {
+       if (!strcmp (library, STANDARD_NAME (low)))
+           return (low << 1);
+       low++;
+    }
+    return -1;
+}
diff --git a/src/xcursorint.h b/src/xcursorint.h
new file mode 100644 (file)
index 0000000..c2eec32
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _XCURSORINT_H_
+#define _XCURSORINT_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+#include <X11/extensions/Xrender.h>
+
+#ifdef HAVE_XFIXES
+#include <X11/extensions/Xfixes.h>
+#endif
+
+#include "Xcursor.h"
+#include "config.h"
+
+typedef struct _XcursorFontInfo {
+    struct _XcursorFontInfo    *next;
+    Font                       font;
+    XcursorBool                        is_cursor_font;
+} XcursorFontInfo;
+
+/*
+ * Track a few recently created bitmaps to see
+ * if they get used to create cursors.  This
+ * is done by hooking into Xlib and watching
+ * for XCreatePixmap, XPutImage, XCreatePixmapCursor
+ * with appropriate arguments.  When this happens
+ * Xcursor computes a hash value for the source image
+ * and tries to load a library cursor of that name.
+ */
+/* large bitmaps are unlikely to be cursors */
+#define MAX_BITMAP_CURSOR_SIZE 64
+/* don't need to remember very many; in fact, 2 is likely sufficient */
+#define NUM_BITMAPS        8
+
+typedef struct _XcursorBitmapInfo {
+    Pixmap         bitmap;
+    unsigned long   sequence;
+    unsigned int    width, height;
+    Bool           has_image;
+    unsigned char   hash[XCURSOR_BITMAP_HASH_SIZE];
+} XcursorBitmapInfo;
+
+typedef enum _XcursorDither {
+    XcursorDitherThreshold,
+    XcursorDitherMedian,
+    XcursorDitherOrdered,
+    XcursorDitherDiffuse
+} XcursorDither;
+
+typedef struct _XcursorDisplayInfo {
+    struct _XcursorDisplayInfo *next;
+    Display                    *display;
+    XExtCodes                  *codes;
+    XcursorBool                        has_render_cursor;
+    XcursorBool                        has_anim_cursor;
+    XcursorBool                        theme_core;
+    int                                size;
+    XcursorFontInfo            *fonts;
+    char                       *theme;
+    char                        *theme_from_config;
+    XcursorDither              dither;
+    XcursorBitmapInfo          bitmaps[NUM_BITMAPS];
+} XcursorDisplayInfo;
+
+XcursorDisplayInfo *
+_XcursorGetDisplayInfo (Display *dpy);
+
+Cursor
+_XcursorCreateGlyphCursor(Display          *dpy,
+                         Font              source_font,
+                         Font              mask_font,
+                         unsigned int      source_char,
+                         unsigned int      mask_char,
+                         XColor _Xconst    *foreground,
+                         XColor _Xconst    *background);
+
+Cursor
+_XcursorCreateFontCursor (Display *dpy, unsigned int shape);
+    
+#endif /* _XCURSORINT_H_ */
diff --git a/src/xlib.c b/src/xlib.c
new file mode 100644 (file)
index 0000000..0475d11
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * Copyright © 2002 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xcursorint.h"
+#include <X11/Xlibint.h>
+#include <X11/Xatom.h>
+#include <stdlib.h>
+
+static XcursorBool
+_XcursorFontIsCursor (Display *dpy, Font font)
+{
+    XcursorFontInfo    *fi;
+    XcursorDisplayInfo *info;
+    XcursorBool                ret;
+    XFontStruct                *fs;
+    int                        n;
+    Atom               cursor;
+
+    if (!dpy || !font)
+        return XcursorFalse;
+
+    if (font == dpy->cursor_font)
+       return XcursorTrue;
+
+    info = _XcursorGetDisplayInfo (dpy);
+    if (!info)
+       return XcursorFalse;
+    LockDisplay (dpy);
+    for (fi = info->fonts; fi; fi = fi->next)
+       if (fi->font == font)
+       {
+           ret = fi->is_cursor_font;
+           UnlockDisplay (dpy);
+           return ret;
+       }
+    UnlockDisplay (dpy);
+    ret = XcursorFalse;
+    fs = XQueryFont (dpy, font);
+    if (fs)
+    {
+       cursor = XInternAtom (dpy, "cursor", False);
+       for (n = 0; n < fs->n_properties; n++)
+           if (fs->properties[n].name == XA_FONT)
+           {
+               ret = (fs->properties[n].card32 == cursor);
+               break;
+           }
+    }
+    fi = malloc (sizeof (XcursorFontInfo));
+    if (fi)
+    {
+       fi->font = font;
+       fi->is_cursor_font = ret;
+       LockDisplay (dpy);
+       fi->next = info->fonts;
+       info->fonts = fi;
+       UnlockDisplay (dpy);
+    }
+    return ret;
+}
+
+Cursor
+XcursorTryShapeCursor (Display     *dpy,
+                      Font         source_font,
+                      Font         mask_font,
+                      unsigned int source_char,
+                      unsigned int mask_char,
+                      XColor _Xconst *foreground,
+                      XColor _Xconst *background)
+{
+    Cursor  cursor = None;
+
+    if (!dpy || !source_font || !mask_font || !foreground || !background)
+        return 0;
+    
+    if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy))
+       return None;
+    
+    if (source_font == mask_font && 
+       _XcursorFontIsCursor (dpy, source_font) &&
+       source_char + 1 == mask_char)
+    {
+       int             size = XcursorGetDefaultSize (dpy);
+       char            *theme = XcursorGetTheme (dpy);
+       XcursorImages   *images = XcursorShapeLoadImages (source_char, theme, size);
+
+       if (images)
+       {
+           cursor = XcursorImagesLoadCursor (dpy, images);
+           XcursorImagesDestroy (images);
+       }
+    }
+    return cursor;
+}
+
+void
+XcursorNoticeCreateBitmap (Display     *dpy,
+                          Pixmap       pid,
+                          unsigned int width,
+                          unsigned int height)
+{
+    XcursorDisplayInfo *info;
+    unsigned long      oldest;
+    unsigned long      now;
+    int                        i;
+    int                        replace = 0;
+    XcursorBitmapInfo  *bmi;
+
+    if (!dpy)
+        return;
+
+    if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy))
+       return;
+    
+    if (width > MAX_BITMAP_CURSOR_SIZE || height > MAX_BITMAP_CURSOR_SIZE)
+       return;
+    
+    info = _XcursorGetDisplayInfo (dpy);
+    if (!info)
+       return;
+    
+    LockDisplay (dpy);
+    replace = 0;
+    now = dpy->request;
+    oldest = now;
+    for (i = 0; i < NUM_BITMAPS; i++)
+    {
+       if (!info->bitmaps[i].bitmap)
+       {
+           replace = i;
+           break;
+       }
+       if ((long) (now - info->bitmaps[i].sequence) >
+           (long) (now - oldest))
+       {
+           replace = i;
+           oldest = info->bitmaps[i].sequence;
+       }
+    }
+    bmi = &info->bitmaps[replace];
+    bmi->bitmap = pid;
+    bmi->sequence = now;
+    bmi->width = width;
+    bmi->height = height;
+    bmi->has_image = False;
+    UnlockDisplay (dpy);
+}
+
+static XcursorBitmapInfo *
+_XcursorGetBitmap (Display *dpy, Pixmap bitmap)
+{
+    XcursorDisplayInfo *info;
+    int                        i;
+
+    if (!dpy || !bitmap)
+        return NULL;
+    
+    info = _XcursorGetDisplayInfo (dpy);
+
+    if (!info)
+       return NULL;
+    LockDisplay (dpy);
+    for (i = 0; i < NUM_BITMAPS; i++)
+       if (info->bitmaps[i].bitmap == bitmap)
+       {
+           info->bitmaps[i].sequence = dpy->request;
+           UnlockDisplay (dpy);
+           return &info->bitmaps[i];
+       }
+    UnlockDisplay (dpy);
+    return NULL;
+}
+
+static Bool
+_XcursorClientLSB (void)
+{
+    int            v = 1;
+    return *((char *) &v) == 1;
+}
+
+/* stolen from Xlib */
+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
+};
+    
+#define RotByte(t,i)    (((t) << (i)) | ((t) >> (8 - (i))))
+
+void
+XcursorImageHash (XImage         *image,
+                 unsigned char   hash[XCURSOR_BITMAP_HASH_SIZE])
+{
+    int                    i;
+    int                    x, y;
+    unsigned char   *line;
+    unsigned char   t;
+    int                    low_addr;
+    Bool           bit_swap;
+
+    if (!image)
+        return;
+
+    for (i = 0; i < XCURSOR_BITMAP_HASH_SIZE; i++)
+       hash[i] = 0;
+    /*
+     * Flip byte order on MSB machines where the bitmap_unit isn't
+     * in bytes
+     */
+    low_addr = 0;
+    if (image->bitmap_unit != 8)
+    {
+       if (!_XcursorClientLSB())
+           switch (image->bitmap_unit) {
+           case 16:
+               low_addr = 1;
+               break;
+           case 32:
+               low_addr = 3;
+               break;
+           }
+    }
+    /*
+     * Flip bit order on MSB images
+     */
+    bit_swap = (image->bitmap_bit_order != LSBFirst);
+    
+    line = (unsigned char *) image->data;
+    i = 0;
+    /*
+     * Compute the hash.  Yes, it might be nice to use
+     * a stronger hash function, but MD5 and SHA1 are both
+     * a bit to expensive in time and space for this,
+     * and cursors are generally small enough that a weak
+     * hash is sufficient to distinguish among them.
+     */
+    for (y = 0; y < image->height; y++)
+    {
+       for (x = 0; x < image->bytes_per_line; x++)
+       {
+           t = line[x^low_addr];
+           if (bit_swap)
+               t = _reverse_byte[t];
+           if (t)
+               hash[(i++) & (XCURSOR_BITMAP_HASH_SIZE - 1)] ^= RotByte (t, y & 7);
+       }
+       line += image->bytes_per_line;
+    }
+}
+
+static Bool
+_XcursorLogDiscover (void)
+{
+    static Bool        been_here;
+    static Bool        log;
+
+    if (!been_here)
+    {
+       been_here = True;
+
+       if (getenv ("XCURSOR_DISCOVER"))
+           log = True;
+    }
+    return log;
+}
+    
+void
+XcursorNoticePutBitmap (Display            *dpy,
+                       Drawable    draw,
+                       XImage      *image)
+{
+    XcursorBitmapInfo  *bmi;
+
+    if (!dpy || !image)
+        return;
+    
+    if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy))
+       return;
+    
+    if (image->width > MAX_BITMAP_CURSOR_SIZE || 
+       image->height > MAX_BITMAP_CURSOR_SIZE)
+       return;
+    
+    bmi = _XcursorGetBitmap (dpy, (Pixmap) draw);
+    if (!bmi)
+       return;
+    /*
+     * Make sure the image fills the bitmap
+     */
+    if (image->width != bmi->width || image->height != bmi->height)
+    {
+       bmi->bitmap = 0;
+       return;
+    }
+    /*
+     * If multiple images are placed in the same bitmap,
+     * assume it's not going to be a cursor
+     */
+    if (bmi->has_image)
+    {
+       bmi->bitmap = 0;
+       return;
+    }
+    /*
+     * Make sure the image is valid
+     */
+    if (image->bytes_per_line & ((image->bitmap_unit >> 3) - 1))
+    {
+       bmi->bitmap = 0;
+       return;
+    }
+    /*
+     * Hash the image
+     */
+    XcursorImageHash (image, bmi->hash);
+    /*
+     * Display the hash value and the image if
+     * requested so that users can find out what
+     * cursor name is associated with each image
+     */
+    if (_XcursorLogDiscover())
+    {
+       int x, y;
+       int i;
+       XImage  t = *image;
+
+       XInitImage (&t);
+       
+       printf ("Cursor image name: ");
+       for (i = 0; i < XCURSOR_BITMAP_HASH_SIZE; i++)
+           printf ("%02x", bmi->hash[i]);
+       printf ("\n");
+       for (y = 0; y < image->height; y++)
+       {
+           for (x = 0; x < image->width; x++)
+               putchar (XGetPixel (&t, x, y) ? '*' : ' ');
+           putchar ('\n');
+       }
+    }
+    bmi->has_image = True;
+}
+
+Cursor
+XcursorTryShapeBitmapCursor (Display           *dpy,
+                            Pixmap             source,
+                            Pixmap             mask,
+                            XColor             *foreground,
+                            XColor             *background,
+                            unsigned int       x,
+                            unsigned int       y)
+{
+    XcursorBitmapInfo  *bmi;
+    char               name[8 * XCURSOR_BITMAP_HASH_SIZE];
+    int                        i;
+    Cursor             cursor;
+
+    if (!dpy || !foreground || !background)
+        return 0;
+
+    if (!XcursorSupportsARGB (dpy) && !XcursorGetThemeCore (dpy))
+       return None;
+    
+    bmi = _XcursorGetBitmap (dpy, source);
+    if (!bmi || !bmi->has_image)
+       return None;
+    for (i = 0; i < XCURSOR_BITMAP_HASH_SIZE; i++)
+       sprintf (name + 2 * i, "%02x", bmi->hash[i]);
+    cursor = XcursorLibraryLoadCursor (dpy, name);
+    if (_XcursorLogDiscover())
+       printf ("Cursor hash %s returns 0x%x\n", name, (unsigned int) cursor);
+    return cursor;
+}
diff --git a/xcursor.pc.in b/xcursor.pc.in
new file mode 100644 (file)
index 0000000..f55bed3
--- /dev/null
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+datarootdir=@datarootdir@
+icondir=@ICONDIR@
+
+Name: Xcursor
+Description: X Cursor Library
+Version: @VERSION@
+Requires: xproto
+Requires.private: x11 xrender xfixes
+Cflags: -I${includedir}
+Libs: -L${libdir} -lXcursor