XTest.c revision ea133fd7
1/* $Xorg: XTest.c,v 1.5 2001/02/09 02:04:00 xorgcvs Exp $ */ 2/* 3Copyright 1990, 1991 by UniSoft Group Limited 4*/ 5 6/* 7 8Copyright 1992, 1993, 1998 The Open Group 9 10Permission to use, copy, modify, distribute, and sell this software and its 11documentation for any purpose is hereby granted without fee, provided that 12the above copyright notice appear in all copies and that both that 13copyright notice and this permission notice appear in supporting 14documentation. 15 16The above copyright notice and this permission notice shall be included 17in all copies or substantial portions of the Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 23OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 24ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25OTHER DEALINGS IN THE SOFTWARE. 26 27Except as contained in this notice, the name of The Open Group shall 28not be used in advertising or otherwise to promote the sale, use or 29other dealings in this Software without prior written authorization 30from The Open Group. 31 32*/ 33/* $XFree86: xc/lib/Xtst/XTest.c,v 1.5 2001/12/14 19:56:40 dawes Exp $ */ 34 35#define NEED_REPLIES 36#include <X11/Xlibint.h> 37#include <X11/extensions/XTest.h> 38#include <X11/extensions/xtestproto.h> 39#include <X11/extensions/Xext.h> 40#include <X11/extensions/extutil.h> 41#include <X11/extensions/XInput.h> 42#include <X11/extensions/XIproto.h> 43 44static XExtensionInfo _xtest_info_data; 45static XExtensionInfo *xtest_info = &_xtest_info_data; 46static /* const */ char *xtest_extension_name = XTestExtensionName; 47 48#define XTestCheckExtension(dpy,i,val) \ 49 XextCheckExtension (dpy, i, xtest_extension_name, val) 50 51#define XTestICheckExtension(dpy,i,val) \ 52 XextCheckExtension (dpy, i, xtest_extension_name, val); \ 53 if (!i->data) return val 54 55/***************************************************************************** 56 * * 57 * private utility routines * 58 * * 59 *****************************************************************************/ 60 61static int close_display(Display *dpy, XExtCodes *codes); 62static /* const */ XExtensionHooks xtest_extension_hooks = { 63 NULL, /* create_gc */ 64 NULL, /* copy_gc */ 65 NULL, /* flush_gc */ 66 NULL, /* free_gc */ 67 NULL, /* create_font */ 68 NULL, /* free_font */ 69 close_display, /* close_display */ 70 NULL, /* wire_to_event */ 71 NULL, /* event_to_wire */ 72 NULL, /* error */ 73 NULL /* error_string */ 74}; 75 76static XPointer 77get_xinput_base(Display *dpy) 78{ 79 int major_opcode, first_event, first_error; 80 first_event = 0; 81 82 XQueryExtension(dpy, INAME, &major_opcode, &first_event, &first_error); 83 return (XPointer)(long)first_event; 84} 85 86static XEXT_GENERATE_FIND_DISPLAY (find_display, xtest_info, 87 xtest_extension_name, 88 &xtest_extension_hooks, XTestNumberEvents, 89 get_xinput_base(dpy)) 90 91static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xtest_info) 92 93/***************************************************************************** 94 * * 95 * public routines * 96 * * 97 *****************************************************************************/ 98 99Bool 100XTestQueryExtension (Display *dpy, 101 int *event_base_return, int *error_base_return, 102 int *major_return, int *minor_return) 103{ 104 XExtDisplayInfo *info = find_display (dpy); 105 register xXTestGetVersionReq *req; 106 xXTestGetVersionReply rep; 107 108 if (XextHasExtension(info)) { 109 LockDisplay(dpy); 110 GetReq(XTestGetVersion, req); 111 req->reqType = info->codes->major_opcode; 112 req->xtReqType = X_XTestGetVersion; 113 req->majorVersion = XTestMajorVersion; 114 req->minorVersion = XTestMinorVersion; 115 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 116 UnlockDisplay(dpy); 117 SyncHandle(); 118 return False; 119 } 120 UnlockDisplay(dpy); 121 SyncHandle(); 122 *event_base_return = info->codes->first_event; 123 *error_base_return = info->codes->first_error; 124 *major_return = rep.majorVersion; 125 *minor_return = rep.minorVersion; 126 return True; 127 } else { 128 return False; 129 } 130} 131 132Bool 133XTestCompareCursorWithWindow(Display *dpy, Window window, Cursor cursor) 134{ 135 XExtDisplayInfo *info = find_display (dpy); 136 register xXTestCompareCursorReq *req; 137 xXTestCompareCursorReply rep; 138 139 XTestCheckExtension (dpy, info, 0); 140 141 LockDisplay(dpy); 142 GetReq(XTestCompareCursor, req); 143 req->reqType = info->codes->major_opcode; 144 req->xtReqType = X_XTestCompareCursor; 145 req->window = window; 146 req->cursor = cursor; 147 if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { 148 UnlockDisplay(dpy); 149 SyncHandle(); 150 return False; 151 } 152 UnlockDisplay(dpy); 153 SyncHandle(); 154 return rep.same; 155} 156 157Bool 158XTestCompareCurrentCursorWithWindow(Display *dpy, Window window) 159{ 160 return XTestCompareCursorWithWindow(dpy, window, XTestCurrentCursor); 161} 162 163int 164XTestFakeKeyEvent(Display *dpy, unsigned int keycode, 165 Bool is_press, unsigned long delay) 166{ 167 XExtDisplayInfo *info = find_display (dpy); 168 register xXTestFakeInputReq *req; 169 170 XTestCheckExtension (dpy, info, 0); 171 172 LockDisplay(dpy); 173 GetReq(XTestFakeInput, req); 174 req->reqType = info->codes->major_opcode; 175 req->xtReqType = X_XTestFakeInput; 176 req->type = is_press ? KeyPress : KeyRelease; 177 req->detail = keycode; 178 req->time = delay; 179 UnlockDisplay(dpy); 180 SyncHandle(); 181 return 1; 182} 183 184int 185XTestFakeButtonEvent(Display *dpy, unsigned int button, 186 Bool is_press, unsigned long delay) 187{ 188 XExtDisplayInfo *info = find_display (dpy); 189 register xXTestFakeInputReq *req; 190 191 XTestCheckExtension (dpy, info, 0); 192 193 LockDisplay(dpy); 194 GetReq(XTestFakeInput, req); 195 req->reqType = info->codes->major_opcode; 196 req->xtReqType = X_XTestFakeInput; 197 req->type = is_press ? ButtonPress : ButtonRelease; 198 req->detail = button; 199 req->time = delay; 200 UnlockDisplay(dpy); 201 SyncHandle(); 202 return 1; 203} 204 205int 206XTestFakeMotionEvent(Display *dpy, int screen, int x, int y, unsigned long delay) 207{ 208 XExtDisplayInfo *info = find_display (dpy); 209 register xXTestFakeInputReq *req; 210 211 XTestCheckExtension (dpy, info, 0); 212 213 LockDisplay(dpy); 214 GetReq(XTestFakeInput, req); 215 req->reqType = info->codes->major_opcode; 216 req->xtReqType = X_XTestFakeInput; 217 req->type = MotionNotify; 218 req->detail = False; 219 if (screen == -1) 220 req->root = None; 221 else 222 req->root = RootWindow(dpy, screen); 223 req->rootX = x; 224 req->rootY = y; 225 req->time = delay; 226 UnlockDisplay(dpy); 227 SyncHandle(); 228 return 1; 229} 230 231int 232XTestFakeRelativeMotionEvent(Display *dpy, int dx, int dy, unsigned long delay) 233{ 234 XExtDisplayInfo *info = find_display (dpy); 235 register xXTestFakeInputReq *req; 236 237 XTestCheckExtension (dpy, info, 0); 238 239 LockDisplay(dpy); 240 GetReq(XTestFakeInput, req); 241 req->reqType = info->codes->major_opcode; 242 req->xtReqType = X_XTestFakeInput; 243 req->type = MotionNotify; 244 req->detail = True; 245 req->root = None; 246 req->rootX = dx; 247 req->rootY = dy; 248 req->time = delay; 249 UnlockDisplay(dpy); 250 SyncHandle(); 251 return 1; 252} 253 254static void 255send_axes( 256 Display *dpy, 257 XExtDisplayInfo *info, 258 xXTestFakeInputReq *req, 259 XDevice *dev, 260 int first_axis, 261 int *axes, 262 int n_axes) 263{ 264 deviceValuator ev; 265 int n; 266 267 req->deviceid |= MORE_EVENTS; 268 req->length += ((n_axes + 5) / 6) * (SIZEOF(xEvent) >> 2); 269 ev.type = XI_DeviceValuator + (long)info->data; 270 ev.deviceid = dev->device_id; 271 ev.num_valuators = n_axes; 272 ev.first_valuator = first_axis; 273 while (n_axes > 0) { 274 n = n_axes; 275 if (n > 6) 276 n = 6; 277 switch (n) { 278 case 6: 279 ev.valuator5 = *(axes+5); 280 case 5: 281 ev.valuator4 = *(axes+4); 282 case 4: 283 ev.valuator3 = *(axes+3); 284 case 3: 285 ev.valuator2 = *(axes+2); 286 case 2: 287 ev.valuator1 = *(axes+1); 288 case 1: 289 ev.valuator0 = *axes; 290 } 291 Data(dpy, (char *)&ev, SIZEOF(xEvent)); 292 axes += n; 293 n_axes -= n; 294 ev.first_valuator += n; 295 } 296} 297 298int 299XTestFakeDeviceKeyEvent(Display *dpy, XDevice *dev, 300 unsigned int keycode, Bool is_press, 301 int *axes, int n_axes, unsigned long delay) 302{ 303 XExtDisplayInfo *info = find_display (dpy); 304 register xXTestFakeInputReq *req; 305 306 XTestICheckExtension (dpy, info, 0); 307 308 LockDisplay(dpy); 309 GetReq(XTestFakeInput, req); 310 req->reqType = info->codes->major_opcode; 311 req->xtReqType = X_XTestFakeInput; 312 req->type = is_press ? XI_DeviceKeyPress : XI_DeviceKeyRelease; 313 req->type += (int)(long)info->data; 314 req->detail = keycode; 315 req->time = delay; 316 req->deviceid = dev->device_id; 317 if (n_axes) 318 send_axes(dpy, info, req, dev, 0, axes, n_axes); 319 UnlockDisplay(dpy); 320 SyncHandle(); 321 return 1; 322} 323 324int 325XTestFakeDeviceButtonEvent(Display *dpy, XDevice *dev, 326 unsigned int button, Bool is_press, 327 int *axes, int n_axes, unsigned long delay) 328{ 329 XExtDisplayInfo *info = find_display (dpy); 330 register xXTestFakeInputReq *req; 331 332 XTestICheckExtension (dpy, info, 0); 333 334 LockDisplay(dpy); 335 GetReq(XTestFakeInput, req); 336 req->reqType = info->codes->major_opcode; 337 req->xtReqType = X_XTestFakeInput; 338 req->type = is_press ? XI_DeviceButtonPress : XI_DeviceButtonRelease; 339 req->type += (int)(long)info->data; 340 req->detail = button; 341 req->time = delay; 342 req->deviceid = dev->device_id; 343 if (n_axes) 344 send_axes(dpy, info, req, dev, 0, axes, n_axes); 345 UnlockDisplay(dpy); 346 SyncHandle(); 347 return 1; 348} 349 350int 351XTestFakeProximityEvent(Display *dpy, XDevice *dev, Bool in_prox, 352 int *axes, int n_axes, unsigned long delay) 353{ 354 XExtDisplayInfo *info = find_display (dpy); 355 register xXTestFakeInputReq *req; 356 357 XTestICheckExtension (dpy, info, 0); 358 359 LockDisplay(dpy); 360 GetReq(XTestFakeInput, req); 361 req->reqType = info->codes->major_opcode; 362 req->xtReqType = X_XTestFakeInput; 363 req->type = in_prox ? XI_ProximityIn : XI_ProximityOut; 364 req->type += (int)(long)info->data; 365 req->time = delay; 366 req->deviceid = dev->device_id; 367 if (n_axes) 368 send_axes(dpy, info, req, dev, 0, axes, n_axes); 369 UnlockDisplay(dpy); 370 SyncHandle(); 371 return 1; 372} 373 374int 375XTestFakeDeviceMotionEvent(Display *dpy, XDevice *dev, 376 Bool is_relative, int first_axis, 377 int *axes, int n_axes, unsigned long delay) 378{ 379 XExtDisplayInfo *info = find_display (dpy); 380 register xXTestFakeInputReq *req; 381 382 XTestICheckExtension (dpy, info, 0); 383 384 LockDisplay(dpy); 385 GetReq(XTestFakeInput, req); 386 req->reqType = info->codes->major_opcode; 387 req->xtReqType = X_XTestFakeInput; 388 req->type = XI_DeviceMotionNotify + (int)(long)info->data; 389 req->detail = is_relative; 390 req->time = delay; 391 req->deviceid = dev->device_id; 392 send_axes(dpy, info, req, dev, first_axis, axes, n_axes); 393 UnlockDisplay(dpy); 394 SyncHandle(); 395 return 1; 396} 397 398int 399XTestGrabControl(Display *dpy, Bool impervious) 400{ 401 XExtDisplayInfo *info = find_display (dpy); 402 register xXTestGrabControlReq *req; 403 404 XTestCheckExtension (dpy, info, 0); 405 406 LockDisplay(dpy); 407 GetReq(XTestGrabControl, req); 408 req->reqType = info->codes->major_opcode; 409 req->xtReqType = X_XTestGrabControl; 410 req->impervious = impervious; 411 UnlockDisplay(dpy); 412 SyncHandle(); 413 return 1; 414} 415 416void 417XTestSetGContextOfGC(GC gc, GContext gid) 418{ 419 gc->gid = gid; 420} 421 422void 423XTestSetVisualIDOfVisual(Visual *visual, VisualID visualid) 424{ 425 visual->visualid = visualid; 426} 427 428static xReq _dummy_request = { 429 0, 0, 0 430}; 431 432Status 433XTestDiscard(Display *dpy) 434{ 435 Bool something; 436 register char *ptr; 437 438 LockDisplay(dpy); 439 if ((something = (dpy->bufptr != dpy->buffer))) { 440 for (ptr = dpy->buffer; 441 ptr < dpy->bufptr; 442 ptr += (((xReq *)ptr)->length << 2)) 443 dpy->request--; 444 dpy->bufptr = dpy->buffer; 445 dpy->last_req = (char *)&_dummy_request; 446 } 447 UnlockDisplay(dpy); 448 SyncHandle(); 449 return something; 450} 451