1/* 2 * Copyright (c) 2006, Oracle and/or its affiliates. 3 * Copyright 2011 Red Hat, Inc. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24/* 25 * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. 26 * 27 * Permission to use, copy, modify, distribute, and sell this software and its 28 * documentation for any purpose is hereby granted without fee, provided that 29 * the above copyright notice appear in all copies and that both that 30 * copyright notice and this permission notice appear in supporting 31 * documentation, and that the name of Keith Packard not be used in 32 * advertising or publicity pertaining to distribution of the software without 33 * specific, written prior permission. Keith Packard makes no 34 * representations about the suitability of this software for any purpose. It 35 * is provided "as is" without express or implied warranty. 36 * 37 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 38 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 39 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 40 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 41 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 42 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 43 * PERFORMANCE OF THIS SOFTWARE. 44 */ 45 46#ifdef HAVE_CONFIG_H 47#include <config.h> 48#endif 49#include "Xfixesint.h" 50#include <limits.h> 51 52void 53XFixesSelectCursorInput (Display *dpy, 54 Window win, 55 unsigned long eventMask) 56{ 57 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 58 xXFixesSelectCursorInputReq *req; 59 60 XFixesSimpleCheckExtension (dpy, info); 61 62 LockDisplay (dpy); 63 GetReq (XFixesSelectCursorInput, req); 64 req->reqType = (CARD8) info->codes->major_opcode; 65 req->xfixesReqType = X_XFixesSelectCursorInput; 66 req->window = (CARD32) win; 67 req->eventMask = (CARD32) eventMask; 68 UnlockDisplay (dpy); 69 SyncHandle (); 70} 71 72XFixesCursorImage * 73XFixesGetCursorImage (Display *dpy) 74{ 75 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 76 xXFixesGetCursorImageAndNameReq *req; 77 xXFixesGetCursorImageAndNameReply rep; 78 size_t npixels; 79 size_t nbytes_name; 80 size_t nbytes = 0, nread = 0; 81 XFixesCursorImage *image; 82 char *name; 83 84 XFixesCheckExtension (dpy, info, NULL); 85 LockDisplay (dpy); 86 GetReq (XFixesGetCursorImageAndName, req); 87 req->reqType = (CARD8) info->codes->major_opcode; 88 if (info->major_version >= 2) 89 req->xfixesReqType = X_XFixesGetCursorImageAndName; 90 else 91 req->xfixesReqType = X_XFixesGetCursorImage; 92 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 93 { 94 UnlockDisplay (dpy); 95 SyncHandle (); 96 return NULL; 97 } 98 if (info->major_version < 2) 99 { 100 rep.cursorName = None; 101 rep.nbytes = 0; 102 } 103 npixels = rep.width * rep.height; 104 nbytes_name = rep.nbytes; 105 if ((rep.length < (INT_MAX >> 2)) && 106 npixels < (((INT_MAX >> 3) - sizeof (XFixesCursorImage) - 1) 107 - nbytes_name)) { 108 size_t rlength; 109 110 /* reply data length */ 111 nbytes = (size_t) rep.length << 2; 112 /* bytes of actual data in the reply */ 113 nread = (npixels << 2) + nbytes_name; 114 /* size of data returned to application */ 115 rlength = (sizeof (XFixesCursorImage) + 116 npixels * sizeof (unsigned long) + 117 nbytes_name + 1); 118 119 image = Xmalloc (rlength); 120 } else 121 image = NULL; 122 if (!image) 123 { 124 _XEatDataWords(dpy, rep.length); 125 UnlockDisplay (dpy); 126 SyncHandle (); 127 return NULL; 128 } 129 image->x = rep.x; 130 image->y = rep.y; 131 image->width = rep.width; 132 image->height = rep.height; 133 image->xhot = rep.xhot; 134 image->yhot = rep.yhot; 135 image->cursor_serial = rep.cursorSerial; 136 image->pixels = (unsigned long *) (image + 1); 137 image->atom = rep.cursorName; 138 name = (char *) (image->pixels + npixels); 139 image->name = name; 140 _XRead32 (dpy, (long *) image->pixels, npixels << 2); 141 _XRead (dpy, name, nbytes_name); 142 name[nbytes_name] = '\0'; /* null-terminate */ 143 /* skip any padding */ 144 if(nbytes > nread) 145 { 146 _XEatData (dpy, (unsigned long) (nbytes - nread)); 147 } 148 UnlockDisplay (dpy); 149 SyncHandle (); 150 return image; 151} 152 153void 154XFixesSetCursorName (Display *dpy, Cursor cursor, const char *name) 155{ 156 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 157 xXFixesSetCursorNameReq *req; 158 CARD16 nbytes = (CARD16) strlen (name); 159 160 XFixesSimpleCheckExtension (dpy, info); 161 if (info->major_version < 2) 162 return; 163 LockDisplay (dpy); 164 GetReq (XFixesSetCursorName, req); 165 req->reqType = (CARD8) info->codes->major_opcode; 166 req->xfixesReqType = X_XFixesSetCursorName; 167 req->cursor = (CARD32) cursor; 168 req->nbytes = nbytes; 169 req->length += (nbytes + 3) >> 2; 170 Data (dpy, name, nbytes); 171 UnlockDisplay (dpy); 172 SyncHandle (); 173} 174 175const char * 176XFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom) 177{ 178 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 179 xXFixesGetCursorNameReq *req; 180 xXFixesGetCursorNameReply rep; 181 char *name; 182 183 XFixesCheckExtension (dpy, info, NULL); 184 if (info->major_version < 2) 185 return NULL; 186 LockDisplay (dpy); 187 GetReq (XFixesGetCursorName, req); 188 req->reqType = (CARD8) info->codes->major_opcode; 189 req->xfixesReqType = X_XFixesGetCursorName; 190 req->cursor = (CARD32) cursor; 191 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 192 { 193 UnlockDisplay (dpy); 194 SyncHandle (); 195 return NULL; 196 } 197 *atom = rep.atom; 198 if ((name = Xmalloc(rep.nbytes+1)) != NULL) { 199 _XReadPad(dpy, name, (long)rep.nbytes); 200 name[rep.nbytes] = '\0'; 201 } else { 202 _XEatDataWords(dpy, rep.length); 203 name = (char *) NULL; 204 } 205 UnlockDisplay(dpy); 206 SyncHandle(); 207 return(name); 208} 209 210void 211XFixesChangeCursor (Display *dpy, Cursor source, Cursor destination) 212{ 213 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 214 xXFixesChangeCursorReq *req; 215 216 XFixesSimpleCheckExtension (dpy, info); 217 if (info->major_version < 2) 218 return; 219 LockDisplay (dpy); 220 GetReq (XFixesChangeCursor, req); 221 req->reqType = (CARD8) info->codes->major_opcode; 222 req->xfixesReqType = X_XFixesChangeCursor; 223 req->source = (CARD32) source; 224 req->destination = (CARD32) destination; 225 UnlockDisplay(dpy); 226 SyncHandle(); 227} 228 229void 230XFixesChangeCursorByName (Display *dpy, Cursor source, const char *name) 231{ 232 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 233 xXFixesChangeCursorByNameReq *req; 234 CARD16 nbytes = (CARD16) strlen (name); 235 236 XFixesSimpleCheckExtension (dpy, info); 237 if (info->major_version < 2) 238 return; 239 LockDisplay (dpy); 240 GetReq (XFixesChangeCursorByName, req); 241 req->reqType = (CARD8) info->codes->major_opcode; 242 req->xfixesReqType = X_XFixesChangeCursorByName; 243 req->source = (CARD32) source; 244 req->nbytes = nbytes; 245 req->length += (nbytes + 3) >> 2; 246 Data (dpy, name, nbytes); 247 UnlockDisplay(dpy); 248 SyncHandle(); 249} 250 251void 252XFixesHideCursor (Display *dpy, Window win) 253{ 254 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 255 xXFixesHideCursorReq *req; 256 257 XFixesSimpleCheckExtension (dpy, info); 258 if (info->major_version < 4) 259 return; 260 LockDisplay (dpy); 261 GetReq (XFixesHideCursor, req); 262 req->reqType = (CARD8) info->codes->major_opcode; 263 req->xfixesReqType = X_XFixesHideCursor; 264 req->window = (CARD32) win; 265 UnlockDisplay (dpy); 266 SyncHandle (); 267} 268 269void 270XFixesShowCursor (Display *dpy, Window win) 271{ 272 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 273 xXFixesShowCursorReq *req; 274 275 XFixesSimpleCheckExtension (dpy, info); 276 if (info->major_version < 4) 277 return; 278 LockDisplay (dpy); 279 GetReq (XFixesShowCursor, req); 280 req->reqType = (CARD8) info->codes->major_opcode; 281 req->xfixesReqType = X_XFixesShowCursor; 282 req->window = (CARD32) win; 283 UnlockDisplay (dpy); 284 SyncHandle (); 285} 286 287PointerBarrier 288XFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1, 289 int x2, int y2, int directions, 290 int num_devices, int *devices) 291{ 292 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 293 xXFixesCreatePointerBarrierReq *req; 294 PointerBarrier barrier; 295 int extra = 0; 296 297 XFixesCheckExtension (dpy, info, 0); 298 if (info->major_version < 5) 299 return 0; 300 301 if (num_devices) 302 extra = (((2 * num_devices) + 3) / 4) * 4; 303 304 LockDisplay (dpy); 305 GetReqExtra (XFixesCreatePointerBarrier, extra, req); 306 req->reqType = (CARD8) info->codes->major_opcode; 307 req->xfixesReqType = X_XFixesCreatePointerBarrier; 308 barrier = XAllocID (dpy); 309 req->barrier = (CARD32) barrier; 310 req->window = (CARD32) w; 311 req->x1 = (INT16) x1; 312 req->y1 = (INT16) y1; 313 req->x2 = (INT16) x2; 314 req->y2 = (INT16) y2; 315 req->directions = (CARD32) directions; 316 if ((req->num_devices = (CARD16) num_devices)) { 317 int i; 318 CARD16 *devs = (CARD16 *)(req + 1); 319 for (i = 0; i < num_devices; i++) 320 devs[i] = (CARD16)(devices[i]); 321 } 322 323 UnlockDisplay (dpy); 324 SyncHandle(); 325 return barrier; 326} 327 328void 329XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b) 330{ 331 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 332 xXFixesDestroyPointerBarrierReq *req; 333 334 XFixesSimpleCheckExtension (dpy, info); 335 if (info->major_version < 5) 336 return; 337 338 LockDisplay (dpy); 339 GetReq (XFixesDestroyPointerBarrier, req); 340 req->reqType = (CARD8) info->codes->major_opcode; 341 req->xfixesReqType = X_XFixesDestroyPointerBarrier; 342 req->barrier = (CARD32) b; 343 UnlockDisplay (dpy); 344 SyncHandle(); 345} 346