26#define _DEFAULT_SOURCE
71#define XCURSOR_MAGIC 0x72756358
78#define XCURSOR_LIB_MAJOR 1
79#define XCURSOR_LIB_MINOR 1
80#define XCURSOR_LIB_REVISION 13
81#define XCURSOR_LIB_VERSION ((XCURSOR_LIB_MAJOR * 10000) + \
82 (XCURSOR_LIB_MINOR * 100) + \
83 (XCURSOR_LIB_REVISION))
89#define XCURSOR_FILE_MAJOR 1
90#define XCURSOR_FILE_MINOR 0
91#define XCURSOR_FILE_VERSION ((XCURSOR_FILE_MAJOR << 16) | (XCURSOR_FILE_MINOR))
92#define XCURSOR_FILE_HEADER_LEN (4 * 4)
93#define XCURSOR_FILE_TOC_LEN (3 * 4)
125#define XCURSOR_CHUNK_HEADER_LEN (4 * 4)
148#define XCURSOR_COMMENT_TYPE 0xfffe0001
149#define XCURSOR_COMMENT_VERSION 1
150#define XCURSOR_COMMENT_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (1 *4))
151#define XCURSOR_COMMENT_COPYRIGHT 1
152#define XCURSOR_COMMENT_LICENSE 2
153#define XCURSOR_COMMENT_OTHER 3
154#define XCURSOR_COMMENT_MAX_LEN 0x100000
178#define XCURSOR_IMAGE_TYPE 0xfffd0002
179#define XCURSOR_IMAGE_VERSION 1
180#define XCURSOR_IMAGE_HEADER_LEN (XCURSOR_CHUNK_HEADER_LEN + (5*4))
181#define XCURSOR_IMAGE_MAX_SIZE 0x7fff
202XcursorImageCreate (
int width,
int height)
206 if (width < 0 || height < 0)
217 image->
size = width > height ? width : height;
218 image->
width = width;
231XcursorImagesCreate (
int size)
252 for (n = 0; n < images->
nimage; n++)
253 XcursorImageDestroy (images->
images[n]);
260 unsigned char bytes[4];
265 if ((*file->
read) (file, bytes, 4) != 4)
295 fileHeader->
ntoc = ntoc;
310 if (!_XcursorReadUInt (file, &head.
magic))
314 if (!_XcursorReadUInt (file, &head.
header))
316 if (!_XcursorReadUInt (file, &head.
version))
318 if (!_XcursorReadUInt (file, &head.
ntoc))
322 if ((*file->
seek) (file, skip, SEEK_CUR) == EOF)
324 fileHeader = _XcursorFileHeaderCreate (head.
ntoc);
331 for (n = 0; n < fileHeader->
ntoc; n++)
333 if (!_XcursorReadUInt (file, &fileHeader->
tocs[n].
type))
335 if (!_XcursorReadUInt (file, &fileHeader->
tocs[n].
subtype))
337 if (!_XcursorReadUInt (file, &fileHeader->
tocs[n].
position))
340 if (n != fileHeader->
ntoc)
342 _XcursorFileHeaderDestroy (fileHeader);
353 if (!file || !fileHeader || \
365 if (!file || !fileHeader || !chunkHeader)
367 if (!_XcursorSeekToToc (file, fileHeader, toc))
369 if (!_XcursorReadUInt (file, &chunkHeader->
header))
371 if (!_XcursorReadUInt (file, &chunkHeader->
type))
373 if (!_XcursorReadUInt (file, &chunkHeader->
subtype))
375 if (!_XcursorReadUInt (file, &chunkHeader->
version))
384#define dist(a,b) ((a) > (b) ? (a) - (b) : (b) - (a))
396 if (!fileHeader || !nsizesp)
399 for (n = 0; n < fileHeader->
ntoc; n++)
404 if (!bestSize ||
dist (thisSize, size) <
dist (bestSize, size))
409 else if (thisSize == bestSize)
427 for (toc = 0; toc < fileHeader->
ntoc; toc++)
432 if (thisSize != size)
438 if (toc == fileHeader->
ntoc)
454 if (!file || !fileHeader)
457 if (!_XcursorFileReadChunkHeader (file, fileHeader, toc, &chunkHeader))
459 if (!_XcursorReadUInt (file, &head.
width))
461 if (!_XcursorReadUInt (file, &head.
height))
463 if (!_XcursorReadUInt (file, &head.
xhot))
465 if (!_XcursorReadUInt (file, &head.
yhot))
467 if (!_XcursorReadUInt (file, &head.
delay))
479 image = XcursorImageCreate (head.
width, head.
height);
492 if (!_XcursorReadUInt (file, p))
494 XcursorImageDestroy (image);
503XcursorXcFileLoadImages (
XcursorFile *file,
int size)
512 if (!file || size < 0)
514 fileHeader = _XcursorReadFileHeader (file);
517 bestSize = _XcursorFindBestSize (fileHeader, (
XcursorDim) size, &nsize);
520 _XcursorFileHeaderDestroy (fileHeader);
523 images = XcursorImagesCreate (nsize);
526 _XcursorFileHeaderDestroy (fileHeader);
529 for (n = 0; n < nsize; n++)
531 toc = _XcursorFindImageToc (fileHeader, bestSize, n);
534 images->
images[images->
nimage] = _XcursorReadImage (file, fileHeader,
540 _XcursorFileHeaderDestroy (fileHeader);
541 if (images->
nimage != nsize)
550_XcursorStdioFileRead (
XcursorFile *file,
unsigned char *buf,
int len)
553 return fread (buf, 1, len, f);
557_XcursorStdioFileWrite (
XcursorFile *file,
unsigned char *buf,
int len)
560 return fwrite (buf, 1, len, f);
564_XcursorStdioFileSeek (
XcursorFile *file,
long offset,
int whence)
567 return fseek (f, offset, whence);
571_XcursorStdioFileInitialize (FILE *stdfile,
XcursorFile *file)
574 file->
read = _XcursorStdioFileRead;
575 file->
write = _XcursorStdioFileWrite;
576 file->
seek = _XcursorStdioFileSeek;
585 FILE *fp = fopen(file,
"r");
589 _XcursorStdioFileInitialize (fp, &f);
590 images = XcursorXcFileLoadImages (&f, size);
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)
struct _XcursorFileToc XcursorFileToc
void XcursorImagesDestroy(XcursorImages *images)
XcursorImages * XcursorFileLoadImages(const char *file, int size)
struct _XcursorComments XcursorComments
#define XCURSOR_FILE_HEADER_LEN
#define XCURSOR_FILE_VERSION
struct _XcursorFileHeader XcursorFileHeader
#define XCURSOR_IMAGE_VERSION
#define XCURSOR_IMAGE_MAX_SIZE
struct _XcursorComment XcursorComment
#define XCURSOR_IMAGE_TYPE
struct _XcursorChunkHeader XcursorChunkHeader