Cursor.c revision ff63a143
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"
504456fccdSmrg
514456fccdSmrgvoid
524456fccdSmrgXFixesSelectCursorInput (Display	*dpy,
534456fccdSmrg			 Window		win,
544456fccdSmrg			 unsigned long	eventMask)
554456fccdSmrg{
564456fccdSmrg    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
574456fccdSmrg    xXFixesSelectCursorInputReq	    *req;
584456fccdSmrg
594456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
604456fccdSmrg
614456fccdSmrg    LockDisplay (dpy);
624456fccdSmrg    GetReq (XFixesSelectCursorInput, req);
634456fccdSmrg    req->reqType = info->codes->major_opcode;
644456fccdSmrg    req->xfixesReqType = X_XFixesSelectCursorInput;
654456fccdSmrg    req->window = win;
664456fccdSmrg    req->eventMask = eventMask;
674456fccdSmrg    UnlockDisplay (dpy);
684456fccdSmrg    SyncHandle ();
694456fccdSmrg}
704456fccdSmrg
714456fccdSmrgXFixesCursorImage *
724456fccdSmrgXFixesGetCursorImage (Display *dpy)
734456fccdSmrg{
744456fccdSmrg    XFixesExtDisplayInfo		*info = XFixesFindDisplay (dpy);
754456fccdSmrg    xXFixesGetCursorImageAndNameReq	*req;
764456fccdSmrg    xXFixesGetCursorImageAndNameReply	rep;
774456fccdSmrg    int					npixels;
784456fccdSmrg    int					nbytes_name;
794456fccdSmrg    int					nbytes, nread, rlength;
804456fccdSmrg    XFixesCursorImage			*image;
814456fccdSmrg    char				*name;
824456fccdSmrg
8342d69509Smrg    XFixesCheckExtension (dpy, info, NULL);
844456fccdSmrg    LockDisplay (dpy);
854456fccdSmrg    GetReq (XFixesGetCursorImageAndName, req);
864456fccdSmrg    req->reqType = info->codes->major_opcode;
874456fccdSmrg    if (info->major_version >= 2)
884456fccdSmrg	req->xfixesReqType = X_XFixesGetCursorImageAndName;
894456fccdSmrg    else
904456fccdSmrg	req->xfixesReqType = X_XFixesGetCursorImage;
914456fccdSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
924456fccdSmrg    {
934456fccdSmrg	UnlockDisplay (dpy);
944456fccdSmrg	SyncHandle ();
9542d69509Smrg	return NULL;
964456fccdSmrg    }
974456fccdSmrg    if (info->major_version < 2)
984456fccdSmrg    {
994456fccdSmrg	rep.cursorName = None;
1004456fccdSmrg	rep.nbytes = 0;
1014456fccdSmrg    }
1024456fccdSmrg    npixels = rep.width * rep.height;
1034456fccdSmrg    nbytes_name = rep.nbytes;
1044456fccdSmrg    /* reply data length */
1054456fccdSmrg    nbytes = (long) rep.length << 2;
1064456fccdSmrg    /* bytes of actual data in the reply */
1074456fccdSmrg    nread = (npixels << 2) + nbytes_name;
1084456fccdSmrg    /* size of data returned to application */
1094456fccdSmrg    rlength = (sizeof (XFixesCursorImage) +
1104456fccdSmrg	       npixels * sizeof (unsigned long) +
1114456fccdSmrg	       nbytes_name + 1);
1124456fccdSmrg
1134456fccdSmrg    image = (XFixesCursorImage *) Xmalloc (rlength);
1144456fccdSmrg    if (!image)
1154456fccdSmrg    {
1164456fccdSmrg	_XEatData (dpy, nbytes);
1174456fccdSmrg	UnlockDisplay (dpy);
1184456fccdSmrg	SyncHandle ();
11942d69509Smrg	return NULL;
1204456fccdSmrg    }
1214456fccdSmrg    image->x = rep.x;
1224456fccdSmrg    image->y = rep.y;
1234456fccdSmrg    image->width = rep.width;
1244456fccdSmrg    image->height = rep.height;
1254456fccdSmrg    image->xhot = rep.xhot;
1264456fccdSmrg    image->yhot = rep.yhot;
1274456fccdSmrg    image->cursor_serial = rep.cursorSerial;
1284456fccdSmrg    image->pixels = (unsigned long *) (image + 1);
1294456fccdSmrg    image->atom = rep.cursorName;
1304456fccdSmrg    name = (char *) (image->pixels + npixels);
1314456fccdSmrg    image->name = name;
1324456fccdSmrg    _XRead32 (dpy, (long *) image->pixels, npixels << 2);
1334456fccdSmrg    _XRead (dpy, name, nbytes_name);
1344456fccdSmrg    name[nbytes_name] = '\0';	/* null-terminate */
1354456fccdSmrg    /* skip any padding */
1364456fccdSmrg    if(nbytes > nread)
1374456fccdSmrg    {
1384456fccdSmrg	_XEatData (dpy, (unsigned long) (nbytes - nread));
1394456fccdSmrg    }
1404456fccdSmrg    UnlockDisplay (dpy);
1414456fccdSmrg    SyncHandle ();
1424456fccdSmrg    return image;
1434456fccdSmrg}
1444456fccdSmrg
1454456fccdSmrgvoid
1464456fccdSmrgXFixesSetCursorName (Display *dpy, Cursor cursor, const char *name)
1474456fccdSmrg{
1484456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
1494456fccdSmrg    xXFixesSetCursorNameReq	*req;
1504456fccdSmrg    int				nbytes = strlen (name);
1514456fccdSmrg
1524456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
1534456fccdSmrg    if (info->major_version < 2)
1544456fccdSmrg	return;
1554456fccdSmrg    LockDisplay (dpy);
1564456fccdSmrg    GetReq (XFixesSetCursorName, req);
1574456fccdSmrg    req->reqType = info->codes->major_opcode;
1584456fccdSmrg    req->xfixesReqType = X_XFixesSetCursorName;
1594456fccdSmrg    req->cursor = cursor;
1604456fccdSmrg    req->nbytes = nbytes;
1614456fccdSmrg    req->length += (nbytes + 3) >> 2;
1624456fccdSmrg    Data (dpy, name, nbytes);
1634456fccdSmrg    UnlockDisplay (dpy);
1644456fccdSmrg    SyncHandle ();
1654456fccdSmrg}
1664456fccdSmrg
1674456fccdSmrgconst char *
1684456fccdSmrgXFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom)
1694456fccdSmrg{
1704456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
1714456fccdSmrg    xXFixesGetCursorNameReq	*req;
1724456fccdSmrg    xXFixesGetCursorNameReply	rep;
1734456fccdSmrg    char			*name;
1744456fccdSmrg
17542d69509Smrg    XFixesCheckExtension (dpy, info, NULL);
1764456fccdSmrg    if (info->major_version < 2)
17742d69509Smrg	return NULL;
1784456fccdSmrg    LockDisplay (dpy);
1794456fccdSmrg    GetReq (XFixesGetCursorName, req);
1804456fccdSmrg    req->reqType = info->codes->major_opcode;
1814456fccdSmrg    req->xfixesReqType = X_XFixesGetCursorName;
1824456fccdSmrg    req->cursor = cursor;
1834456fccdSmrg    if (!_XReply (dpy, (xReply *) &rep, 0, xFalse))
1844456fccdSmrg    {
1854456fccdSmrg	UnlockDisplay (dpy);
1864456fccdSmrg	SyncHandle ();
18742d69509Smrg	return NULL;
1884456fccdSmrg    }
1894456fccdSmrg    *atom = rep.atom;
1904456fccdSmrg    if ((name = (char *) Xmalloc(rep.nbytes+1))) {
1914456fccdSmrg	_XReadPad(dpy, name, (long)rep.nbytes);
1924456fccdSmrg	name[rep.nbytes] = '\0';
1934456fccdSmrg    } else {
1944456fccdSmrg	_XEatData(dpy, (unsigned long) (rep.nbytes + 3) & ~3);
1954456fccdSmrg	name = (char *) NULL;
1964456fccdSmrg    }
1974456fccdSmrg    UnlockDisplay(dpy);
1984456fccdSmrg    SyncHandle();
1994456fccdSmrg    return(name);
2004456fccdSmrg}
2014456fccdSmrg
2024456fccdSmrgvoid
2034456fccdSmrgXFixesChangeCursor (Display *dpy, Cursor source, Cursor destination)
2044456fccdSmrg{
2054456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
2064456fccdSmrg    xXFixesChangeCursorReq	*req;
2074456fccdSmrg
2084456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2094456fccdSmrg    if (info->major_version < 2)
2104456fccdSmrg	return;
2114456fccdSmrg    LockDisplay (dpy);
2124456fccdSmrg    GetReq (XFixesChangeCursor, req);
2134456fccdSmrg    req->reqType = info->codes->major_opcode;
2144456fccdSmrg    req->xfixesReqType = X_XFixesChangeCursor;
2154456fccdSmrg    req->source = source;
2164456fccdSmrg    req->destination = destination;
2174456fccdSmrg    UnlockDisplay(dpy);
2184456fccdSmrg    SyncHandle();
2194456fccdSmrg}
2204456fccdSmrg
2214456fccdSmrgvoid
2224456fccdSmrgXFixesChangeCursorByName (Display *dpy, Cursor source, const char *name)
2234456fccdSmrg{
2244456fccdSmrg    XFixesExtDisplayInfo	    *info = XFixesFindDisplay (dpy);
2254456fccdSmrg    xXFixesChangeCursorByNameReq    *req;
2264456fccdSmrg    int				    nbytes = strlen (name);
2274456fccdSmrg
2284456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2294456fccdSmrg    if (info->major_version < 2)
2304456fccdSmrg	return;
2314456fccdSmrg    LockDisplay (dpy);
2324456fccdSmrg    GetReq (XFixesChangeCursorByName, req);
2334456fccdSmrg    req->reqType = info->codes->major_opcode;
2344456fccdSmrg    req->xfixesReqType = X_XFixesChangeCursorByName;
2354456fccdSmrg    req->source = source;
2364456fccdSmrg    req->nbytes = nbytes;
2374456fccdSmrg    req->length += (nbytes + 3) >> 2;
2384456fccdSmrg    Data (dpy, name, nbytes);
2394456fccdSmrg    UnlockDisplay(dpy);
2404456fccdSmrg    SyncHandle();
2414456fccdSmrg}
2424456fccdSmrg
2434456fccdSmrgvoid
2444456fccdSmrgXFixesHideCursor (Display *dpy, Window win)
2454456fccdSmrg{
2464456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
2474456fccdSmrg    xXFixesHideCursorReq	*req;
2484456fccdSmrg
2494456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2504456fccdSmrg    if (info->major_version < 4)
2514456fccdSmrg	return;
2524456fccdSmrg    LockDisplay (dpy);
2534456fccdSmrg    GetReq (XFixesHideCursor, req);
2544456fccdSmrg    req->reqType = info->codes->major_opcode;
2554456fccdSmrg    req->xfixesReqType = X_XFixesHideCursor;
2564456fccdSmrg    req->window = win;
2574456fccdSmrg    UnlockDisplay (dpy);
2584456fccdSmrg    SyncHandle ();
2594456fccdSmrg}
2604456fccdSmrg
2614456fccdSmrgvoid
2624456fccdSmrgXFixesShowCursor (Display *dpy, Window win)
2634456fccdSmrg{
2644456fccdSmrg    XFixesExtDisplayInfo	*info = XFixesFindDisplay (dpy);
2654456fccdSmrg    xXFixesShowCursorReq	*req;
2664456fccdSmrg
2674456fccdSmrg    XFixesSimpleCheckExtension (dpy, info);
2684456fccdSmrg    if (info->major_version < 4)
2694456fccdSmrg	return;
2704456fccdSmrg    LockDisplay (dpy);
2714456fccdSmrg    GetReq (XFixesShowCursor, req);
2724456fccdSmrg    req->reqType = info->codes->major_opcode;
2734456fccdSmrg    req->xfixesReqType = X_XFixesShowCursor;
2744456fccdSmrg    req->window = win;
2754456fccdSmrg    UnlockDisplay (dpy);
2764456fccdSmrg    SyncHandle ();
2774456fccdSmrg}
278ff63a143Smrg
279ff63a143SmrgPointerBarrier
280ff63a143SmrgXFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1,
281ff63a143Smrg			   int x2, int y2, int directions,
282ff63a143Smrg			   int num_devices, int *devices)
283ff63a143Smrg{
284ff63a143Smrg    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
285ff63a143Smrg    xXFixesCreatePointerBarrierReq *req;
286ff63a143Smrg    PointerBarrier barrier;
287ff63a143Smrg    int extra = 0;
288ff63a143Smrg
289ff63a143Smrg    XFixesCheckExtension (dpy, info, 0);
290ff63a143Smrg    if (info->major_version < 5)
291ff63a143Smrg	return 0;
292ff63a143Smrg
293ff63a143Smrg    if (num_devices)
294ff63a143Smrg	extra = (((2 * num_devices) + 3) / 4) * 4;
295ff63a143Smrg
296ff63a143Smrg    LockDisplay (dpy);
297ff63a143Smrg    GetReqExtra (XFixesCreatePointerBarrier, extra, req);
298ff63a143Smrg    req->reqType = info->codes->major_opcode;
299ff63a143Smrg    req->xfixesReqType = X_XFixesCreatePointerBarrier;
300ff63a143Smrg    barrier = req->barrier = XAllocID (dpy);
301ff63a143Smrg    req->window = w;
302ff63a143Smrg    req->x1 = x1;
303ff63a143Smrg    req->y1 = y1;
304ff63a143Smrg    req->x2 = x2;
305ff63a143Smrg    req->y2 = y2;
306ff63a143Smrg    req->directions = directions;
307ff63a143Smrg    if ((req->num_devices = num_devices)) {
308ff63a143Smrg	int i;
309ff63a143Smrg	CARD16 *devs = (CARD16 *)(req + 1);
310ff63a143Smrg	for (i = 0; i < num_devices; i++)
311ff63a143Smrg	    devs[i] = (CARD16)(devices[i]);
312ff63a143Smrg    }
313ff63a143Smrg
314ff63a143Smrg    UnlockDisplay (dpy);
315ff63a143Smrg    SyncHandle();
316ff63a143Smrg    return barrier;
317ff63a143Smrg}
318ff63a143Smrg
319ff63a143Smrgvoid
320ff63a143SmrgXFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b)
321ff63a143Smrg{
322ff63a143Smrg    XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy);
323ff63a143Smrg    xXFixesDestroyPointerBarrierReq *req;
324ff63a143Smrg
325ff63a143Smrg    XFixesSimpleCheckExtension (dpy, info);
326ff63a143Smrg    if (info->major_version < 5)
327ff63a143Smrg	return;
328ff63a143Smrg
329ff63a143Smrg    LockDisplay (dpy);
330ff63a143Smrg    GetReq (XFixesDestroyPointerBarrier, req);
331ff63a143Smrg    req->reqType = info->codes->major_opcode;
332ff63a143Smrg    req->xfixesReqType = X_XFixesDestroyPointerBarrier;
333ff63a143Smrg    req->barrier = b;
334ff63a143Smrg    UnlockDisplay (dpy);
335ff63a143Smrg    SyncHandle();
336ff63a143Smrg}
337