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