XTestExt1.c revision caade7cc
1caade7ccSmrg/* $Xorg: XTestExt1.c,v 1.4 2001/02/09 02:03:49 xorgcvs Exp $ */ 2caade7ccSmrg/* 3caade7ccSmrg * File: xtestext1lib.c 4caade7ccSmrg * 5caade7ccSmrg * This file contains the Xlib parts of the input synthesis extension 6caade7ccSmrg */ 7caade7ccSmrg 8caade7ccSmrg/* 9caade7ccSmrg 10caade7ccSmrg 11caade7ccSmrgCopyright 1986, 1987, 1988, 1998 The Open Group 12caade7ccSmrg 13caade7ccSmrgPermission to use, copy, modify, distribute, and sell this software and its 14caade7ccSmrgdocumentation for any purpose is hereby granted without fee, provided that 15caade7ccSmrgthe above copyright notice appear in all copies and that both that 16caade7ccSmrgcopyright notice and this permission notice appear in supporting 17caade7ccSmrgdocumentation. 18caade7ccSmrg 19caade7ccSmrgThe above copyright notice and this permission notice shall be included in 20caade7ccSmrgall copies or substantial portions of the Software. 21caade7ccSmrg 22caade7ccSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23caade7ccSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24caade7ccSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25caade7ccSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26caade7ccSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 27caade7ccSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28caade7ccSmrg 29caade7ccSmrgExcept as contained in this notice, the name of The Open Group shall not be 30caade7ccSmrgused in advertising or otherwise to promote the sale, use or other dealings 31caade7ccSmrgin this Software without prior written authorization from The Open Group. 32caade7ccSmrg 33caade7ccSmrg 34caade7ccSmrgCopyright 1986, 1987, 1988 by Hewlett-Packard Corporation 35caade7ccSmrg 36caade7ccSmrgPermission to use, copy, modify, and distribute this 37caade7ccSmrgsoftware and its documentation for any purpose and without 38caade7ccSmrgfee is hereby granted, provided that the above copyright 39caade7ccSmrgnotice appear in all copies and that both that copyright 40caade7ccSmrgnotice and this permission notice appear in supporting 41caade7ccSmrgdocumentation, and that the name of Hewlett-Packard not be used in 42caade7ccSmrgadvertising or publicity pertaining to distribution of the 43caade7ccSmrgsoftware without specific, written prior permission. 44caade7ccSmrg 45caade7ccSmrgHewlett-Packard makes no representations about the 46caade7ccSmrgsuitability of this software for any purpose. It is provided 47caade7ccSmrg"as is" without express or implied warranty. 48caade7ccSmrg 49caade7ccSmrgThis software is not subject to any license of the American 50caade7ccSmrgTelephone and Telegraph Company or of the Regents of the 51caade7ccSmrgUniversity of California. 52caade7ccSmrg 53caade7ccSmrg*/ 54caade7ccSmrg/* $XFree86: xc/lib/Xext/XTestExt1.c,v 1.3 2001/01/17 19:42:46 dawes Exp $ */ 55caade7ccSmrg 56caade7ccSmrg/****************************************************************************** 57caade7ccSmrg * include files 58caade7ccSmrg *****************************************************************************/ 59caade7ccSmrg 60caade7ccSmrg#define NEED_REPLIES 61caade7ccSmrg#define NEED_EVENTS 62caade7ccSmrg 63caade7ccSmrg#ifdef HAVE_CONFIG_H 64caade7ccSmrg#include <config.h> 65caade7ccSmrg#endif 66caade7ccSmrg#include <stdio.h> 67caade7ccSmrg#include <X11/Xproto.h> 68caade7ccSmrg#include <X11/Xlibint.h> 69caade7ccSmrg#include <X11/extensions/xtestext1.h> 70caade7ccSmrg 71caade7ccSmrg/****************************************************************************** 72caade7ccSmrg * variables 73caade7ccSmrg *****************************************************************************/ 74caade7ccSmrg 75caade7ccSmrg/* 76caade7ccSmrg * Holds the request type code for this extension. The request type code 77caade7ccSmrg * for this extension may vary depending on how many extensions are installed 78caade7ccSmrg * already, so the initial value given below will be added to the base request 79caade7ccSmrg * code that is acquired when this extension is installed. 80caade7ccSmrg */ 81caade7ccSmrgstatic int XTestReqCode = 0; 82caade7ccSmrg/* 83caade7ccSmrg * Holds the two event type codes for this extension. The event type codes 84caade7ccSmrg * for this extension may vary depending on how many extensions are installed 85caade7ccSmrg * already, so the initial values given below will be added to the base event 86caade7ccSmrg * code that is acquired when this extension is installed. 87caade7ccSmrg * 88caade7ccSmrg * These two variables must be available to programs that use this extension. 89caade7ccSmrg */ 90caade7ccSmrgint XTestInputActionType = 0; 91caade7ccSmrgint XTestFakeAckType = 1; 92caade7ccSmrg/* 93caade7ccSmrg * holds the current x and y coordinates for XTestMovePointer 94caade7ccSmrg */ 95caade7ccSmrgstatic int current_x = 0; 96caade7ccSmrgstatic int current_y = 0; 97caade7ccSmrg/* 98caade7ccSmrg * Holds input actions being accumulated until the input action buffer is 99caade7ccSmrg * full or until XTestFlush is called. 100caade7ccSmrg */ 101caade7ccSmrgstatic CARD8 action_buf[XTestMAX_ACTION_LIST_SIZE]; 102caade7ccSmrg/* 103caade7ccSmrg * the index into the input action buffer 104caade7ccSmrg */ 105caade7ccSmrgstatic int action_index = 0; 106caade7ccSmrg/* 107caade7ccSmrg * the number of input actions that the server can handle at one time 108caade7ccSmrg */ 109caade7ccSmrgstatic unsigned long action_array_size = 0; 110caade7ccSmrg/* 111caade7ccSmrg * the current number of input actions 112caade7ccSmrg */ 113caade7ccSmrgstatic unsigned long action_count = 0; 114caade7ccSmrg 115caade7ccSmrg/****************************************************************************** 116caade7ccSmrg * function declarations 117caade7ccSmrg *****************************************************************************/ 118caade7ccSmrg 119caade7ccSmrgstatic int XTestWireToEvent(Display *dpy, XEvent *reTemp, xEvent *eventTemp); 120caade7ccSmrgstatic int XTestCheckExtInit(register Display *dpy); 121caade7ccSmrgstatic Bool XTestIdentifyMyEvent(Display *display, XEvent *event_ptr, char *args); 122caade7ccSmrgstatic int XTestInitExtension(register Display *dpy); 123caade7ccSmrgstatic int XTestKeyOrButton(Display *display, int device_id, long unsigned int delay, unsigned int code, unsigned int action); 124caade7ccSmrgstatic int XTestCheckDelay(Display *display, long unsigned int *delay_addr); 125caade7ccSmrgstatic int XTestPackInputAction(Display *display, CARD8 *action_addr, int action_size); 126caade7ccSmrgstatic int XTestWriteInputActions(Display *display, char *action_list_addr, int action_list_size, int ack_flag); 127caade7ccSmrg 128caade7ccSmrg/****************************************************************************** 129caade7ccSmrg * 130caade7ccSmrg * XTestFakeInput 131caade7ccSmrg * 132caade7ccSmrg * Send a a request containing one or more input actions to be sent 133caade7ccSmrg * to the server by this extension. 134caade7ccSmrg */ 135caade7ccSmrgint 136caade7ccSmrgXTestFakeInput( 137caade7ccSmrg/* 138caade7ccSmrg * the connection to the X server 139caade7ccSmrg */ 140caade7ccSmrgregister Display *dpy, 141caade7ccSmrg/* 142caade7ccSmrg * the address of a list of input actions to be sent to the server 143caade7ccSmrg */ 144caade7ccSmrgchar *action_list_addr, 145caade7ccSmrg/* 146caade7ccSmrg * the size (in bytes) of the list of input actions 147caade7ccSmrg */ 148caade7ccSmrgint action_list_size, 149caade7ccSmrg/* 150caade7ccSmrg * specifies whether the server needs to send an event to indicate that its 151caade7ccSmrg * input action buffer is empty 152caade7ccSmrg */ 153caade7ccSmrgint ack_flag) 154caade7ccSmrg{ 155caade7ccSmrg /* 156caade7ccSmrg * pointer to xTestFakeInputReq structure 157caade7ccSmrg */ 158caade7ccSmrg xTestFakeInputReq *req; 159caade7ccSmrg /* 160caade7ccSmrg * loop index 161caade7ccSmrg */ 162caade7ccSmrg int i; 163caade7ccSmrg 164caade7ccSmrg LockDisplay(dpy); 165caade7ccSmrg if ((XTestCheckExtInit(dpy) == -1) || 166caade7ccSmrg (action_list_size > XTestMAX_ACTION_LIST_SIZE)) 167caade7ccSmrg { 168caade7ccSmrg /* 169caade7ccSmrg * if the extension is not installed in the server or the 170caade7ccSmrg * action list will not fit in the request, then unlock 171caade7ccSmrg * the display and return -1. 172caade7ccSmrg */ 173caade7ccSmrg UnlockDisplay(dpy); 174caade7ccSmrg return(-1); 175caade7ccSmrg } 176caade7ccSmrg else 177caade7ccSmrg { 178caade7ccSmrg /* 179caade7ccSmrg * Get the next available X request packet in the buffer. 180caade7ccSmrg * It sets the `length' field to the size (in 32-bit words) 181caade7ccSmrg * of the request. It also sets the `reqType' field in the 182caade7ccSmrg * request to X_TestFakeInput, which is not what is needed. 183caade7ccSmrg * 184caade7ccSmrg * GetReq is a macro defined in Xlibint.h. 185caade7ccSmrg */ 186caade7ccSmrg GetReq(TestFakeInput, req); 187caade7ccSmrg /* 188caade7ccSmrg * fix up the request type code to what is needed 189caade7ccSmrg */ 190caade7ccSmrg req->reqType = XTestReqCode; 191caade7ccSmrg /* 192caade7ccSmrg * set the minor request type code to X_TestFakeInput 193caade7ccSmrg */ 194caade7ccSmrg req->XTestReqType = X_TestFakeInput; 195caade7ccSmrg /* 196caade7ccSmrg * set the ack code 197caade7ccSmrg */ 198caade7ccSmrg req->ack = ack_flag; 199caade7ccSmrg /* 200caade7ccSmrg * Set the action_list area to all 0's. An input action header 201caade7ccSmrg * value of 0 is interpreted as a flag to the input action 202caade7ccSmrg * list handling code in the server part of this extension 203caade7ccSmrg * that there are no more input actions in this request. 204caade7ccSmrg */ 205caade7ccSmrg for (i = 0; i < XTestMAX_ACTION_LIST_SIZE; i++) 206caade7ccSmrg { 207caade7ccSmrg req->action_list[i] = 0; 208caade7ccSmrg } 209caade7ccSmrg /* 210caade7ccSmrg * copy the input actions into the request 211caade7ccSmrg */ 212caade7ccSmrg for (i = 0; i < action_list_size; i++) 213caade7ccSmrg { 214caade7ccSmrg req->action_list[i] = *(action_list_addr++); 215caade7ccSmrg } 216caade7ccSmrg UnlockDisplay(dpy); 217caade7ccSmrg SyncHandle(); 218caade7ccSmrg return(0); 219caade7ccSmrg } 220caade7ccSmrg} 221caade7ccSmrg 222caade7ccSmrg/****************************************************************************** 223caade7ccSmrg * 224caade7ccSmrg * XTestGetInput 225caade7ccSmrg * 226caade7ccSmrg * Request the server to begin putting user input actions into events 227caade7ccSmrg * to be sent to the client that called this function. 228caade7ccSmrg */ 229caade7ccSmrgint 230caade7ccSmrgXTestGetInput( 231caade7ccSmrg/* 232caade7ccSmrg * the connection to the X server 233caade7ccSmrg */ 234caade7ccSmrgregister Display *dpy, 235caade7ccSmrg/* 236caade7ccSmrg * tells the server what to do with the user input actions 237caade7ccSmrg */ 238caade7ccSmrgint action_handling) 239caade7ccSmrg{ 240caade7ccSmrg /* 241caade7ccSmrg * pointer to xTestGetInputReq structure 242caade7ccSmrg */ 243caade7ccSmrg xTestGetInputReq *req; 244caade7ccSmrg 245caade7ccSmrg LockDisplay(dpy); 246caade7ccSmrg if (XTestCheckExtInit(dpy) == -1) 247caade7ccSmrg { 248caade7ccSmrg /* 249caade7ccSmrg * if the extension is not installed in the server 250caade7ccSmrg * then unlock the display and return -1. 251caade7ccSmrg */ 252caade7ccSmrg UnlockDisplay(dpy); 253caade7ccSmrg return(-1); 254caade7ccSmrg } 255caade7ccSmrg else 256caade7ccSmrg { 257caade7ccSmrg /* 258caade7ccSmrg * Get the next available X request packet in the buffer. 259caade7ccSmrg * It sets the `length' field to the size (in 32-bit words) 260caade7ccSmrg * of the request. It also sets the `reqType' field in the 261caade7ccSmrg * request to X_TestGetInput, which is not what is needed. 262caade7ccSmrg * 263caade7ccSmrg * GetReq is a macro defined in Xlibint.h. 264caade7ccSmrg */ 265caade7ccSmrg GetReq(TestGetInput, req); 266caade7ccSmrg /* 267caade7ccSmrg * fix up the request type code to what is needed 268caade7ccSmrg */ 269caade7ccSmrg req->reqType = XTestReqCode; 270caade7ccSmrg /* 271caade7ccSmrg * set the minor request type code to X_TestGetInput 272caade7ccSmrg */ 273caade7ccSmrg req->XTestReqType = X_TestGetInput; 274caade7ccSmrg /* 275caade7ccSmrg * set the action handling mode 276caade7ccSmrg */ 277caade7ccSmrg req->mode = action_handling; 278caade7ccSmrg UnlockDisplay(dpy); 279caade7ccSmrg SyncHandle(); 280caade7ccSmrg return(0); 281caade7ccSmrg } 282caade7ccSmrg} 283caade7ccSmrg 284caade7ccSmrg/****************************************************************************** 285caade7ccSmrg * 286caade7ccSmrg * XTestStopInput 287caade7ccSmrg * 288caade7ccSmrg * Tell the server to stop putting information about user input actions 289caade7ccSmrg * into events. 290caade7ccSmrg */ 291caade7ccSmrgint 292caade7ccSmrgXTestStopInput( 293caade7ccSmrg/* 294caade7ccSmrg * the connection to the X server 295caade7ccSmrg */ 296caade7ccSmrgregister Display *dpy) 297caade7ccSmrg{ 298caade7ccSmrg /* 299caade7ccSmrg * pointer to xTestStopInputReq structure 300caade7ccSmrg */ 301caade7ccSmrg xTestStopInputReq *req; 302caade7ccSmrg 303caade7ccSmrg LockDisplay(dpy); 304caade7ccSmrg if (XTestCheckExtInit(dpy) == -1) 305caade7ccSmrg { 306caade7ccSmrg /* 307caade7ccSmrg * if the extension is not installed in the server 308caade7ccSmrg * then unlock the display and return -1. 309caade7ccSmrg */ 310caade7ccSmrg UnlockDisplay(dpy); 311caade7ccSmrg return(-1); 312caade7ccSmrg } 313caade7ccSmrg else 314caade7ccSmrg { 315caade7ccSmrg /* 316caade7ccSmrg * Get the next available X request packet in the buffer. 317caade7ccSmrg * It sets the `length' field to the size (in 32-bit words) 318caade7ccSmrg * of the request. It also sets the `reqType' field in the 319caade7ccSmrg * request to X_TestStopInput, which is not what is needed. 320caade7ccSmrg * 321caade7ccSmrg * GetReq is a macro defined in Xlibint.h. 322caade7ccSmrg */ 323caade7ccSmrg GetReq(TestStopInput, req); 324caade7ccSmrg /* 325caade7ccSmrg * fix up the request type code to what is needed 326caade7ccSmrg */ 327caade7ccSmrg req->reqType = XTestReqCode; 328caade7ccSmrg /* 329caade7ccSmrg * set the minor request type code to X_TestStopInput 330caade7ccSmrg */ 331caade7ccSmrg req->XTestReqType = X_TestStopInput; 332caade7ccSmrg UnlockDisplay(dpy); 333caade7ccSmrg SyncHandle(); 334caade7ccSmrg return(0); 335caade7ccSmrg } 336caade7ccSmrg} 337caade7ccSmrg 338caade7ccSmrg/****************************************************************************** 339caade7ccSmrg * 340caade7ccSmrg * XTestReset 341caade7ccSmrg * 342caade7ccSmrg * Tell the server to set everything having to do with this extension 343caade7ccSmrg * back to its initial state. 344caade7ccSmrg */ 345caade7ccSmrgint 346caade7ccSmrgXTestReset( 347caade7ccSmrg/* 348caade7ccSmrg * the connection to the X server 349caade7ccSmrg */ 350caade7ccSmrgregister Display *dpy) 351caade7ccSmrg{ 352caade7ccSmrg /* 353caade7ccSmrg * pointer to xTestReset structure 354caade7ccSmrg */ 355caade7ccSmrg xTestResetReq *req; 356caade7ccSmrg 357caade7ccSmrg LockDisplay(dpy); 358caade7ccSmrg if (XTestCheckExtInit(dpy) == -1) 359caade7ccSmrg { 360caade7ccSmrg /* 361caade7ccSmrg * if the extension is not installed in the server 362caade7ccSmrg * then unlock the display and return -1. 363caade7ccSmrg */ 364caade7ccSmrg UnlockDisplay(dpy); 365caade7ccSmrg return(-1); 366caade7ccSmrg } 367caade7ccSmrg else 368caade7ccSmrg { 369caade7ccSmrg /* 370caade7ccSmrg * Get the next available X request packet in the buffer. 371caade7ccSmrg * It sets the `length' field to the size (in 32-bit words) 372caade7ccSmrg * of the request. It also sets the `reqType' field in the 373caade7ccSmrg * request to X_TestReset, which is not what is needed. 374caade7ccSmrg * 375caade7ccSmrg * GetReq is a macro defined in Xlibint.h. 376caade7ccSmrg */ 377caade7ccSmrg GetReq(TestReset, req); 378caade7ccSmrg /* 379caade7ccSmrg * fix up the request type code to what is needed 380caade7ccSmrg */ 381caade7ccSmrg req->reqType = XTestReqCode; 382caade7ccSmrg /* 383caade7ccSmrg * set the minor request type code to X_TestReset 384caade7ccSmrg */ 385caade7ccSmrg req->XTestReqType = X_TestReset; 386caade7ccSmrg UnlockDisplay(dpy); 387caade7ccSmrg SyncHandle(); 388caade7ccSmrg return(0); 389caade7ccSmrg } 390caade7ccSmrg} 391caade7ccSmrg 392caade7ccSmrg/****************************************************************************** 393caade7ccSmrg * 394caade7ccSmrg * XTestQueryInputSize 395caade7ccSmrg * 396caade7ccSmrg * Returns the number of input actions in the server's input action buffer. 397caade7ccSmrg */ 398caade7ccSmrgint 399caade7ccSmrgXTestQueryInputSize( 400caade7ccSmrg/* 401caade7ccSmrg * the connection to the X server 402caade7ccSmrg */ 403caade7ccSmrgregister Display *dpy, 404caade7ccSmrg/* 405caade7ccSmrg * the address of the place to put the number of input actions in the 406caade7ccSmrg * server's input action buffer 407caade7ccSmrg */ 408caade7ccSmrgunsigned long *size_return) 409caade7ccSmrg{ 410caade7ccSmrg /* 411caade7ccSmrg * pointer to xTestQueryInputSize structure 412caade7ccSmrg */ 413caade7ccSmrg xTestQueryInputSizeReq *req; 414caade7ccSmrg /* 415caade7ccSmrg * pointer to xTestQueryInputSize structure 416caade7ccSmrg */ 417caade7ccSmrg xTestQueryInputSizeReply rep; 418caade7ccSmrg 419caade7ccSmrg LockDisplay(dpy); 420caade7ccSmrg if (XTestCheckExtInit(dpy) == -1) 421caade7ccSmrg { 422caade7ccSmrg /* 423caade7ccSmrg * if the extension is not installed in the server 424caade7ccSmrg * then unlock the display and return -1. 425caade7ccSmrg */ 426caade7ccSmrg UnlockDisplay(dpy); 427caade7ccSmrg return(-1); 428caade7ccSmrg } 429caade7ccSmrg else 430caade7ccSmrg { 431caade7ccSmrg /* 432caade7ccSmrg * Get the next available X request packet in the buffer. 433caade7ccSmrg * It sets the `length' field to the size (in 32-bit words) 434caade7ccSmrg * of the request. It also sets the `reqType' field in the 435caade7ccSmrg * request to X_TestQueryInputSize, which is not what is needed. 436caade7ccSmrg * 437caade7ccSmrg * GetReq is a macro defined in Xlibint.h. 438caade7ccSmrg */ 439caade7ccSmrg GetReq(TestQueryInputSize, req); 440caade7ccSmrg /* 441caade7ccSmrg * fix up the request type code to what is needed 442caade7ccSmrg */ 443caade7ccSmrg req->reqType = XTestReqCode; 444caade7ccSmrg /* 445caade7ccSmrg * set the minor request type code to X_TestQueryInputSize 446caade7ccSmrg */ 447caade7ccSmrg req->XTestReqType = X_TestQueryInputSize; 448caade7ccSmrg /* 449caade7ccSmrg * get a reply from the server 450caade7ccSmrg */ 451caade7ccSmrg (void) _XReply (dpy, (xReply *) &rep, 0, xTrue); 452caade7ccSmrg /* 453caade7ccSmrg * put the size in the caller's variable 454caade7ccSmrg */ 455caade7ccSmrg *size_return = (unsigned long) rep.size_return; 456caade7ccSmrg UnlockDisplay(dpy); 457caade7ccSmrg SyncHandle(); 458caade7ccSmrg return(0); 459caade7ccSmrg } 460caade7ccSmrg} 461caade7ccSmrg 462caade7ccSmrg/****************************************************************************** 463caade7ccSmrg * 464caade7ccSmrg * XTestCheckExtInit 465caade7ccSmrg * 466caade7ccSmrg * Check to see if the XTest extension is installed in the server. 467caade7ccSmrg */ 468caade7ccSmrgstatic int 469caade7ccSmrgXTestCheckExtInit( 470caade7ccSmrg/* 471caade7ccSmrg * the connection to the X server 472caade7ccSmrg */ 473caade7ccSmrgregister Display *dpy) 474caade7ccSmrg{ 475caade7ccSmrg /* 476caade7ccSmrg * if the extension has not been initialized, then do so 477caade7ccSmrg */ 478caade7ccSmrg if (!XTestReqCode) 479caade7ccSmrg { 480caade7ccSmrg return(XTestInitExtension(dpy)); 481caade7ccSmrg } 482caade7ccSmrg return(0); 483caade7ccSmrg} 484caade7ccSmrg 485caade7ccSmrg/****************************************************************************** 486caade7ccSmrg * 487caade7ccSmrg * XTestInitExtension 488caade7ccSmrg * 489caade7ccSmrg * Attempt to initialize this extension in the server. Return 0 if it 490caade7ccSmrg * succeeds, -1 if it does not succeed. 491caade7ccSmrg */ 492caade7ccSmrgstatic int 493caade7ccSmrgXTestInitExtension( 494caade7ccSmrg/* 495caade7ccSmrg * the connection to the X server 496caade7ccSmrg */ 497caade7ccSmrgregister Display *dpy) 498caade7ccSmrg{ 499caade7ccSmrg /* 500caade7ccSmrg * loop index 501caade7ccSmrg */ 502caade7ccSmrg int i; 503caade7ccSmrg /* 504caade7ccSmrg * return value from XInitExtension 505caade7ccSmrg */ 506caade7ccSmrg XExtCodes *ret; 507caade7ccSmrg 508caade7ccSmrg /* 509caade7ccSmrg * attempt to initialize the extension 510caade7ccSmrg */ 511caade7ccSmrg ret = XInitExtension(dpy, XTestEXTENSION_NAME); 512caade7ccSmrg /* 513caade7ccSmrg * if the initialize failed, return -1 514caade7ccSmrg */ 515caade7ccSmrg if (ret == NULL) 516caade7ccSmrg { 517caade7ccSmrg return (-1); 518caade7ccSmrg } 519caade7ccSmrg /* 520caade7ccSmrg * the initialize succeeded, remember the major opcode 521caade7ccSmrg * for this extension 522caade7ccSmrg */ 523caade7ccSmrg XTestReqCode = ret->major_opcode; 524caade7ccSmrg /* 525caade7ccSmrg * set up the event handler for any events from 526caade7ccSmrg * this extension 527caade7ccSmrg */ 528caade7ccSmrg for (i = 0; i < XTestEVENT_COUNT; i++) 529caade7ccSmrg { 530caade7ccSmrg XESetWireToEvent(dpy, 531caade7ccSmrg ret->first_event+i, 532caade7ccSmrg XTestWireToEvent); 533caade7ccSmrg } 534caade7ccSmrg /* 535caade7ccSmrg * compute the event type codes for the events 536caade7ccSmrg * in this extension 537caade7ccSmrg */ 538caade7ccSmrg XTestInputActionType += ret->first_event; 539caade7ccSmrg XTestFakeAckType += ret->first_event; 540caade7ccSmrg /* 541caade7ccSmrg * everything worked ok 542caade7ccSmrg */ 543caade7ccSmrg return(0); 544caade7ccSmrg} 545caade7ccSmrg 546caade7ccSmrg/****************************************************************************** 547caade7ccSmrg * 548caade7ccSmrg * XTestWireToEvent 549caade7ccSmrg * 550caade7ccSmrg * Handle XTest extension events. 551caade7ccSmrg * Reformat a wire event into an XEvent structure of the right type. 552caade7ccSmrg */ 553caade7ccSmrgstatic Bool 554caade7ccSmrgXTestWireToEvent( 555caade7ccSmrg/* 556caade7ccSmrg * the connection to the X server 557caade7ccSmrg */ 558caade7ccSmrgDisplay *dpy, 559caade7ccSmrg/* 560caade7ccSmrg * a pointer to where a host formatted event should be stored 561caade7ccSmrg * with the information copied to it 562caade7ccSmrg */ 563caade7ccSmrgXEvent *reTemp, 564caade7ccSmrg/* 565caade7ccSmrg * a pointer to the wire event 566caade7ccSmrg */ 567caade7ccSmrgxEvent *eventTemp) 568caade7ccSmrg{ 569caade7ccSmrg XTestInputActionEvent *re = (XTestInputActionEvent *) reTemp; 570caade7ccSmrg xTestInputActionEvent *event = (xTestInputActionEvent *) eventTemp; 571caade7ccSmrg 572caade7ccSmrg /* 573caade7ccSmrg * loop index 574caade7ccSmrg */ 575caade7ccSmrg int i; 576caade7ccSmrg /* 577caade7ccSmrg * pointer to where the input actions go in the host format event 578caade7ccSmrg */ 579caade7ccSmrg CARD8 *to; 580caade7ccSmrg /* 581caade7ccSmrg * pointer to the input actions in the wire event 582caade7ccSmrg */ 583caade7ccSmrg CARD8 *from; 584caade7ccSmrg 585caade7ccSmrg /* 586caade7ccSmrg * Copy the type of the wire event to the new event. 587caade7ccSmrg * This will work for either event type because the type, 588caade7ccSmrg * display, and window fields in the events have to be the same. 589caade7ccSmrg */ 590caade7ccSmrg re->type = event->type; 591caade7ccSmrg /* 592caade7ccSmrg * set the display parameter in case it is needed (by who?) 593caade7ccSmrg */ 594caade7ccSmrg re->display = dpy; 595caade7ccSmrg if (re->type == XTestInputActionType) 596caade7ccSmrg { 597caade7ccSmrg /* 598caade7ccSmrg * point at the first byte of input actions in the wire event 599caade7ccSmrg */ 600caade7ccSmrg from = &(event->actions[0]); 601caade7ccSmrg /* 602caade7ccSmrg * point at where the input action bytes go in the new event 603caade7ccSmrg */ 604caade7ccSmrg to = &(re->actions[0]); 605caade7ccSmrg /* 606caade7ccSmrg * copy the input action bytes from the wire event to 607caade7ccSmrg * the new event 608caade7ccSmrg */ 609caade7ccSmrg for (i = 0; i < XTestACTIONS_SIZE; i++) 610caade7ccSmrg { 611caade7ccSmrg *(to++) = *(from++); 612caade7ccSmrg } 613caade7ccSmrg } 614caade7ccSmrg else if (re->type == XTestFakeAckType) 615caade7ccSmrg { 616caade7ccSmrg /* 617caade7ccSmrg * nothing else needs to be done 618caade7ccSmrg */ 619caade7ccSmrg } 620caade7ccSmrg else 621caade7ccSmrg { 622caade7ccSmrg printf("XTestWireToEvent: UNKNOWN WIRE EVENT! type=%d\n", 623caade7ccSmrg (int) event->type); 624caade7ccSmrg printf("%s is giving up.\n", XTestEXTENSION_NAME); 625caade7ccSmrg exit (1); 626caade7ccSmrg } 627caade7ccSmrg return 1; 628caade7ccSmrg} 629caade7ccSmrg 630caade7ccSmrg/****************************************************************************** 631caade7ccSmrg * 632caade7ccSmrg * XTestPressKey 633caade7ccSmrg * 634caade7ccSmrg * Send input actions to the server to cause the server to think 635caade7ccSmrg * that the specified key on the keyboard was moved as specified. 636caade7ccSmrg */ 637caade7ccSmrgint 638caade7ccSmrgXTestPressKey( 639caade7ccSmrgDisplay *display, 640caade7ccSmrgint device_id, 641caade7ccSmrgunsigned long delay, 642caade7ccSmrgunsigned int keycode, 643caade7ccSmrgunsigned int key_action) 644caade7ccSmrg{ 645caade7ccSmrg /* 646caade7ccSmrg * bounds check the key code 647caade7ccSmrg */ 648caade7ccSmrg if (keycode < 8 || keycode > 255) 649caade7ccSmrg { 650caade7ccSmrg return(-1); 651caade7ccSmrg } 652caade7ccSmrg /* 653caade7ccSmrg * use the commmon key/button handling routine 654caade7ccSmrg */ 655caade7ccSmrg return(XTestKeyOrButton(display, 656caade7ccSmrg device_id, 657caade7ccSmrg delay, 658caade7ccSmrg keycode, 659caade7ccSmrg key_action)); 660caade7ccSmrg} 661caade7ccSmrg 662caade7ccSmrg/****************************************************************************** 663caade7ccSmrg * 664caade7ccSmrg * XTestPressButton 665caade7ccSmrg * 666caade7ccSmrg * Send input actions to the server to cause the server to think 667caade7ccSmrg * that the specified button on the mouse was moved as specified. 668caade7ccSmrg */ 669caade7ccSmrgint 670caade7ccSmrgXTestPressButton( 671caade7ccSmrgDisplay *display, 672caade7ccSmrgint device_id, 673caade7ccSmrgunsigned long delay, 674caade7ccSmrgunsigned int button_number, 675caade7ccSmrgunsigned int button_action) 676caade7ccSmrg{ 677caade7ccSmrg /* 678caade7ccSmrg * bounds check the button number 679caade7ccSmrg */ 680caade7ccSmrg if (button_number > 7) 681caade7ccSmrg { 682caade7ccSmrg return(-1); 683caade7ccSmrg } 684caade7ccSmrg /* 685caade7ccSmrg * use the commmon key/button handling routine 686caade7ccSmrg */ 687caade7ccSmrg return(XTestKeyOrButton(display, 688caade7ccSmrg device_id, 689caade7ccSmrg delay, 690caade7ccSmrg button_number, 691caade7ccSmrg button_action)); 692caade7ccSmrg} 693caade7ccSmrg 694caade7ccSmrg/****************************************************************************** 695caade7ccSmrg * 696caade7ccSmrg * XTestKeyOrButton 697caade7ccSmrg * 698caade7ccSmrg * Send input actions to the server to cause the server to think 699caade7ccSmrg * that the specified key/button was moved as specified. 700caade7ccSmrg */ 701caade7ccSmrgstatic int 702caade7ccSmrgXTestKeyOrButton( 703caade7ccSmrgDisplay *display, 704caade7ccSmrgint device_id, 705caade7ccSmrgunsigned long delay, 706caade7ccSmrgunsigned int code, 707caade7ccSmrgunsigned int action) 708caade7ccSmrg{ 709caade7ccSmrg /* 710caade7ccSmrg * holds a key input action to be filled out and sent to the server 711caade7ccSmrg */ 712caade7ccSmrg XTestKeyInfo keyinfo; 713caade7ccSmrg 714caade7ccSmrg /* 715caade7ccSmrg * bounds check the device id 716caade7ccSmrg */ 717caade7ccSmrg if (device_id < 0 || device_id > XTestMAX_DEVICE_ID) 718caade7ccSmrg { 719caade7ccSmrg return(-1); 720caade7ccSmrg } 721caade7ccSmrg /* 722caade7ccSmrg * fill out the key input action(s) as appropriate 723caade7ccSmrg */ 724caade7ccSmrg switch(action) 725caade7ccSmrg { 726caade7ccSmrg case XTestPRESS: 727caade7ccSmrg /* 728caade7ccSmrg * Check the delay. If it is larger than will fit in the 729caade7ccSmrg * key input action, send a delay input action. 730caade7ccSmrg */ 731caade7ccSmrg if(XTestCheckDelay(display, &delay) == -1) 732caade7ccSmrg { 733caade7ccSmrg /* 734caade7ccSmrg * an error occurred, return -1 735caade7ccSmrg */ 736caade7ccSmrg return(-1); 737caade7ccSmrg } 738caade7ccSmrg /* 739caade7ccSmrg * create the header 740caade7ccSmrg */ 741caade7ccSmrg keyinfo.header = XTestPackDeviceID(device_id) | 742caade7ccSmrg XTestKEY_ACTION | 743caade7ccSmrg XTestKEY_DOWN; 744caade7ccSmrg /* 745caade7ccSmrg * set the key/button code 746caade7ccSmrg */ 747caade7ccSmrg keyinfo.keycode = code; 748caade7ccSmrg /* 749caade7ccSmrg * set the delay time 750caade7ccSmrg */ 751caade7ccSmrg keyinfo.delay_time = delay; 752caade7ccSmrg /* 753caade7ccSmrg * pack the input action into a request to be sent to the 754caade7ccSmrg * server when the request is full or XTestFlush is called 755caade7ccSmrg */ 756caade7ccSmrg return(XTestPackInputAction(display, 757caade7ccSmrg (CARD8 *) &keyinfo, 758caade7ccSmrg sizeof(XTestKeyInfo))); 759caade7ccSmrg case XTestRELEASE: 760caade7ccSmrg /* 761caade7ccSmrg * Check the delay. If it is larger than will fit in the 762caade7ccSmrg * key input action, send a delay input action. 763caade7ccSmrg */ 764caade7ccSmrg if(XTestCheckDelay(display, &delay) == -1) 765caade7ccSmrg { 766caade7ccSmrg /* 767caade7ccSmrg * an error occurred, return -1 768caade7ccSmrg */ 769caade7ccSmrg return(-1); 770caade7ccSmrg } 771caade7ccSmrg /* 772caade7ccSmrg * create the header 773caade7ccSmrg */ 774caade7ccSmrg keyinfo.header = XTestPackDeviceID(device_id) | 775caade7ccSmrg XTestKEY_ACTION | 776caade7ccSmrg XTestKEY_UP; 777caade7ccSmrg /* 778caade7ccSmrg * set the key/button code 779caade7ccSmrg */ 780caade7ccSmrg keyinfo.keycode = code; 781caade7ccSmrg /* 782caade7ccSmrg * set the delay time 783caade7ccSmrg */ 784caade7ccSmrg keyinfo.delay_time = delay; 785caade7ccSmrg /* 786caade7ccSmrg * pack the input action into a request to be sent to the 787caade7ccSmrg * server when the request is full or XTestFlush is called 788caade7ccSmrg */ 789caade7ccSmrg return(XTestPackInputAction(display, 790caade7ccSmrg (CARD8 *) &keyinfo, 791caade7ccSmrg sizeof(XTestKeyInfo))); 792caade7ccSmrg case XTestSTROKE: 793caade7ccSmrg /* 794caade7ccSmrg * Check the delay. If it is larger than will fit in the 795caade7ccSmrg * key input action, send a delay input action. 796caade7ccSmrg */ 797caade7ccSmrg if(XTestCheckDelay(display, &delay) == -1) 798caade7ccSmrg { 799caade7ccSmrg /* 800caade7ccSmrg * an error occurred, return -1 801caade7ccSmrg */ 802caade7ccSmrg return(-1); 803caade7ccSmrg } 804caade7ccSmrg /* 805caade7ccSmrg * create a key/button-down input action header 806caade7ccSmrg */ 807caade7ccSmrg keyinfo.header = XTestPackDeviceID(device_id) | 808caade7ccSmrg XTestKEY_ACTION | 809caade7ccSmrg XTestKEY_DOWN; 810caade7ccSmrg /* 811caade7ccSmrg * set the key/button code 812caade7ccSmrg */ 813caade7ccSmrg keyinfo.keycode = code; 814caade7ccSmrg /* 815caade7ccSmrg * set the delay time 816caade7ccSmrg */ 817caade7ccSmrg keyinfo.delay_time = delay; 818caade7ccSmrg /* 819caade7ccSmrg * pack the input action into a request to be sent to the 820caade7ccSmrg * server when the request is full or XTestFlush is called 821caade7ccSmrg */ 822caade7ccSmrg if (XTestPackInputAction(display, 823caade7ccSmrg (CARD8 *) &keyinfo, 824caade7ccSmrg sizeof(XTestKeyInfo)) == -1) 825caade7ccSmrg { 826caade7ccSmrg /* 827caade7ccSmrg * an error occurred, return -1 828caade7ccSmrg */ 829caade7ccSmrg return(-1); 830caade7ccSmrg } 831caade7ccSmrg /* 832caade7ccSmrg * set the delay to XTestSTROKE_DELAY_TIME 833caade7ccSmrg */ 834caade7ccSmrg delay = XTestSTROKE_DELAY_TIME; 835caade7ccSmrg /* 836caade7ccSmrg * Check the delay. If it is larger than will fit in the 837caade7ccSmrg * key input action, send a delay input action. 838caade7ccSmrg */ 839caade7ccSmrg if(XTestCheckDelay(display, &delay) == -1) 840caade7ccSmrg { 841caade7ccSmrg /* 842caade7ccSmrg * an error occurred, return -1 843caade7ccSmrg */ 844caade7ccSmrg return(-1); 845caade7ccSmrg } 846caade7ccSmrg /* 847caade7ccSmrg * create a key/button-up input action header 848caade7ccSmrg */ 849caade7ccSmrg keyinfo.header = XTestPackDeviceID(device_id) | 850caade7ccSmrg XTestKEY_ACTION | 851caade7ccSmrg XTestKEY_UP; 852caade7ccSmrg /* 853caade7ccSmrg * set the key/button code 854caade7ccSmrg */ 855caade7ccSmrg keyinfo.keycode = code; 856caade7ccSmrg /* 857caade7ccSmrg * set the delay time 858caade7ccSmrg */ 859caade7ccSmrg keyinfo.delay_time = delay; 860caade7ccSmrg /* 861caade7ccSmrg * pack the input action into a request to be sent to the 862caade7ccSmrg * server when the request is full or XTestFlush is called 863caade7ccSmrg */ 864caade7ccSmrg return(XTestPackInputAction(display, 865caade7ccSmrg (CARD8 *) &keyinfo, 866caade7ccSmrg sizeof(XTestKeyInfo))); 867caade7ccSmrg default: 868caade7ccSmrg /* 869caade7ccSmrg * invalid action value, return -1 870caade7ccSmrg */ 871caade7ccSmrg return(-1); 872caade7ccSmrg } 873caade7ccSmrg} 874caade7ccSmrg 875caade7ccSmrg/****************************************************************************** 876caade7ccSmrg * 877caade7ccSmrg * XTestMovePointer 878caade7ccSmrg * 879caade7ccSmrg * Send input actions to the server to cause the server to think 880caade7ccSmrg * that the mouse was moved as specified. 881caade7ccSmrg */ 882caade7ccSmrgint 883caade7ccSmrgXTestMovePointer( 884caade7ccSmrgDisplay *display, 885caade7ccSmrgint device_id, 886caade7ccSmrgunsigned long delay[], 887caade7ccSmrgint x[], 888caade7ccSmrgint y[], 889caade7ccSmrgunsigned int count) 890caade7ccSmrg{ 891caade7ccSmrg /* 892caade7ccSmrg * holds a motion input action to be filled out and sent to the server 893caade7ccSmrg */ 894caade7ccSmrg XTestMotionInfo motioninfo; 895caade7ccSmrg /* 896caade7ccSmrg * holds a jump input action to be filled out and sent to the server 897caade7ccSmrg */ 898caade7ccSmrg XTestJumpInfo jumpinfo; 899caade7ccSmrg /* 900caade7ccSmrg * loop index 901caade7ccSmrg */ 902caade7ccSmrg unsigned int i; 903caade7ccSmrg /* 904caade7ccSmrg * holds the change in x and y directions from the current x and y 905caade7ccSmrg * coordinates 906caade7ccSmrg */ 907caade7ccSmrg int dx; 908caade7ccSmrg int dy; 909caade7ccSmrg 910caade7ccSmrg /* 911caade7ccSmrg * bounds check the device id 912caade7ccSmrg */ 913caade7ccSmrg if (device_id < 0 || device_id > XTestMAX_DEVICE_ID) 914caade7ccSmrg { 915caade7ccSmrg return(-1); 916caade7ccSmrg } 917caade7ccSmrg /* 918caade7ccSmrg * if the count is 0, there is nothing to do. return 0 919caade7ccSmrg */ 920caade7ccSmrg if (count == 0) 921caade7ccSmrg { 922caade7ccSmrg return(0); 923caade7ccSmrg } 924caade7ccSmrg /* 925caade7ccSmrg * loop through the pointer motions, creating the appropriate 926caade7ccSmrg * input actions for each motion 927caade7ccSmrg */ 928caade7ccSmrg for (i = 0; i < count; i++) 929caade7ccSmrg { 930caade7ccSmrg /* 931caade7ccSmrg * Check the delay. If it is larger than will fit in the 932caade7ccSmrg * input action, send a delay input action. 933caade7ccSmrg */ 934caade7ccSmrg if(XTestCheckDelay(display, &(delay[i])) == -1) 935caade7ccSmrg { 936caade7ccSmrg /* 937caade7ccSmrg * an error occurred, return -1 938caade7ccSmrg */ 939caade7ccSmrg return(-1); 940caade7ccSmrg } 941caade7ccSmrg /* 942caade7ccSmrg * compute the change from the current x and y coordinates 943caade7ccSmrg * to the new x and y coordinates 944caade7ccSmrg */ 945caade7ccSmrg dx = x[i] - current_x; 946caade7ccSmrg dy = y[i] - current_y; 947caade7ccSmrg /* 948caade7ccSmrg * update the current x and y coordinates 949caade7ccSmrg */ 950caade7ccSmrg current_x = x[i]; 951caade7ccSmrg current_y = y[i]; 952caade7ccSmrg /* 953caade7ccSmrg * If the pointer motion range is too large to fit into 954caade7ccSmrg * a motion input action, then use a jump input action. 955caade7ccSmrg * Otherwise, use a motion input action. 956caade7ccSmrg */ 957caade7ccSmrg if ((dx > XTestMOTION_MAX) || (dx < XTestMOTION_MIN) || 958caade7ccSmrg (dy > XTestMOTION_MAX) || (dy < XTestMOTION_MIN)) 959caade7ccSmrg { 960caade7ccSmrg /* 961caade7ccSmrg * create a jump input action header 962caade7ccSmrg */ 963caade7ccSmrg jumpinfo.header = XTestPackDeviceID(device_id) | 964caade7ccSmrg XTestJUMP_ACTION; 965caade7ccSmrg /* 966caade7ccSmrg * set the x and y coordinates to jump to 967caade7ccSmrg */ 968caade7ccSmrg jumpinfo.jumpx = x[i]; 969caade7ccSmrg jumpinfo.jumpy = y[i]; 970caade7ccSmrg /* 971caade7ccSmrg * set the delay time 972caade7ccSmrg */ 973caade7ccSmrg jumpinfo.delay_time = delay[i]; 974caade7ccSmrg /* 975caade7ccSmrg * pack the jump input action into a request to be 976caade7ccSmrg * sent to the server when the request is full 977caade7ccSmrg * or XTestFlush is called 978caade7ccSmrg */ 979caade7ccSmrg if (XTestPackInputAction(display, 980caade7ccSmrg (CARD8 *) &jumpinfo, 981caade7ccSmrg sizeof(XTestJumpInfo)) == -1) 982caade7ccSmrg { 983caade7ccSmrg /* 984caade7ccSmrg * an error occurred, return -1 985caade7ccSmrg */ 986caade7ccSmrg return(-1); 987caade7ccSmrg } 988caade7ccSmrg } 989caade7ccSmrg else 990caade7ccSmrg { 991caade7ccSmrg /* 992caade7ccSmrg * create a motion input action header 993caade7ccSmrg */ 994caade7ccSmrg motioninfo.header = XTestPackDeviceID(device_id) | 995caade7ccSmrg XTestMOTION_ACTION; 996caade7ccSmrg /* 997caade7ccSmrg * compute the motion data byte 998caade7ccSmrg */ 999caade7ccSmrg if (dx < 0) 1000caade7ccSmrg { 1001caade7ccSmrg motioninfo.header |= XTestX_NEGATIVE; 1002caade7ccSmrg dx = abs(dx); 1003caade7ccSmrg } 1004caade7ccSmrg if (dy < 0) 1005caade7ccSmrg { 1006caade7ccSmrg motioninfo.header |= XTestY_NEGATIVE; 1007caade7ccSmrg dy = abs(dy); 1008caade7ccSmrg } 1009caade7ccSmrg motioninfo.motion_data = XTestPackXMotionValue(dx); 1010caade7ccSmrg motioninfo.motion_data |= XTestPackYMotionValue(dy); 1011caade7ccSmrg /* 1012caade7ccSmrg * set the delay time 1013caade7ccSmrg */ 1014caade7ccSmrg motioninfo.delay_time = delay[i]; 1015caade7ccSmrg /* 1016caade7ccSmrg * pack the motion input action into a request to be 1017caade7ccSmrg * sent to the server when the request is full 1018caade7ccSmrg * or XTestFlush is called 1019caade7ccSmrg */ 1020caade7ccSmrg if (XTestPackInputAction(display, 1021caade7ccSmrg (CARD8 *) &motioninfo, 1022caade7ccSmrg sizeof(XTestMotionInfo)) == -1) 1023caade7ccSmrg { 1024caade7ccSmrg /* 1025caade7ccSmrg * an error occurred, return -1 1026caade7ccSmrg */ 1027caade7ccSmrg return(-1); 1028caade7ccSmrg } 1029caade7ccSmrg } 1030caade7ccSmrg } 1031caade7ccSmrg /* 1032caade7ccSmrg * if you get here, everything went ok 1033caade7ccSmrg */ 1034caade7ccSmrg return(0); 1035caade7ccSmrg} 1036caade7ccSmrg 1037caade7ccSmrg/****************************************************************************** 1038caade7ccSmrg * 1039caade7ccSmrg * XTestCheckDelay 1040caade7ccSmrg * 1041caade7ccSmrg * Check the delay value at the passed-in address. If it is larger than 1042caade7ccSmrg * will fit in a normal input action, then send a delay input action. 1043caade7ccSmrg */ 1044caade7ccSmrgstatic int 1045caade7ccSmrgXTestCheckDelay( 1046caade7ccSmrgDisplay *display, 1047caade7ccSmrgunsigned long *delay_addr) 1048caade7ccSmrg{ 1049caade7ccSmrg /* 1050caade7ccSmrg * holds a delay input action to be filled out and sent to the server 1051caade7ccSmrg */ 1052caade7ccSmrg XTestDelayInfo delayinfo; 1053caade7ccSmrg 1054caade7ccSmrg /* 1055caade7ccSmrg * if the delay value will fit in the input action, 1056caade7ccSmrg * then there is no need for a delay input action 1057caade7ccSmrg */ 1058caade7ccSmrg if (*delay_addr <= XTestSHORT_DELAY_TIME) 1059caade7ccSmrg { 1060caade7ccSmrg return(0); 1061caade7ccSmrg } 1062caade7ccSmrg /* 1063caade7ccSmrg * fill out a delay input action 1064caade7ccSmrg */ 1065caade7ccSmrg delayinfo.header = XTestPackDeviceID(XTestDELAY_DEVICE_ID); 1066caade7ccSmrg delayinfo.delay_time = *delay_addr; 1067caade7ccSmrg /* 1068caade7ccSmrg * all of the delay time will be accounted for in the 1069caade7ccSmrg * delay input action, so set the original delay value to 0 1070caade7ccSmrg */ 1071caade7ccSmrg *delay_addr = 0; 1072caade7ccSmrg /* 1073caade7ccSmrg * pack the delay input action into a request to be sent to the 1074caade7ccSmrg * server when the request is full or XTestFlush is called 1075caade7ccSmrg */ 1076caade7ccSmrg return(XTestPackInputAction(display, 1077caade7ccSmrg (CARD8 *) &delayinfo, 1078caade7ccSmrg sizeof(XTestDelayInfo))); 1079caade7ccSmrg} 1080caade7ccSmrg 1081caade7ccSmrg/****************************************************************************** 1082caade7ccSmrg * 1083caade7ccSmrg * XTestPackInputAction 1084caade7ccSmrg * 1085caade7ccSmrg * If the input action buffer is full or the number of input actions 1086caade7ccSmrg * has reached the maximum that the server can handle at one time, 1087caade7ccSmrg * then send the input actions to the server using XTestFakeInput. 1088caade7ccSmrg */ 1089caade7ccSmrgstatic int 1090caade7ccSmrgXTestPackInputAction( 1091caade7ccSmrgDisplay *display, 1092caade7ccSmrgCARD8 *action_addr, 1093caade7ccSmrgint action_size) 1094caade7ccSmrg{ 1095caade7ccSmrg /* 1096caade7ccSmrg * loop index 1097caade7ccSmrg */ 1098caade7ccSmrg int i; 1099caade7ccSmrg /* 1100caade7ccSmrg * acknowledge flag 1101caade7ccSmrg */ 1102caade7ccSmrg int ack_flag; 1103caade7ccSmrg 1104caade7ccSmrg /* 1105caade7ccSmrg * if we don't already know it, find out how many input actions 1106caade7ccSmrg * the server can handle at one time 1107caade7ccSmrg */ 1108caade7ccSmrg if (action_array_size == 0) 1109caade7ccSmrg { 1110caade7ccSmrg if(XTestQueryInputSize(display, &action_array_size) == -1) 1111caade7ccSmrg { 1112caade7ccSmrg /* 1113caade7ccSmrg * if an error, return -1 1114caade7ccSmrg */ 1115caade7ccSmrg return(-1); 1116caade7ccSmrg } 1117caade7ccSmrg } 1118caade7ccSmrg /* 1119caade7ccSmrg * if the specified input action will fit in the the input 1120caade7ccSmrg * action buffer and won't exceed the server's capacity, then 1121caade7ccSmrg * put the input action into the input buffer 1122caade7ccSmrg */ 1123caade7ccSmrg if(((action_index + action_size) <= XTestMAX_ACTION_LIST_SIZE) && 1124caade7ccSmrg ((action_count + 1) < action_array_size)) 1125caade7ccSmrg { 1126caade7ccSmrg /* 1127caade7ccSmrg * copy the input action into the buffer 1128caade7ccSmrg */ 1129caade7ccSmrg for (i = 0; i < action_size; i++) 1130caade7ccSmrg { 1131caade7ccSmrg action_buf[action_index++] = *(action_addr++); 1132caade7ccSmrg } 1133caade7ccSmrg /* 1134caade7ccSmrg * increment the action count 1135caade7ccSmrg */ 1136caade7ccSmrg action_count++; 1137caade7ccSmrg /* 1138caade7ccSmrg * everything went ok, return 0 1139caade7ccSmrg */ 1140caade7ccSmrg return(0); 1141caade7ccSmrg } 1142caade7ccSmrg /* 1143caade7ccSmrg * We have to write input actions to the server. If the server's 1144caade7ccSmrg * input action capacity will be reached, then ask for an 1145caade7ccSmrg * acknowledge event when the server has processed all of the 1146caade7ccSmrg * input actions. Otherwise, an acknowledge event is not needed. 1147caade7ccSmrg */ 1148caade7ccSmrg if (action_count >= action_array_size) 1149caade7ccSmrg { 1150caade7ccSmrg ack_flag = XTestFAKE_ACK_REQUEST; 1151caade7ccSmrg } 1152caade7ccSmrg else 1153caade7ccSmrg { 1154caade7ccSmrg ack_flag = XTestFAKE_ACK_NOT_NEEDED; 1155caade7ccSmrg } 1156caade7ccSmrg /* 1157caade7ccSmrg * write the input actions to the server 1158caade7ccSmrg */ 1159caade7ccSmrg if (XTestWriteInputActions(display, 1160caade7ccSmrg (char *) &(action_buf[0]), 1161caade7ccSmrg action_index, 1162caade7ccSmrg ack_flag) == -1) 1163caade7ccSmrg { 1164caade7ccSmrg /* 1165caade7ccSmrg * error, return -1 1166caade7ccSmrg */ 1167caade7ccSmrg return(-1); 1168caade7ccSmrg } 1169caade7ccSmrg /* 1170caade7ccSmrg * copy the input action into the buffer 1171caade7ccSmrg */ 1172caade7ccSmrg for (i = 0; i < action_size; i++) 1173caade7ccSmrg { 1174caade7ccSmrg action_buf[action_index++] = *(action_addr++); 1175caade7ccSmrg } 1176caade7ccSmrg /* 1177caade7ccSmrg * increment the action count 1178caade7ccSmrg */ 1179caade7ccSmrg action_count++; 1180caade7ccSmrg return(0); 1181caade7ccSmrg} 1182caade7ccSmrg 1183caade7ccSmrg/****************************************************************************** 1184caade7ccSmrg * 1185caade7ccSmrg * XTestWriteInputActions 1186caade7ccSmrg * 1187caade7ccSmrg * Send input actions to the server. 1188caade7ccSmrg */ 1189caade7ccSmrgstatic int 1190caade7ccSmrgXTestWriteInputActions( 1191caade7ccSmrgDisplay *display, 1192caade7ccSmrgchar *action_list_addr, 1193caade7ccSmrgint action_list_size, 1194caade7ccSmrgint ack_flag) 1195caade7ccSmrg{ 1196caade7ccSmrg /* 1197caade7ccSmrg * Holds an event. Used while waiting for an acknowledge event 1198caade7ccSmrg */ 1199caade7ccSmrg XEvent event; 1200caade7ccSmrg /* 1201caade7ccSmrg * points to XTestIdentifyMyEvent 1202caade7ccSmrg */ 1203caade7ccSmrg Bool (*func_ptr)(Display *, XEvent *, XPointer); 1204caade7ccSmrg 1205caade7ccSmrg /* 1206caade7ccSmrg * write the input actions to the server 1207caade7ccSmrg */ 1208caade7ccSmrg if (XTestFakeInput(display, 1209caade7ccSmrg action_list_addr, 1210caade7ccSmrg action_list_size, 1211caade7ccSmrg ack_flag) == -1) 1212caade7ccSmrg { 1213caade7ccSmrg /* 1214caade7ccSmrg * if an error, return -1 1215caade7ccSmrg */ 1216caade7ccSmrg return(-1); 1217caade7ccSmrg } 1218caade7ccSmrg /* 1219caade7ccSmrg * flush X's buffers to make sure that the server really gets 1220caade7ccSmrg * the input actions 1221caade7ccSmrg */ 1222caade7ccSmrg XFlush(display); 1223caade7ccSmrg /* 1224caade7ccSmrg * mark the input action buffer as empty 1225caade7ccSmrg */ 1226caade7ccSmrg action_index = 0; 1227caade7ccSmrg /* 1228caade7ccSmrg * if we asked for an acknowledge event, then wait for it 1229caade7ccSmrg */ 1230caade7ccSmrg if (ack_flag == XTestFAKE_ACK_REQUEST) 1231caade7ccSmrg { 1232caade7ccSmrg /* 1233caade7ccSmrg * point func_ptr at XTestIdentifyMyEvent 1234caade7ccSmrg */ 1235caade7ccSmrg func_ptr = XTestIdentifyMyEvent; 1236caade7ccSmrg /* 1237caade7ccSmrg * Wait until the acknowledge event comes. When the 1238caade7ccSmrg * acknowledge event comes, it is removed from the event 1239caade7ccSmrg * queue without disturbing any other events that might 1240caade7ccSmrg * be in the queue. 1241caade7ccSmrg */ 1242caade7ccSmrg XIfEvent(display, &event, func_ptr, NULL); 1243caade7ccSmrg /* 1244caade7ccSmrg * set the input action count back to 0 1245caade7ccSmrg */ 1246caade7ccSmrg action_count = 0; 1247caade7ccSmrg } 1248caade7ccSmrg /* 1249caade7ccSmrg * if we got here, then everything is ok, return 0 1250caade7ccSmrg */ 1251caade7ccSmrg return(0); 1252caade7ccSmrg} 1253caade7ccSmrg 1254caade7ccSmrg/****************************************************************************** 1255caade7ccSmrg * 1256caade7ccSmrg * XTestIdentifyMyEvent 1257caade7ccSmrg * 1258caade7ccSmrg * This function is called by XIfEvent to look at an event and see if 1259caade7ccSmrg * it is of XTestFakeAckType. 1260caade7ccSmrg */ 1261caade7ccSmrgstatic Bool 1262caade7ccSmrgXTestIdentifyMyEvent( 1263caade7ccSmrgDisplay *display, 1264caade7ccSmrg/* 1265caade7ccSmrg * Holds the event that this routine is supposed to look at. 1266caade7ccSmrg */ 1267caade7ccSmrgXEvent *event_ptr, 1268caade7ccSmrg/* 1269caade7ccSmrg * this points to any user-specified arguments (ignored) 1270caade7ccSmrg */ 1271caade7ccSmrgchar *args) 1272caade7ccSmrg{ 1273caade7ccSmrg /* 1274caade7ccSmrg * if the event if of the correct type, return the Bool True, 1275caade7ccSmrg * otherwise return the Bool False. 1276caade7ccSmrg */ 1277caade7ccSmrg if (event_ptr->type == XTestFakeAckType) 1278caade7ccSmrg { 1279caade7ccSmrg return(True); 1280caade7ccSmrg } 1281caade7ccSmrg else 1282caade7ccSmrg { 1283caade7ccSmrg return(False); 1284caade7ccSmrg } 1285caade7ccSmrg} 1286caade7ccSmrg 1287caade7ccSmrg/****************************************************************************** 1288caade7ccSmrg * 1289caade7ccSmrg * XTestFlush 1290caade7ccSmrg * 1291caade7ccSmrg * Send any input actions in the input action buffer to the server. 1292caade7ccSmrg */ 1293caade7ccSmrgint 1294caade7ccSmrgXTestFlush(Display *display) 1295caade7ccSmrg{ 1296caade7ccSmrg /* 1297caade7ccSmrg * acknowledge flag 1298caade7ccSmrg */ 1299caade7ccSmrg int ack_flag; 1300caade7ccSmrg 1301caade7ccSmrg /* 1302caade7ccSmrg * if there are no input actions in the input action buffer, 1303caade7ccSmrg * then return 0 1304caade7ccSmrg */ 1305caade7ccSmrg if (action_index == 0) 1306caade7ccSmrg { 1307caade7ccSmrg return(0); 1308caade7ccSmrg } 1309caade7ccSmrg /* 1310caade7ccSmrg * We have input actions to write to the server. We will 1311caade7ccSmrg * wait until the server has finished processing the input actions. 1312caade7ccSmrg */ 1313caade7ccSmrg ack_flag = XTestFAKE_ACK_REQUEST; 1314caade7ccSmrg /* 1315caade7ccSmrg * write the input actions to the server 1316caade7ccSmrg */ 1317caade7ccSmrg return(XTestWriteInputActions(display, 1318caade7ccSmrg (char *) &(action_buf[0]), 1319caade7ccSmrg action_index, 1320caade7ccSmrg ack_flag)); 1321caade7ccSmrg} 1322