Bug Summary

File:XTestExt1.c
Location:line 1127, column 31
Description:Assigned value is garbage or undefined

Annotated Source Code

1/*
2 * File: xtestext1lib.c
3 *
4 * This file contains the Xlib parts of the input synthesis extension
5 */
6
7/*
8
9
10Copyright 1986, 1987, 1988, 1998 The Open Group
11
12Permission to use, copy, modify, distribute, and sell this software and its
13documentation for any purpose is hereby granted without fee, provided that
14the above copyright notice appear in all copies and that both that
15copyright notice and this permission notice appear in supporting
16documentation.
17
18The above copyright notice and this permission notice shall be included in
19all copies or substantial portions of the Software.
20
21THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
25AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28Except as contained in this notice, the name of The Open Group shall not be
29used in advertising or otherwise to promote the sale, use or other dealings
30in this Software without prior written authorization from The Open Group.
31
32
33Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
34
35Permission to use, copy, modify, and distribute this
36software and its documentation for any purpose and without
37fee is hereby granted, provided that the above copyright
38notice appear in all copies and that both that copyright
39notice and this permission notice appear in supporting
40documentation, and that the name of Hewlett-Packard not be used in
41advertising or publicity pertaining to distribution of the
42software without specific, written prior permission.
43
44Hewlett-Packard makes no representations about the
45suitability of this software for any purpose. It is provided
46"as is" without express or implied warranty.
47
48This software is not subject to any license of the American
49Telephone and Telegraph Company or of the Regents of the
50University 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 */
77static 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 */
86int XTestInputActionType = 0;
87int XTestFakeAckType = 1;
88/*
89 * holds the current x and y coordinates for XTestMovePointer
90 */
91static int current_x = 0;
92static 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 */
97static CARD8 action_buf[XTestMAX_ACTION_LIST_SIZE64];
98/*
99 * the index into the input action buffer
100 */
101static int action_index = 0;
102/*
103 * the number of input actions that the server can handle at one time
104 */
105static unsigned long action_array_size = 0;
106/*
107 * the current number of input actions
108 */
109static unsigned long action_count = 0;
110
111/******************************************************************************
112 * function declarations
113 *****************************************************************************/
114
115static int XTestWireToEvent(Display *dpy, XEvent *reTemp, xEvent *eventTemp);
116static int XTestCheckExtInit(register Display *dpy);
117static Boolint XTestIdentifyMyEvent(Display *display, XEvent *event_ptr, char *args);
118static int XTestInitExtension(register Display *dpy);
119static int XTestKeyOrButton(Display *display, int device_id, long unsigned int delay, unsigned int code, unsigned int action);
120static int XTestCheckDelay(Display *display, long unsigned int *delay_addr);
121static int XTestPackInputAction(Display *display, CARD8 *action_addr, int action_size);
122static 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 */
131int
132XTestFakeInput(
133/*
134 * the connection to the X server
135 */
136register Display *dpy,
137/*
138 * the address of a list of input actions to be sent to the server
139 */
140char *action_list_addr,
141/*
142 * the size (in bytes) of the list of input actions
143 */
144int 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 */
149int 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 */
225int
226XTestGetInput(
227/*
228 * the connection to the X server
229 */
230register Display *dpy,
231/*
232 * tells the server what to do with the user input actions
233 */
234int 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 */
287int
288XTestStopInput(
289/*
290 * the connection to the X server
291 */
292register 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 */
341int
342XTestReset(
343/*
344 * the connection to the X server
345 */
346register 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 */
394int
395XTestQueryInputSize(
396/*
397 * the connection to the X server
398 */
399register 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 */
404unsigned 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 */
464static int
465XTestCheckExtInit(
466/*
467 * the connection to the X server
468 */
469register 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 */
488static int
489XTestInitExtension(
490/*
491 * the connection to the X server
492 */
493register 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 */
549static Boolint
550XTestWireToEvent(
551/*
552 * the connection to the X server
553 */
554Display *dpy,
555/*
556 * a pointer to where a host formatted event should be stored
557 * with the information copied to it
558 */
559XEvent *reTemp,
560/*
561 * a pointer to the wire event
562 */
563xEvent *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 */
633int
634XTestPressKey(
635Display *display,
636int device_id,
637unsigned long delay,
638unsigned int keycode,
639unsigned 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 */
665int
666XTestPressButton(
667Display *display,
668int device_id,
669unsigned long delay,
670unsigned int button_number,
671unsigned 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 */
697static int
698XTestKeyOrButton(
699Display *display,
700int device_id,
701unsigned long delay,
702unsigned int code,
703unsigned 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 */
878int
879XTestMovePointer(
880Display *display,
881int device_id,
882unsigned long delay[],
883int x[],
884int y[],
885unsigned 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)
1
Assuming 'device_id' is >= 0
2
Assuming 'device_id' is <= 15
3
Taking false branch
910 {
911 return(-1);
912 }
913 /*
914 * if the count is 0, there is nothing to do. return 0
915 */
916 if (count == 0)
4
Assuming 'count' is not equal to 0
5
Taking false branch
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++)
6
Loop condition is true. Entering loop body
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)
7
Calling 'XTestCheckDelay'
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 */
1040static int
1041XTestCheckDelay(
1042Display *display,
1043unsigned 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)
8
Taking false branch
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,
9
Calling 'XTestPackInputAction'
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 */
1085static int
1086XTestPackInputAction(
1087Display *display,
1088CARD8 *action_addr,
1089int 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)
10
Assuming 'action_array_size' is not equal to 0
11
Taking false branch
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) &&
12
Taking true branch
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++)
13
Loop condition is true. Entering loop body
14
Loop condition is true. Entering loop body
1126 {
1127 action_buf[action_index++] = *(action_addr++);
15
Assigned value is garbage or undefined
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 */
1185static int
1186XTestWriteInputActions(
1187Display *display,
1188char *action_list_addr,
1189int action_list_size,
1190int 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 */
1257static Boolint
1258XTestIdentifyMyEvent(
1259Display *display,
1260/*
1261 * Holds the event that this routine is supposed to look at.
1262 */
1263XEvent *event_ptr,
1264/*
1265 * this points to any user-specified arguments (ignored)
1266 */
1267char *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 */
1289int
1290XTestFlush(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}