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