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