Cursor.c revision ff63a143
1/* 2 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. 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 51void 52XFixesSelectCursorInput (Display *dpy, 53 Window win, 54 unsigned long eventMask) 55{ 56 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 57 xXFixesSelectCursorInputReq *req; 58 59 XFixesSimpleCheckExtension (dpy, info); 60 61 LockDisplay (dpy); 62 GetReq (XFixesSelectCursorInput, req); 63 req->reqType = info->codes->major_opcode; 64 req->xfixesReqType = X_XFixesSelectCursorInput; 65 req->window = win; 66 req->eventMask = eventMask; 67 UnlockDisplay (dpy); 68 SyncHandle (); 69} 70 71XFixesCursorImage * 72XFixesGetCursorImage (Display *dpy) 73{ 74 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 75 xXFixesGetCursorImageAndNameReq *req; 76 xXFixesGetCursorImageAndNameReply rep; 77 int npixels; 78 int nbytes_name; 79 int nbytes, nread, rlength; 80 XFixesCursorImage *image; 81 char *name; 82 83 XFixesCheckExtension (dpy, info, NULL); 84 LockDisplay (dpy); 85 GetReq (XFixesGetCursorImageAndName, req); 86 req->reqType = info->codes->major_opcode; 87 if (info->major_version >= 2) 88 req->xfixesReqType = X_XFixesGetCursorImageAndName; 89 else 90 req->xfixesReqType = X_XFixesGetCursorImage; 91 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 92 { 93 UnlockDisplay (dpy); 94 SyncHandle (); 95 return NULL; 96 } 97 if (info->major_version < 2) 98 { 99 rep.cursorName = None; 100 rep.nbytes = 0; 101 } 102 npixels = rep.width * rep.height; 103 nbytes_name = rep.nbytes; 104 /* reply data length */ 105 nbytes = (long) rep.length << 2; 106 /* bytes of actual data in the reply */ 107 nread = (npixels << 2) + nbytes_name; 108 /* size of data returned to application */ 109 rlength = (sizeof (XFixesCursorImage) + 110 npixels * sizeof (unsigned long) + 111 nbytes_name + 1); 112 113 image = (XFixesCursorImage *) Xmalloc (rlength); 114 if (!image) 115 { 116 _XEatData (dpy, nbytes); 117 UnlockDisplay (dpy); 118 SyncHandle (); 119 return NULL; 120 } 121 image->x = rep.x; 122 image->y = rep.y; 123 image->width = rep.width; 124 image->height = rep.height; 125 image->xhot = rep.xhot; 126 image->yhot = rep.yhot; 127 image->cursor_serial = rep.cursorSerial; 128 image->pixels = (unsigned long *) (image + 1); 129 image->atom = rep.cursorName; 130 name = (char *) (image->pixels + npixels); 131 image->name = name; 132 _XRead32 (dpy, (long *) image->pixels, npixels << 2); 133 _XRead (dpy, name, nbytes_name); 134 name[nbytes_name] = '\0'; /* null-terminate */ 135 /* skip any padding */ 136 if(nbytes > nread) 137 { 138 _XEatData (dpy, (unsigned long) (nbytes - nread)); 139 } 140 UnlockDisplay (dpy); 141 SyncHandle (); 142 return image; 143} 144 145void 146XFixesSetCursorName (Display *dpy, Cursor cursor, const char *name) 147{ 148 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 149 xXFixesSetCursorNameReq *req; 150 int nbytes = strlen (name); 151 152 XFixesSimpleCheckExtension (dpy, info); 153 if (info->major_version < 2) 154 return; 155 LockDisplay (dpy); 156 GetReq (XFixesSetCursorName, req); 157 req->reqType = info->codes->major_opcode; 158 req->xfixesReqType = X_XFixesSetCursorName; 159 req->cursor = cursor; 160 req->nbytes = nbytes; 161 req->length += (nbytes + 3) >> 2; 162 Data (dpy, name, nbytes); 163 UnlockDisplay (dpy); 164 SyncHandle (); 165} 166 167const char * 168XFixesGetCursorName (Display *dpy, Cursor cursor, Atom *atom) 169{ 170 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 171 xXFixesGetCursorNameReq *req; 172 xXFixesGetCursorNameReply rep; 173 char *name; 174 175 XFixesCheckExtension (dpy, info, NULL); 176 if (info->major_version < 2) 177 return NULL; 178 LockDisplay (dpy); 179 GetReq (XFixesGetCursorName, req); 180 req->reqType = info->codes->major_opcode; 181 req->xfixesReqType = X_XFixesGetCursorName; 182 req->cursor = cursor; 183 if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) 184 { 185 UnlockDisplay (dpy); 186 SyncHandle (); 187 return NULL; 188 } 189 *atom = rep.atom; 190 if ((name = (char *) Xmalloc(rep.nbytes+1))) { 191 _XReadPad(dpy, name, (long)rep.nbytes); 192 name[rep.nbytes] = '\0'; 193 } else { 194 _XEatData(dpy, (unsigned long) (rep.nbytes + 3) & ~3); 195 name = (char *) NULL; 196 } 197 UnlockDisplay(dpy); 198 SyncHandle(); 199 return(name); 200} 201 202void 203XFixesChangeCursor (Display *dpy, Cursor source, Cursor destination) 204{ 205 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 206 xXFixesChangeCursorReq *req; 207 208 XFixesSimpleCheckExtension (dpy, info); 209 if (info->major_version < 2) 210 return; 211 LockDisplay (dpy); 212 GetReq (XFixesChangeCursor, req); 213 req->reqType = info->codes->major_opcode; 214 req->xfixesReqType = X_XFixesChangeCursor; 215 req->source = source; 216 req->destination = destination; 217 UnlockDisplay(dpy); 218 SyncHandle(); 219} 220 221void 222XFixesChangeCursorByName (Display *dpy, Cursor source, const char *name) 223{ 224 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 225 xXFixesChangeCursorByNameReq *req; 226 int nbytes = strlen (name); 227 228 XFixesSimpleCheckExtension (dpy, info); 229 if (info->major_version < 2) 230 return; 231 LockDisplay (dpy); 232 GetReq (XFixesChangeCursorByName, req); 233 req->reqType = info->codes->major_opcode; 234 req->xfixesReqType = X_XFixesChangeCursorByName; 235 req->source = source; 236 req->nbytes = nbytes; 237 req->length += (nbytes + 3) >> 2; 238 Data (dpy, name, nbytes); 239 UnlockDisplay(dpy); 240 SyncHandle(); 241} 242 243void 244XFixesHideCursor (Display *dpy, Window win) 245{ 246 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 247 xXFixesHideCursorReq *req; 248 249 XFixesSimpleCheckExtension (dpy, info); 250 if (info->major_version < 4) 251 return; 252 LockDisplay (dpy); 253 GetReq (XFixesHideCursor, req); 254 req->reqType = info->codes->major_opcode; 255 req->xfixesReqType = X_XFixesHideCursor; 256 req->window = win; 257 UnlockDisplay (dpy); 258 SyncHandle (); 259} 260 261void 262XFixesShowCursor (Display *dpy, Window win) 263{ 264 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 265 xXFixesShowCursorReq *req; 266 267 XFixesSimpleCheckExtension (dpy, info); 268 if (info->major_version < 4) 269 return; 270 LockDisplay (dpy); 271 GetReq (XFixesShowCursor, req); 272 req->reqType = info->codes->major_opcode; 273 req->xfixesReqType = X_XFixesShowCursor; 274 req->window = win; 275 UnlockDisplay (dpy); 276 SyncHandle (); 277} 278 279PointerBarrier 280XFixesCreatePointerBarrier(Display *dpy, Window w, int x1, int y1, 281 int x2, int y2, int directions, 282 int num_devices, int *devices) 283{ 284 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 285 xXFixesCreatePointerBarrierReq *req; 286 PointerBarrier barrier; 287 int extra = 0; 288 289 XFixesCheckExtension (dpy, info, 0); 290 if (info->major_version < 5) 291 return 0; 292 293 if (num_devices) 294 extra = (((2 * num_devices) + 3) / 4) * 4; 295 296 LockDisplay (dpy); 297 GetReqExtra (XFixesCreatePointerBarrier, extra, req); 298 req->reqType = info->codes->major_opcode; 299 req->xfixesReqType = X_XFixesCreatePointerBarrier; 300 barrier = req->barrier = XAllocID (dpy); 301 req->window = w; 302 req->x1 = x1; 303 req->y1 = y1; 304 req->x2 = x2; 305 req->y2 = y2; 306 req->directions = directions; 307 if ((req->num_devices = num_devices)) { 308 int i; 309 CARD16 *devs = (CARD16 *)(req + 1); 310 for (i = 0; i < num_devices; i++) 311 devs[i] = (CARD16)(devices[i]); 312 } 313 314 UnlockDisplay (dpy); 315 SyncHandle(); 316 return barrier; 317} 318 319void 320XFixesDestroyPointerBarrier(Display *dpy, PointerBarrier b) 321{ 322 XFixesExtDisplayInfo *info = XFixesFindDisplay (dpy); 323 xXFixesDestroyPointerBarrierReq *req; 324 325 XFixesSimpleCheckExtension (dpy, info); 326 if (info->major_version < 5) 327 return; 328 329 LockDisplay (dpy); 330 GetReq (XFixesDestroyPointerBarrier, req); 331 req->reqType = info->codes->major_opcode; 332 req->xfixesReqType = X_XFixesDestroyPointerBarrier; 333 req->barrier = b; 334 UnlockDisplay (dpy); 335 SyncHandle(); 336} 337