14456fccdSmrg/* 2a7e741d5Smrg * Copyright (c) 2006, Oracle and/or its affiliates. 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); 64a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 654456fccdSmrg req->xfixesReqType = X_XFixesSelectCursorInput; 66a7e741d5Smrg req->window = (CARD32) win; 67a7e741d5Smrg req->eventMask = (CARD32) 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; 80a7e741d5Smrg size_t nbytes = 0, nread = 0; 814456fccdSmrg XFixesCursorImage *image; 824456fccdSmrg char *name; 834456fccdSmrg 8442d69509Smrg XFixesCheckExtension (dpy, info, NULL); 854456fccdSmrg LockDisplay (dpy); 864456fccdSmrg GetReq (XFixesGetCursorImageAndName, req); 87a7e741d5Smrg req->reqType = (CARD8) 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)) { 108a7e741d5Smrg size_t rlength; 109a7e741d5Smrg 1103e6c936aSmrg /* reply data length */ 1113e6c936aSmrg nbytes = (size_t) rep.length << 2; 1123e6c936aSmrg /* bytes of actual data in the reply */ 1133e6c936aSmrg nread = (npixels << 2) + nbytes_name; 1143e6c936aSmrg /* size of data returned to application */ 1153e6c936aSmrg rlength = (sizeof (XFixesCursorImage) + 1163e6c936aSmrg npixels * sizeof (unsigned long) + 1173e6c936aSmrg nbytes_name + 1); 1184456fccdSmrg 1193e6c936aSmrg image = Xmalloc (rlength); 1203e6c936aSmrg } else 1213e6c936aSmrg image = NULL; 1224456fccdSmrg if (!image) 1234456fccdSmrg { 1243e6c936aSmrg _XEatDataWords(dpy, rep.length); 1254456fccdSmrg UnlockDisplay (dpy); 1264456fccdSmrg SyncHandle (); 12742d69509Smrg return NULL; 1284456fccdSmrg } 1294456fccdSmrg image->x = rep.x; 1304456fccdSmrg image->y = rep.y; 1314456fccdSmrg image->width = rep.width; 1324456fccdSmrg image->height = rep.height; 1334456fccdSmrg image->xhot = rep.xhot; 1344456fccdSmrg image->yhot = rep.yhot; 1354456fccdSmrg image->cursor_serial = rep.cursorSerial; 1364456fccdSmrg image->pixels = (unsigned long *) (image + 1); 1374456fccdSmrg image->atom = rep.cursorName; 1384456fccdSmrg name = (char *) (image->pixels + npixels); 1394456fccdSmrg image->name = name; 1404456fccdSmrg _XRead32 (dpy, (long *) image->pixels, npixels << 2); 1414456fccdSmrg _XRead (dpy, name, nbytes_name); 1424456fccdSmrg name[nbytes_name] = '\0'; /* null-terminate */ 1434456fccdSmrg /* skip any padding */ 1444456fccdSmrg if(nbytes > nread) 1454456fccdSmrg { 1464456fccdSmrg _XEatData (dpy, (unsigned long) (nbytes - nread)); 1474456fccdSmrg } 1484456fccdSmrg UnlockDisplay (dpy); 1494456fccdSmrg SyncHandle (); 1504456fccdSmrg return image; 1514456fccdSmrg} 1524456fccdSmrg 1534456fccdSmrgvoid 1544456fccdSmrgXFixesSetCursorName (Display *dpy, Cursor cursor, const char *name) 1554456fccdSmrg{ 1564456fccdSmrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 1574456fccdSmrg xXFixesSetCursorNameReq *req; 158a7e741d5Smrg CARD16 nbytes = (CARD16) strlen (name); 1594456fccdSmrg 1604456fccdSmrg XFixesSimpleCheckExtension (dpy, info); 1614456fccdSmrg if (info->major_version < 2) 1624456fccdSmrg return; 1634456fccdSmrg LockDisplay (dpy); 1644456fccdSmrg GetReq (XFixesSetCursorName, req); 165a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 1664456fccdSmrg req->xfixesReqType = X_XFixesSetCursorName; 167a7e741d5Smrg req->cursor = (CARD32) cursor; 1684456fccdSmrg req->nbytes = nbytes; 1694456fccdSmrg req->length += (nbytes + 3) >> 2; 1704456fccdSmrg Data (dpy, name, nbytes); 1714456fccdSmrg UnlockDisplay (dpy); 1724456fccdSmrg SyncHandle (); 1734456fccdSmrg} 1744456fccdSmrg 1754456fccdSmrgconst char * 1764456fccdSmrgXFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom) 1774456fccdSmrg{ 1784456fccdSmrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 1794456fccdSmrg xXFixesGetCursorNameReq *req; 1804456fccdSmrg xXFixesGetCursorNameReply rep; 1814456fccdSmrg char *name; 1824456fccdSmrg 18342d69509Smrg XFixesCheckExtension (dpy, info, NULL); 1844456fccdSmrg if (info->major_version < 2) 18542d69509Smrg return NULL; 1864456fccdSmrg LockDisplay (dpy); 1874456fccdSmrg GetReq (XFixesGetCursorName, req); 188a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 1894456fccdSmrg req->xfixesReqType = X_XFixesGetCursorName; 190a7e741d5Smrg req->cursor = (CARD32) cursor; 1914456fccdSmrg if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 1924456fccdSmrg { 1934456fccdSmrg UnlockDisplay (dpy); 1944456fccdSmrg SyncHandle (); 19542d69509Smrg return NULL; 1964456fccdSmrg } 1974456fccdSmrg *atom = rep.atom; 198a7e741d5Smrg if ((name = Xmalloc(rep.nbytes+1)) != NULL) { 1994456fccdSmrg _XReadPad(dpy, name, (long)rep.nbytes); 2004456fccdSmrg name[rep.nbytes] = '\0'; 2014456fccdSmrg } else { 2023e6c936aSmrg _XEatDataWords(dpy, rep.length); 2034456fccdSmrg name = (char *) NULL; 2044456fccdSmrg } 2054456fccdSmrg UnlockDisplay(dpy); 2064456fccdSmrg SyncHandle(); 2074456fccdSmrg return(name); 2084456fccdSmrg} 2094456fccdSmrg 2104456fccdSmrgvoid 2114456fccdSmrgXFixesChangeCursor (Display *dpy, Cursor source, Cursor destination) 2124456fccdSmrg{ 2134456fccdSmrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 2144456fccdSmrg xXFixesChangeCursorReq *req; 2154456fccdSmrg 2164456fccdSmrg XFixesSimpleCheckExtension (dpy, info); 2174456fccdSmrg if (info->major_version < 2) 2184456fccdSmrg return; 2194456fccdSmrg LockDisplay (dpy); 2204456fccdSmrg GetReq (XFixesChangeCursor, req); 221a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 2224456fccdSmrg req->xfixesReqType = X_XFixesChangeCursor; 223a7e741d5Smrg req->source = (CARD32) source; 224a7e741d5Smrg req->destination = (CARD32) destination; 2254456fccdSmrg UnlockDisplay(dpy); 2264456fccdSmrg SyncHandle(); 2274456fccdSmrg} 2284456fccdSmrg 2294456fccdSmrgvoid 2304456fccdSmrgXFixesChangeCursorByName (Display *dpy, Cursor source, const char *name) 2314456fccdSmrg{ 2324456fccdSmrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 2334456fccdSmrg xXFixesChangeCursorByNameReq *req; 234a7e741d5Smrg CARD16 nbytes = (CARD16) strlen (name); 2354456fccdSmrg 2364456fccdSmrg XFixesSimpleCheckExtension (dpy, info); 2374456fccdSmrg if (info->major_version < 2) 2384456fccdSmrg return; 2394456fccdSmrg LockDisplay (dpy); 2404456fccdSmrg GetReq (XFixesChangeCursorByName, req); 241a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 2424456fccdSmrg req->xfixesReqType = X_XFixesChangeCursorByName; 243a7e741d5Smrg req->source = (CARD32) source; 2444456fccdSmrg req->nbytes = nbytes; 2454456fccdSmrg req->length += (nbytes + 3) >> 2; 2464456fccdSmrg Data (dpy, name, nbytes); 2474456fccdSmrg UnlockDisplay(dpy); 2484456fccdSmrg SyncHandle(); 2494456fccdSmrg} 2504456fccdSmrg 2514456fccdSmrgvoid 2524456fccdSmrgXFixesHideCursor (Display *dpy, Window win) 2534456fccdSmrg{ 2544456fccdSmrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 2554456fccdSmrg xXFixesHideCursorReq *req; 2564456fccdSmrg 2574456fccdSmrg XFixesSimpleCheckExtension (dpy, info); 2584456fccdSmrg if (info->major_version < 4) 2594456fccdSmrg return; 2604456fccdSmrg LockDisplay (dpy); 2614456fccdSmrg GetReq (XFixesHideCursor, req); 262a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 2634456fccdSmrg req->xfixesReqType = X_XFixesHideCursor; 264a7e741d5Smrg req->window = (CARD32) win; 2654456fccdSmrg UnlockDisplay (dpy); 2664456fccdSmrg SyncHandle (); 2674456fccdSmrg} 2684456fccdSmrg 2694456fccdSmrgvoid 2704456fccdSmrgXFixesShowCursor (Display *dpy, Window win) 2714456fccdSmrg{ 2724456fccdSmrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 2734456fccdSmrg xXFixesShowCursorReq *req; 2744456fccdSmrg 2754456fccdSmrg XFixesSimpleCheckExtension (dpy, info); 2764456fccdSmrg if (info->major_version < 4) 2774456fccdSmrg return; 2784456fccdSmrg LockDisplay (dpy); 2794456fccdSmrg GetReq (XFixesShowCursor, req); 280a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 2814456fccdSmrg req->xfixesReqType = X_XFixesShowCursor; 282a7e741d5Smrg req->window = (CARD32) win; 2834456fccdSmrg UnlockDisplay (dpy); 2844456fccdSmrg SyncHandle (); 2854456fccdSmrg} 286ff63a143Smrg 287ff63a143SmrgPointerBarrier 288ff63a143SmrgXFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1, 289ff63a143Smrg int x2, int y2, int directions, 290ff63a143Smrg int num_devices, int *devices) 291ff63a143Smrg{ 292ff63a143Smrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 293ff63a143Smrg xXFixesCreatePointerBarrierReq *req; 294ff63a143Smrg PointerBarrier barrier; 295ff63a143Smrg int extra = 0; 296ff63a143Smrg 297ff63a143Smrg XFixesCheckExtension (dpy, info, 0); 298ff63a143Smrg if (info->major_version < 5) 299ff63a143Smrg return 0; 300ff63a143Smrg 301ff63a143Smrg if (num_devices) 302ff63a143Smrg extra = (((2 * num_devices) + 3) / 4) * 4; 303ff63a143Smrg 304ff63a143Smrg LockDisplay (dpy); 305ff63a143Smrg GetReqExtra (XFixesCreatePointerBarrier, extra, req); 306a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 307ff63a143Smrg req->xfixesReqType = X_XFixesCreatePointerBarrier; 308a7e741d5Smrg barrier = XAllocID (dpy); 309a7e741d5Smrg req->barrier = (CARD32) barrier; 310a7e741d5Smrg req->window = (CARD32) w; 311a7e741d5Smrg req->x1 = (INT16) x1; 312a7e741d5Smrg req->y1 = (INT16) y1; 313a7e741d5Smrg req->x2 = (INT16) x2; 314a7e741d5Smrg req->y2 = (INT16) y2; 315a7e741d5Smrg req->directions = (CARD32) directions; 316a7e741d5Smrg if ((req->num_devices = (CARD16) num_devices)) { 317ff63a143Smrg int i; 318ff63a143Smrg CARD16 *devs = (CARD16 *)(req + 1); 319ff63a143Smrg for (i = 0; i < num_devices; i++) 320ff63a143Smrg devs[i] = (CARD16)(devices[i]); 321ff63a143Smrg } 322ff63a143Smrg 323ff63a143Smrg UnlockDisplay (dpy); 324ff63a143Smrg SyncHandle(); 325ff63a143Smrg return barrier; 326ff63a143Smrg} 327ff63a143Smrg 328ff63a143Smrgvoid 329ff63a143SmrgXFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b) 330ff63a143Smrg{ 331ff63a143Smrg XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 332ff63a143Smrg xXFixesDestroyPointerBarrierReq *req; 333ff63a143Smrg 334ff63a143Smrg XFixesSimpleCheckExtension (dpy, info); 335ff63a143Smrg if (info->major_version < 5) 336ff63a143Smrg return; 337ff63a143Smrg 338ff63a143Smrg LockDisplay (dpy); 339ff63a143Smrg GetReq (XFixesDestroyPointerBarrier, req); 340a7e741d5Smrg req->reqType = (CARD8) info->codes->major_opcode; 341ff63a143Smrg req->xfixesReqType = X_XFixesDestroyPointerBarrier; 342a7e741d5Smrg req->barrier = (CARD32) b; 343ff63a143Smrg UnlockDisplay (dpy); 344ff63a143Smrg SyncHandle(); 345ff63a143Smrg} 346