1/*
2 * Copyright © 2024 Thomas E. Dickey
3 * Copyright © 2002 Keith Packard
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  Keith Packard makes no
12 * representations about the suitability of this software for any purpose.  It
13 * is provided "as is" without express or implied warranty.
14 *
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24#ifndef _XCURSOR_H_
25#define _XCURSOR_H_
26#include <stdio.h>
27#include <stdint.h>
28#include <X11/Xfuncproto.h>
29#include <X11/Xlib.h>
30
31typedef int		XcursorBool;
32typedef uint32_t	XcursorUInt;
33
34typedef XcursorUInt	XcursorDim;
35typedef XcursorUInt	XcursorPixel;
36
37#define XcursorTrue	1
38#define XcursorFalse	0
39
40/*
41 * Cursor files start with a header.  The header
42 * contains a magic number, a version number and a
43 * table of contents which has type and offset information
44 * for the remaining tables in the file.
45 *
46 * File minor versions increment for compatible changes
47 * File major versions increment for incompatible changes (never, we hope)
48 *
49 * Chunks of the same type are always upward compatible.  Incompatible
50 * changes are made with new chunk types; the old data can remain under
51 * the old type.  Upward compatible changes can add header data as the
52 * header lengths are specified in the file.
53 *
54 *  File:
55 *	FileHeader
56 *	LISTofChunk
57 *
58 *  FileHeader:
59 *	CARD32		magic	    magic number
60 *	CARD32		header	    bytes in file header
61 *	CARD32		version	    file version
62 *	CARD32		ntoc	    number of toc entries
63 *	LISTofFileToc   toc	    table of contents
64 *
65 *  FileToc:
66 *	CARD32		type	    entry type
67 *	CARD32		subtype	    entry subtype (size for images)
68 *	CARD32		position    absolute file position
69 */
70
71#define XCURSOR_MAGIC	0x72756358  /* "Xcur" LSBFirst */
72
73/*
74 * Current Xcursor version number.  Will be substituted by configure
75 * from the version in the libXcursor configure.ac file.
76 */
77
78#undef XCURSOR_LIB_MAJOR
79#undef XCURSOR_LIB_MINOR
80#undef XCURSOR_LIB_REVISION
81#define XCURSOR_LIB_VERSION	((XCURSOR_LIB_MAJOR * 10000) + \
82				 (XCURSOR_LIB_MINOR * 100) + \
83				 (XCURSOR_LIB_REVISION))
84
85/*
86 * This version number is stored in cursor files; changes to the
87 * file format require updating this version number
88 */
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)
94
95typedef struct _XcursorFileToc {
96    XcursorUInt	    type;	/* chunk type */
97    XcursorUInt	    subtype;	/* subtype (size for images) */
98    XcursorUInt	    position;	/* absolute position in file */
99} XcursorFileToc;
100
101typedef struct _XcursorFileHeader {
102    XcursorUInt	    magic;	/* magic number */
103    XcursorUInt	    header;	/* byte length of header */
104    XcursorUInt	    version;	/* file version number */
105    XcursorUInt	    ntoc;	/* number of toc entries */
106    XcursorFileToc  *tocs;	/* table of contents */
107} XcursorFileHeader;
108
109/*
110 * The rest of the file is a list of chunks, each tagged by type
111 * and version.
112 *
113 *  Chunk:
114 *	ChunkHeader
115 *	<extra type-specific header fields>
116 *	<type-specific data>
117 *
118 *  ChunkHeader:
119 *	CARD32	    header	bytes in chunk header + type header
120 *	CARD32	    type	chunk type
121 *	CARD32	    subtype	chunk subtype
122 *	CARD32	    version	chunk type version
123 */
124
125#define XCURSOR_CHUNK_HEADER_LEN    (4 * 4)
126
127typedef struct _XcursorChunkHeader {
128    XcursorUInt	    header;	/* bytes in chunk header */
129    XcursorUInt	    type;	/* chunk type */
130    XcursorUInt	    subtype;	/* chunk subtype (size for images) */
131    XcursorUInt	    version;	/* version of this type */
132} XcursorChunkHeader;
133
134/*
135 * Here's a list of the known chunk types
136 */
137
138/*
139 * Comments consist of a 4-byte length field followed by
140 * UTF-8 encoded text
141 *
142 *  Comment:
143 *	ChunkHeader header	chunk header
144 *	CARD32	    length	bytes in text
145 *	LISTofCARD8 text	UTF-8 encoded text
146 */
147
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
155
156typedef struct _XcursorComment {
157    XcursorUInt	    version;
158    XcursorUInt	    comment_type;
159    char	    *comment;
160} XcursorComment;
161
162/*
163 * Each cursor image occupies a separate image chunk.
164 * The length of the image header follows the chunk header
165 * so that future versions can extend the header without
166 * breaking older applications
167 *
168 *  Image:
169 *	ChunkHeader	header	chunk header
170 *	CARD32		width	actual width
171 *	CARD32		height	actual height
172 *	CARD32		xhot	hot spot x
173 *	CARD32		yhot	hot spot y
174 *	CARD32		delay	animation delay
175 *	LISTofCARD32	pixels	ARGB pixels
176 */
177
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	/* 32767x32767 max cursor size */
182
183typedef struct _XcursorImage {
184    XcursorUInt	    version;	/* version of the image data */
185    XcursorDim	    size;	/* nominal size for matching */
186    XcursorDim	    width;	/* actual width */
187    XcursorDim	    height;	/* actual height */
188    XcursorDim	    xhot;	/* hot spot x (must be inside image) */
189    XcursorDim	    yhot;	/* hot spot y (must be inside image) */
190    XcursorUInt	    delay;	/* animation delay to next frame (ms) */
191    XcursorPixel    *pixels;	/* pointer to pixels */
192} XcursorImage;
193
194/*
195 * Other data structures exposed by the library API
196 */
197typedef struct _XcursorImages {
198    int		    nimage;	/* number of images */
199    XcursorImage    **images;	/* array of XcursorImage pointers */
200    char	    *name;	/* name used to load images */
201} XcursorImages;
202
203typedef struct _XcursorCursors {
204    Display	    *dpy;	/* Display holding cursors */
205    int		    ref;	/* reference count */
206    int		    ncursor;	/* number of cursors */
207    Cursor	    *cursors;	/* array of cursors */
208} XcursorCursors;
209
210typedef struct _XcursorAnimate {
211    XcursorCursors   *cursors;	/* list of cursors to use */
212    int		    sequence;	/* which cursor is next */
213} XcursorAnimate;
214
215typedef struct _XcursorFile XcursorFile;
216
217struct _XcursorFile {
218    void    *closure;
219    int	    (*read)  (XcursorFile *file, unsigned char *buf, int len);
220    int	    (*write) (XcursorFile *file, unsigned char *buf, int len);
221    int	    (*seek)  (XcursorFile *file, long offset, int whence);
222};
223
224typedef struct _XcursorComments {
225    int		    ncomment;	/* number of comments */
226    XcursorComment  **comments;	/* array of XcursorComment pointers */
227} XcursorComments;
228
229#define XCURSOR_CORE_THEME  "core"
230
231_XFUNCPROTOBEGIN
232
233/*
234 * Manage Image objects
235 */
236XcursorImage *
237XcursorImageCreate (int width, int height);
238
239void
240XcursorImageDestroy (XcursorImage *image);
241
242/*
243 * Manage Images objects
244 */
245XcursorImages *
246XcursorImagesCreate (int size);
247
248void
249XcursorImagesDestroy (XcursorImages *images);
250
251void
252XcursorImagesSetName (XcursorImages *images, const char *name);
253
254/*
255 * Manage Cursor objects
256 */
257XcursorCursors *
258XcursorCursorsCreate (Display *dpy, int size);
259
260void
261XcursorCursorsDestroy (XcursorCursors *cursors);
262
263/*
264 * Manage Animate objects
265 */
266XcursorAnimate *
267XcursorAnimateCreate (XcursorCursors *cursors);
268
269void
270XcursorAnimateDestroy (XcursorAnimate *animate);
271
272Cursor
273XcursorAnimateNext (XcursorAnimate *animate);
274
275/*
276 * Manage Comment objects
277 */
278XcursorComment *
279XcursorCommentCreate (XcursorUInt comment_type, int length);
280
281void
282XcursorCommentDestroy (XcursorComment *comment);
283
284XcursorComments *
285XcursorCommentsCreate (int size);
286
287void
288XcursorCommentsDestroy (XcursorComments *comments);
289
290/*
291 * XcursorFile/Image APIs
292 */
293XcursorImage *
294XcursorXcFileLoadImage (XcursorFile *file, int size);
295
296XcursorImages *
297XcursorXcFileLoadImages (XcursorFile *file, int size);
298
299XcursorImages *
300XcursorXcFileLoadAllImages (XcursorFile *file);
301
302XcursorBool
303XcursorXcFileLoad (XcursorFile	    *file,
304		   XcursorComments  **commentsp,
305		   XcursorImages    **imagesp);
306
307XcursorBool
308XcursorXcFileSave (XcursorFile		    *file,
309		   const XcursorComments    *comments,
310		   const XcursorImages	    *images);
311
312/*
313 * FILE/Image APIs
314 */
315XcursorImage *
316XcursorFileLoadImage (FILE *file, int size);
317
318XcursorImages *
319XcursorFileLoadImages (FILE *file, int size);
320
321XcursorImages *
322XcursorFileLoadAllImages (FILE *file);
323
324XcursorBool
325XcursorFileLoad (FILE		    *file,
326		 XcursorComments    **commentsp,
327		 XcursorImages	    **imagesp);
328
329XcursorBool
330XcursorFileSaveImages (FILE *file, const XcursorImages *images);
331
332XcursorBool
333XcursorFileSave (FILE *			file,
334		 const XcursorComments	*comments,
335		 const XcursorImages	*images);
336
337/*
338 * Filename/Image APIs
339 */
340XcursorImage *
341XcursorFilenameLoadImage (const char *filename, int size);
342
343XcursorImages *
344XcursorFilenameLoadImages (const char *filename, int size);
345
346XcursorImages *
347XcursorFilenameLoadAllImages (const char *filename);
348
349XcursorBool
350XcursorFilenameLoad (const char		*file,
351		     XcursorComments	**commentsp,
352		     XcursorImages	**imagesp);
353
354XcursorBool
355XcursorFilenameSaveImages (const char *filename, const XcursorImages *images);
356
357XcursorBool
358XcursorFilenameSave (const char		    *file,
359		     const XcursorComments  *comments,
360		     const XcursorImages    *images);
361
362/*
363 * Library/Image APIs
364 */
365XcursorImage *
366XcursorLibraryLoadImage (const char *library, const char *theme, int size);
367
368XcursorImages *
369XcursorLibraryLoadImages (const char *library, const char *theme, int size);
370
371/*
372 * Library/shape API
373 */
374
375const char *
376XcursorLibraryPath (void);
377
378int
379XcursorLibraryShape (const char *library);
380
381/*
382 * Image/Cursor APIs
383 */
384
385Cursor
386XcursorImageLoadCursor (Display *dpy, const XcursorImage *image);
387
388XcursorCursors *
389XcursorImagesLoadCursors (Display *dpy, const XcursorImages *images);
390
391Cursor
392XcursorImagesLoadCursor (Display *dpy, const XcursorImages *images);
393
394/*
395 * Filename/Cursor APIs
396 */
397Cursor
398XcursorFilenameLoadCursor (Display *dpy, const char *file);
399
400XcursorCursors *
401XcursorFilenameLoadCursors (Display *dpy, const char *file);
402
403/*
404 * Library/Cursor APIs
405 */
406Cursor
407XcursorLibraryLoadCursor (Display *dpy, const char *file);
408
409XcursorCursors *
410XcursorLibraryLoadCursors (Display *dpy, const char *file);
411
412/*
413 * Shape/Image APIs
414 */
415
416XcursorImage *
417XcursorShapeLoadImage (unsigned int shape, const char *theme, int size);
418
419XcursorImages *
420XcursorShapeLoadImages (unsigned int shape, const char *theme, int size);
421
422/*
423 * Shape/Cursor APIs
424 */
425Cursor
426XcursorShapeLoadCursor (Display *dpy, unsigned int shape);
427
428XcursorCursors *
429XcursorShapeLoadCursors (Display *dpy, unsigned int shape);
430
431/*
432 * This is the function called by Xlib when attempting to
433 * load cursors from XCreateGlyphCursor.  The interface must
434 * not change as Xlib loads 'libXcursor.so' instead of
435 * a specific major version
436 */
437Cursor
438XcursorTryShapeCursor (Display	    *dpy,
439		       Font	    source_font,
440		       Font	    mask_font,
441		       unsigned int source_char,
442		       unsigned int mask_char,
443		       XColor _Xconst *foreground,
444		       XColor _Xconst *background);
445
446void
447XcursorNoticeCreateBitmap (Display	*dpy,
448			   Pixmap	pid,
449			   unsigned int width,
450			   unsigned int height);
451
452void
453XcursorNoticePutBitmap (Display	    *dpy,
454			Drawable    draw,
455			XImage	    *image);
456
457Cursor
458XcursorTryShapeBitmapCursor (Display		*dpy,
459			     Pixmap		source,
460			     Pixmap		mask,
461			     XColor		*foreground,
462			     XColor		*background,
463			     unsigned int	x,
464			     unsigned int	y);
465
466#define XCURSOR_BITMAP_HASH_SIZE    16
467
468void
469XcursorImageHash (XImage	*image,
470		  unsigned char	hash[XCURSOR_BITMAP_HASH_SIZE]);
471
472/*
473 * Display information APIs
474 */
475XcursorBool
476XcursorSupportsARGB (Display *dpy);
477
478XcursorBool
479XcursorSupportsAnim (Display *dpy);
480
481XcursorBool
482XcursorSetDefaultSize (Display *dpy, int size);
483
484int
485XcursorGetDefaultSize (Display *dpy);
486
487XcursorBool
488XcursorSetResizable (Display *dpy, XcursorBool flag);
489
490XcursorBool
491XcursorGetResizable (Display *dpy);
492
493XcursorBool
494XcursorSetTheme (Display *dpy, const char *theme);
495
496char *
497XcursorGetTheme (Display *dpy);
498
499XcursorBool
500XcursorGetThemeCore (Display *dpy);
501
502XcursorBool
503XcursorSetThemeCore (Display *dpy, XcursorBool theme_core);
504
505_XFUNCPROTOEND
506
507#endif
508