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