Cursor.c revision 3e6c936a
14456fccdSmrg/*
2521070a0Smrg * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3ff63a143Smrg * Copyright 2011 Red Hat, Inc.
44456fccdSmrg *
5521070a0Smrg * Permission is hereby granted, free of charge, to any person obtaining a
6521070a0Smrg * copy of this software and associated documentation files (the "Software"),
7521070a0Smrg * to deal in the Software without restriction, including without limitation
8521070a0Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9521070a0Smrg * and/or sell copies of the Software, and to permit persons to whom the
10521070a0Smrg * Software is furnished to do so, subject to the following conditions:
114456fccdSmrg *
12521070a0Smrg * The above copyright notice and this permission notice (including the next
13521070a0Smrg * paragraph) shall be included in all copies or substantial portions of the
14521070a0Smrg * Software.
154456fccdSmrg *
16521070a0Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17521070a0Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18521070a0Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19521070a0Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20521070a0Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21521070a0Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22521070a0Smrg * DEALINGS IN THE SOFTWARE.
23521070a0Smrg */
24521070a0Smrg/*
254456fccdSmrg * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
264456fccdSmrg *
274456fccdSmrg * Permission to use, copy, modify, distribute, and sell this software and its
284456fccdSmrg * documentation for any purpose is hereby granted without fee, provided that
294456fccdSmrg * the above copyright notice appear in all copies and that both that
304456fccdSmrg * copyright notice and this permission notice appear in supporting
314456fccdSmrg * documentation, and that the name of Keith Packard not be used in
324456fccdSmrg * advertising or publicity pertaining to distribution of the software without
334456fccdSmrg * specific, written prior permission.  Keith Packard makes no
344456fccdSmrg * representations about the suitability of this software for any purpose.  It
354456fccdSmrg * is provided "as is" without express or implied warranty.
364456fccdSmrg *
374456fccdSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
384456fccdSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
394456fccdSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
404456fccdSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
414456fccdSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
424456fccdSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
434456fccdSmrg * PERFORMANCE OF THIS SOFTWARE.
444456fccdSmrg */
454456fccdSmrg
464456fccdSmrg#ifdef HAVE_CONFIG_H
474456fccdSmrg#include <config.h>
484456fccdSmrg#endif
494456fccdSmrg#include "Xfixesint.h"
503e6c936aSmrg#include <limits.h>
514456fccdSmrg
524456fccdSmrgvoid
534456fccdSmrgXFixesSelectCursorInput (Display	*dpy,
544456fccdSmrg			 Window		win,
554456fccdSmrg			 unsigned long	eventMask)
564456fccdSmrg{
574456fccdSmrg    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
584456fccdSmrg    xXFixesSelectCursorInputReq	    *req;
594456fccdSmrg
604456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
614456fccdSmrg
624456fccdSmrg    LockDisplay (dpy);
634456fccdSmrg    GetReq (XFixesSelectCursorInput, req);
644456fccdSmrg    req->reqType = info->codes->major_opcode;
654456fccdSmrg    req->xfixesReqType = X_XFixesSelectCursorInput;
664456fccdSmrg    req->window = win;
674456fccdSmrg    req->eventMask = eventMask;
684456fccdSmrg    UnlockDisplay (dpy);
694456fccdSmrg    SyncHandle ();
704456fccdSmrg}
714456fccdSmrg
724456fccdSmrgXFixesCursorImage *
734456fccdSmrgXFixesGetCursorImage (Display *dpy)
744456fccdSmrg{
754456fccdSmrg    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
764456fccdSmrg    xXFixesGetCursorImageAndNameReq	*req;
774456fccdSmrg    xXFixesGetCursorImageAndNameReply	rep;
783e6c936aSmrg    size_t				npixels;
793e6c936aSmrg    size_t				nbytes_name;
803e6c936aSmrg    size_t				nbytes, nread, rlength;
814456fccdSmrg    XFixesCursorImage			*image;
824456fccdSmrg    char				*name;
834456fccdSmrg
8442d69509Smrg    XFixesCheckExtension (dpy, info, NULL);
854456fccdSmrg    LockDisplay (dpy);
864456fccdSmrg    GetReq (XFixesGetCursorImageAndName, req);
874456fccdSmrg    req->reqType = info->codes->major_opcode;
884456fccdSmrg    if (info->major_version >= 2)
894456fccdSmrg	req->xfixesReqType = X_XFixesGetCursorImageAndName;
904456fccdSmrg    else
914456fccdSmrg	req->xfixesReqType = X_XFixesGetCursorImage;
924456fccdSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
934456fccdSmrg    {
944456fccdSmrg	UnlockDisplay (dpy);
954456fccdSmrg	SyncHandle ();
9642d69509Smrg	return NULL;
974456fccdSmrg    }
984456fccdSmrg    if (info->major_version < 2)
994456fccdSmrg    {
1004456fccdSmrg	rep.cursorName = None;
1014456fccdSmrg	rep.nbytes = 0;
1024456fccdSmrg    }
1034456fccdSmrg    npixels = rep.width * rep.height;
1044456fccdSmrg    nbytes_name = rep.nbytes;
1053e6c936aSmrg    if ((rep.length < (INT_MAX >> 2)) &&
1063e6c936aSmrg	npixels < (((INT_MAX >> 3) - sizeof (XFixesCursorImage) - 1)
1073e6c936aSmrg		   - nbytes_name)) {
1083e6c936aSmrg	/* reply data length */
1093e6c936aSmrg	nbytes = (size_t) rep.length << 2;
1103e6c936aSmrg	/* bytes of actual data in the reply */
1113e6c936aSmrg	nread = (npixels << 2) + nbytes_name;
1123e6c936aSmrg	/* size of data returned to application */
1133e6c936aSmrg	rlength = (sizeof (XFixesCursorImage) +
1143e6c936aSmrg		   npixels * sizeof (unsigned long) +
1153e6c936aSmrg		   nbytes_name + 1);
1164456fccdSmrg
1173e6c936aSmrg	image = Xmalloc (rlength);
1183e6c936aSmrg    } else
1193e6c936aSmrg	image = NULL;
1204456fccdSmrg    if (!image)
1214456fccdSmrg    {
1223e6c936aSmrg	_XEatDataWords(dpy, rep.length);
1234456fccdSmrg	UnlockDisplay (dpy);
1244456fccdSmrg	SyncHandle ();
12542d69509Smrg	return NULL;
1264456fccdSmrg    }
1274456fccdSmrg    image->x = rep.x;
1284456fccdSmrg    image->y = rep.y;
1294456fccdSmrg    image->width = rep.width;
1304456fccdSmrg    image->height = rep.height;
1314456fccdSmrg    image->xhot = rep.xhot;
1324456fccdSmrg    image->yhot = rep.yhot;
1334456fccdSmrg    image->cursor_serial = rep.cursorSerial;
1344456fccdSmrg    image->pixels = (unsigned long *) (image + 1);
1354456fccdSmrg    image->atom = rep.cursorName;
1364456fccdSmrg    name = (char *) (image->pixels + npixels);
1374456fccdSmrg    image->name = name;
1384456fccdSmrg    _XRead32 (dpy, (long *) image->pixels, npixels << 2);
1394456fccdSmrg    _XRead (dpy, name, nbytes_name);
1404456fccdSmrg    name[nbytes_name] = '\0';	/* null-terminate */
1414456fccdSmrg    /* skip any padding */
1424456fccdSmrg    if(nbytes > nread)
1434456fccdSmrg    {
1444456fccdSmrg	_XEatData (dpy, (unsigned long) (nbytes - nread));
1454456fccdSmrg    }
1464456fccdSmrg    UnlockDisplay (dpy);
1474456fccdSmrg    SyncHandle ();
1484456fccdSmrg    return image;
1494456fccdSmrg}
1504456fccdSmrg
1514456fccdSmrgvoid
1524456fccdSmrgXFixesSetCursorName (Display *dpy, Cursor cursor, const char *name)
1534456fccdSmrg{
1544456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
1554456fccdSmrg    xXFixesSetCursorNameReq	*req;
1564456fccdSmrg    int				nbytes = strlen (name);
1574456fccdSmrg
1584456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
1594456fccdSmrg    if (info->major_version < 2)
1604456fccdSmrg	return;
1614456fccdSmrg    LockDisplay (dpy);
1624456fccdSmrg    GetReq (XFixesSetCursorName, req);
1634456fccdSmrg    req->reqType = info->codes->major_opcode;
1644456fccdSmrg    req->xfixesReqType = X_XFixesSetCursorName;
1654456fccdSmrg    req->cursor = cursor;
1664456fccdSmrg    req->nbytes = nbytes;
1674456fccdSmrg    req->length += (nbytes + 3) >> 2;
1684456fccdSmrg    Data (dpy, name, nbytes);
1694456fccdSmrg    UnlockDisplay (dpy);
1704456fccdSmrg    SyncHandle ();
1714456fccdSmrg}
1724456fccdSmrg
1734456fccdSmrgconst char *
1744456fccdSmrgXFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom)
1754456fccdSmrg{
1764456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
1774456fccdSmrg    xXFixesGetCursorNameReq	*req;
1784456fccdSmrg    xXFixesGetCursorNameReply	rep;
1794456fccdSmrg    char			*name;
1804456fccdSmrg
18142d69509Smrg    XFixesCheckExtension (dpy, info, NULL);
1824456fccdSmrg    if (info->major_version < 2)
18342d69509Smrg	return NULL;
1844456fccdSmrg    LockDisplay (dpy);
1854456fccdSmrg    GetReq (XFixesGetCursorName, req);
1864456fccdSmrg    req->reqType = info->codes->major_opcode;
1874456fccdSmrg    req->xfixesReqType = X_XFixesGetCursorName;
1884456fccdSmrg    req->cursor = cursor;
1894456fccdSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
1904456fccdSmrg    {
1914456fccdSmrg	UnlockDisplay (dpy);
1924456fccdSmrg	SyncHandle ();
19342d69509Smrg	return NULL;
1944456fccdSmrg    }
1954456fccdSmrg    *atom = rep.atom;
1964456fccdSmrg    if ((name = (char *) Xmalloc(rep.nbytes+1))) {
1974456fccdSmrg	_XReadPad(dpy, name, (long)rep.nbytes);
1984456fccdSmrg	name[rep.nbytes] = '\0';
1994456fccdSmrg    } else {
2003e6c936aSmrg	_XEatDataWords(dpy, rep.length);
2014456fccdSmrg	name = (char *) NULL;
2024456fccdSmrg    }
2034456fccdSmrg    UnlockDisplay(dpy);
2044456fccdSmrg    SyncHandle();
2054456fccdSmrg    return(name);
2064456fccdSmrg}
2074456fccdSmrg
2084456fccdSmrgvoid
2094456fccdSmrgXFixesChangeCursor (Display *dpy, Cursor source, Cursor destination)
2104456fccdSmrg{
2114456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
2124456fccdSmrg    xXFixesChangeCursorReq	*req;
2134456fccdSmrg
2144456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2154456fccdSmrg    if (info->major_version < 2)
2164456fccdSmrg	return;
2174456fccdSmrg    LockDisplay (dpy);
2184456fccdSmrg    GetReq (XFixesChangeCursor, req);
2194456fccdSmrg    req->reqType = info->codes->major_opcode;
2204456fccdSmrg    req->xfixesReqType = X_XFixesChangeCursor;
2214456fccdSmrg    req->source = source;
2224456fccdSmrg    req->destination = destination;
2234456fccdSmrg    UnlockDisplay(dpy);
2244456fccdSmrg    SyncHandle();
2254456fccdSmrg}
2264456fccdSmrg
2274456fccdSmrgvoid
2284456fccdSmrgXFixesChangeCursorByName (Display *dpy, Cursor source, const char *name)
2294456fccdSmrg{
2304456fccdSmrg    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
2314456fccdSmrg    xXFixesChangeCursorByNameReq    *req;
2324456fccdSmrg    int				    nbytes = strlen (name);
2334456fccdSmrg
2344456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2354456fccdSmrg    if (info->major_version < 2)
2364456fccdSmrg	return;
2374456fccdSmrg    LockDisplay (dpy);
2384456fccdSmrg    GetReq (XFixesChangeCursorByName, req);
2394456fccdSmrg    req->reqType = info->codes->major_opcode;
2404456fccdSmrg    req->xfixesReqType = X_XFixesChangeCursorByName;
2414456fccdSmrg    req->source = source;
2424456fccdSmrg    req->nbytes = nbytes;
2434456fccdSmrg    req->length += (nbytes + 3) >> 2;
2444456fccdSmrg    Data (dpy, name, nbytes);
2454456fccdSmrg    UnlockDisplay(dpy);
2464456fccdSmrg    SyncHandle();
2474456fccdSmrg}
2484456fccdSmrg
2494456fccdSmrgvoid
2504456fccdSmrgXFixesHideCursor (Display *dpy, Window win)
2514456fccdSmrg{
2524456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
2534456fccdSmrg    xXFixesHideCursorReq	*req;
2544456fccdSmrg
2554456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2564456fccdSmrg    if (info->major_version < 4)
2574456fccdSmrg	return;
2584456fccdSmrg    LockDisplay (dpy);
2594456fccdSmrg    GetReq (XFixesHideCursor, req);
2604456fccdSmrg    req->reqType = info->codes->major_opcode;
2614456fccdSmrg    req->xfixesReqType = X_XFixesHideCursor;
2624456fccdSmrg    req->window = win;
2634456fccdSmrg    UnlockDisplay (dpy);
2644456fccdSmrg    SyncHandle ();
2654456fccdSmrg}
2664456fccdSmrg
2674456fccdSmrgvoid
2684456fccdSmrgXFixesShowCursor (Display *dpy, Window win)
2694456fccdSmrg{
2704456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
2714456fccdSmrg    xXFixesShowCursorReq	*req;
2724456fccdSmrg
2734456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2744456fccdSmrg    if (info->major_version < 4)
2754456fccdSmrg	return;
2764456fccdSmrg    LockDisplay (dpy);
2774456fccdSmrg    GetReq (XFixesShowCursor, req);
2784456fccdSmrg    req->reqType = info->codes->major_opcode;
2794456fccdSmrg    req->xfixesReqType = X_XFixesShowCursor;
2804456fccdSmrg    req->window = win;
2814456fccdSmrg    UnlockDisplay (dpy);
2824456fccdSmrg    SyncHandle ();
2834456fccdSmrg}
284ff63a143Smrg
285ff63a143SmrgPointerBarrier
286ff63a143SmrgXFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1,
287ff63a143Smrg			   int x2, int y2, int directions,
288ff63a143Smrg			   int num_devices, int *devices)
289ff63a143Smrg{
290ff63a143Smrg    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
291ff63a143Smrg    xXFixesCreatePointerBarrierReq *req;
292ff63a143Smrg    PointerBarrier barrier;
293ff63a143Smrg    int extra = 0;
294ff63a143Smrg
295ff63a143Smrg    XFixesCheckExtension (dpy, info, 0);
296ff63a143Smrg    if (info->major_version < 5)
297ff63a143Smrg	return 0;
298ff63a143Smrg
299ff63a143Smrg    if (num_devices)
300ff63a143Smrg	extra = (((2 * num_devices) + 3) / 4) * 4;
301ff63a143Smrg
302ff63a143Smrg    LockDisplay (dpy);
303ff63a143Smrg    GetReqExtra (XFixesCreatePointerBarrier, extra, req);
304ff63a143Smrg    req->reqType = info->codes->major_opcode;
305ff63a143Smrg    req->xfixesReqType = X_XFixesCreatePointerBarrier;
306ff63a143Smrg    barrier = req->barrier = XAllocID (dpy);
307ff63a143Smrg    req->window = w;
308ff63a143Smrg    req->x1 = x1;
309ff63a143Smrg    req->y1 = y1;
310ff63a143Smrg    req->x2 = x2;
311ff63a143Smrg    req->y2 = y2;
312ff63a143Smrg    req->directions = directions;
313ff63a143Smrg    if ((req->num_devices = num_devices)) {
314ff63a143Smrg	int i;
315ff63a143Smrg	CARD16 *devs = (CARD16 *)(req + 1);
316ff63a143Smrg	for (i = 0; i < num_devices; i++)
317ff63a143Smrg	    devs[i] = (CARD16)(devices[i]);
318ff63a143Smrg    }
319ff63a143Smrg
320ff63a143Smrg    UnlockDisplay (dpy);
321ff63a143Smrg    SyncHandle();
322ff63a143Smrg    return barrier;
323ff63a143Smrg}
324ff63a143Smrg
325ff63a143Smrgvoid
326ff63a143SmrgXFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b)
327ff63a143Smrg{
328ff63a143Smrg    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
329ff63a143Smrg    xXFixesDestroyPointerBarrierReq *req;
330ff63a143Smrg
331ff63a143Smrg    XFixesSimpleCheckExtension (dpy, info);
332ff63a143Smrg    if (info->major_version < 5)
333ff63a143Smrg	return;
334ff63a143Smrg
335ff63a143Smrg    LockDisplay (dpy);
336ff63a143Smrg    GetReq (XFixesDestroyPointerBarrier, req);
337ff63a143Smrg    req->reqType = info->codes->major_opcode;
338ff63a143Smrg    req->xfixesReqType = X_XFixesDestroyPointerBarrier;
339ff63a143Smrg    req->barrier = b;
340ff63a143Smrg    UnlockDisplay (dpy);
341ff63a143Smrg    SyncHandle();
342ff63a143Smrg}
343