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