Cursor.c revision 521070a0
1/*
2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23/*
24 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
25 *
26 * Permission to use, copy, modify, distribute, and sell this software and its
27 * documentation for any purpose is hereby granted without fee, provided that
28 * the above copyright notice appear in all copies and that both that
29 * copyright notice and this permission notice appear in supporting
30 * documentation, and that the name of Keith Packard not be used in
31 * advertising or publicity pertaining to distribution of the software without
32 * specific, written prior permission.  Keith Packard makes no
33 * representations about the suitability of this software for any purpose.  It
34 * is provided "as is" without express or implied warranty.
35 *
36 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
37 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
38 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
39 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
40 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
41 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
42 * PERFORMANCE OF THIS SOFTWARE.
43 */
44
45#ifdef HAVE_CONFIG_H
46#include <config.h>
47#endif
48#include "Xfixesint.h"
49
50void
51XFixesSelectCursorInput (Display	*dpy,
52			 Window		win,
53			 unsigned long	eventMask)
54{
55    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
56    xXFixesSelectCursorInputReq	    *req;
57
58    XFixesSimpleCheckExtension (dpy, info);
59
60    LockDisplay (dpy);
61    GetReq (XFixesSelectCursorInput, req);
62    req->reqType = info->codes->major_opcode;
63    req->xfixesReqType = X_XFixesSelectCursorInput;
64    req->window = win;
65    req->eventMask = eventMask;
66    UnlockDisplay (dpy);
67    SyncHandle ();
68}
69
70XFixesCursorImage *
71XFixesGetCursorImage (Display *dpy)
72{
73    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
74    xXFixesGetCursorImageAndNameReq	*req;
75    xXFixesGetCursorImageAndNameReply	rep;
76    int					npixels;
77    int					nbytes_name;
78    int					nbytes, nread, rlength;
79    XFixesCursorImage			*image;
80    char				*name;
81
82    XFixesCheckExtension (dpy, info, NULL);
83    LockDisplay (dpy);
84    GetReq (XFixesGetCursorImageAndName, req);
85    req->reqType = info->codes->major_opcode;
86    if (info->major_version >= 2)
87	req->xfixesReqType = X_XFixesGetCursorImageAndName;
88    else
89	req->xfixesReqType = X_XFixesGetCursorImage;
90    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
91    {
92	UnlockDisplay (dpy);
93	SyncHandle ();
94	return NULL;
95    }
96    if (info->major_version < 2)
97    {
98	rep.cursorName = None;
99	rep.nbytes = 0;
100    }
101    npixels = rep.width * rep.height;
102    nbytes_name = rep.nbytes;
103    /* reply data length */
104    nbytes = (long) rep.length << 2;
105    /* bytes of actual data in the reply */
106    nread = (npixels << 2) + nbytes_name;
107    /* size of data returned to application */
108    rlength = (sizeof (XFixesCursorImage) +
109	       npixels * sizeof (unsigned long) +
110	       nbytes_name + 1);
111
112    image = (XFixesCursorImage *) Xmalloc (rlength);
113    if (!image)
114    {
115	_XEatData (dpy, nbytes);
116	UnlockDisplay (dpy);
117	SyncHandle ();
118	return NULL;
119    }
120    image->x = rep.x;
121    image->y = rep.y;
122    image->width = rep.width;
123    image->height = rep.height;
124    image->xhot = rep.xhot;
125    image->yhot = rep.yhot;
126    image->cursor_serial = rep.cursorSerial;
127    image->pixels = (unsigned long *) (image + 1);
128    image->atom = rep.cursorName;
129    name = (char *) (image->pixels + npixels);
130    image->name = name;
131    _XRead32 (dpy, (long *) image->pixels, npixels << 2);
132    _XRead (dpy, name, nbytes_name);
133    name[nbytes_name] = '\0';	/* null-terminate */
134    /* skip any padding */
135    if(nbytes > nread)
136    {
137	_XEatData (dpy, (unsigned long) (nbytes - nread));
138    }
139    UnlockDisplay (dpy);
140    SyncHandle ();
141    return image;
142}
143
144void
145XFixesSetCursorName (Display *dpy, Cursor cursor, const char *name)
146{
147    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
148    xXFixesSetCursorNameReq	*req;
149    int				nbytes = strlen (name);
150
151    XFixesSimpleCheckExtension (dpy, info);
152    if (info->major_version < 2)
153	return;
154    LockDisplay (dpy);
155    GetReq (XFixesSetCursorName, req);
156    req->reqType = info->codes->major_opcode;
157    req->xfixesReqType = X_XFixesSetCursorName;
158    req->cursor = cursor;
159    req->nbytes = nbytes;
160    req->length += (nbytes + 3) >> 2;
161    Data (dpy, name, nbytes);
162    UnlockDisplay (dpy);
163    SyncHandle ();
164}
165
166const char *
167XFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom)
168{
169    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
170    xXFixesGetCursorNameReq	*req;
171    xXFixesGetCursorNameReply	rep;
172    char			*name;
173
174    XFixesCheckExtension (dpy, info, NULL);
175    if (info->major_version < 2)
176	return NULL;
177    LockDisplay (dpy);
178    GetReq (XFixesGetCursorName, req);
179    req->reqType = info->codes->major_opcode;
180    req->xfixesReqType = X_XFixesGetCursorName;
181    req->cursor = cursor;
182    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
183    {
184	UnlockDisplay (dpy);
185	SyncHandle ();
186	return NULL;
187    }
188    *atom = rep.atom;
189    if ((name = (char *) Xmalloc(rep.nbytes+1))) {
190	_XReadPad(dpy, name, (long)rep.nbytes);
191	name[rep.nbytes] = '\0';
192    } else {
193	_XEatData(dpy, (unsigned long) (rep.nbytes + 3) & ~3);
194	name = (char *) NULL;
195    }
196    UnlockDisplay(dpy);
197    SyncHandle();
198    return(name);
199}
200
201void
202XFixesChangeCursor (Display *dpy, Cursor source, Cursor destination)
203{
204    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
205    xXFixesChangeCursorReq	*req;
206
207    XFixesSimpleCheckExtension (dpy, info);
208    if (info->major_version < 2)
209	return;
210    LockDisplay (dpy);
211    GetReq (XFixesChangeCursor, req);
212    req->reqType = info->codes->major_opcode;
213    req->xfixesReqType = X_XFixesChangeCursor;
214    req->source = source;
215    req->destination = destination;
216    UnlockDisplay(dpy);
217    SyncHandle();
218}
219
220void
221XFixesChangeCursorByName (Display *dpy, Cursor source, const char *name)
222{
223    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
224    xXFixesChangeCursorByNameReq    *req;
225    int				    nbytes = strlen (name);
226
227    XFixesSimpleCheckExtension (dpy, info);
228    if (info->major_version < 2)
229	return;
230    LockDisplay (dpy);
231    GetReq (XFixesChangeCursorByName, req);
232    req->reqType = info->codes->major_opcode;
233    req->xfixesReqType = X_XFixesChangeCursorByName;
234    req->source = source;
235    req->nbytes = nbytes;
236    req->length += (nbytes + 3) >> 2;
237    Data (dpy, name, nbytes);
238    UnlockDisplay(dpy);
239    SyncHandle();
240}
241
242void
243XFixesHideCursor (Display *dpy, Window win)
244{
245    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
246    xXFixesHideCursorReq	*req;
247
248    XFixesSimpleCheckExtension (dpy, info);
249    if (info->major_version < 4)
250	return;
251    LockDisplay (dpy);
252    GetReq (XFixesHideCursor, req);
253    req->reqType = info->codes->major_opcode;
254    req->xfixesReqType = X_XFixesHideCursor;
255    req->window = win;
256    UnlockDisplay (dpy);
257    SyncHandle ();
258}
259
260void
261XFixesShowCursor (Display *dpy, Window win)
262{
263    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
264    xXFixesShowCursorReq	*req;
265
266    XFixesSimpleCheckExtension (dpy, info);
267    if (info->major_version < 4)
268	return;
269    LockDisplay (dpy);
270    GetReq (XFixesShowCursor, req);
271    req->reqType = info->codes->major_opcode;
272    req->xfixesReqType = X_XFixesShowCursor;
273    req->window = win;
274    UnlockDisplay (dpy);
275    SyncHandle ();
276}
277