4 * This file contains the Xlib parts of the input synthesis extension
10 Copyright 1986, 1987, 1988, 1998 The Open Group
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
18 The above copyright notice and this permission notice shall be included in
19 all copies or substantial portions of the Software.
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.
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.
33 Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
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.
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.
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.
54 /******************************************************************************
56 *****************************************************************************/
62 #include <X11/Xproto.h>
63 #include <X11/Xlibint.h>
64 #include <X11/extensions/xtestext1.h>
65 #include <X11/extensions/xtestext1proto.h>
67 /******************************************************************************
69 *****************************************************************************/
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.
77 static int XTestReqCode = 0;
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.
84 * These two variables must be available to programs that use this extension.
86 int XTestInputActionType = 0;
87 int XTestFakeAckType = 1;
89 * holds the current x and y coordinates for XTestMovePointer
91 static int current_x = 0;
92 static int current_y = 0;
94 * Holds input actions being accumulated until the input action buffer is
95 * full or until XTestFlush is called.
97 static CARD8 action_buf[XTestMAX_ACTION_LIST_SIZE];
99 * the index into the input action buffer
101 static int action_index = 0;
103 * the number of input actions that the server can handle at one time
105 static unsigned long action_array_size = 0;
107 * the current number of input actions
109 static unsigned long action_count = 0;
111 /******************************************************************************
112 * function declarations
113 *****************************************************************************/
115 static int XTestWireToEvent(Display *dpy, XEvent *reTemp, xEvent *eventTemp);
116 static int XTestCheckExtInit(register Display *dpy);
117 static Bool 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);
124 /******************************************************************************
128 * Send a a request containing one or more input actions to be sent
129 * to the server by this extension.
134 * the connection to the X server
136 register Display *dpy,
138 * the address of a list of input actions to be sent to the server
140 char *action_list_addr,
142 * the size (in bytes) of the list of input actions
144 int action_list_size,
146 * specifies whether the server needs to send an event to indicate that its
147 * input action buffer is empty
152 * pointer to xTestFakeInputReq structure
154 xTestFakeInputReq *req;
161 if ((XTestCheckExtInit(dpy) == -1) ||
162 (action_list_size > XTestMAX_ACTION_LIST_SIZE))
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.
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.
180 * GetReq is a macro defined in Xlibint.h.
182 GetReq(TestFakeInput, req);
184 * fix up the request type code to what is needed
186 req->reqType = XTestReqCode;
188 * set the minor request type code to X_TestFakeInput
190 req->XTestReqType = X_TestFakeInput;
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.
201 for (i = 0; i < XTestMAX_ACTION_LIST_SIZE; i++)
203 req->action_list[i] = 0;
206 * copy the input actions into the request
208 for (i = 0; i < action_list_size; i++)
210 req->action_list[i] = *(action_list_addr++);
218 /******************************************************************************
222 * Request the server to begin putting user input actions into events
223 * to be sent to the client that called this function.
228 * the connection to the X server
230 register Display *dpy,
232 * tells the server what to do with the user input actions
237 * pointer to xTestGetInputReq structure
239 xTestGetInputReq *req;
242 if (XTestCheckExtInit(dpy) == -1)
245 * if the extension is not installed in the server
246 * then unlock the display and return -1.
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.
259 * GetReq is a macro defined in Xlibint.h.
261 GetReq(TestGetInput, req);
263 * fix up the request type code to what is needed
265 req->reqType = XTestReqCode;
267 * set the minor request type code to X_TestGetInput
269 req->XTestReqType = X_TestGetInput;
271 * set the action handling mode
273 req->mode = action_handling;
280 /******************************************************************************
284 * Tell the server to stop putting information about user input actions
290 * the connection to the X server
292 register Display *dpy)
295 * pointer to xTestStopInputReq structure
297 xTestStopInputReq *req;
300 if (XTestCheckExtInit(dpy) == -1)
303 * if the extension is not installed in the server
304 * then unlock the display and return -1.
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.
317 * GetReq is a macro defined in Xlibint.h.
319 GetReq(TestStopInput, req);
321 * fix up the request type code to what is needed
323 req->reqType = XTestReqCode;
325 * set the minor request type code to X_TestStopInput
327 req->XTestReqType = X_TestStopInput;
334 /******************************************************************************
338 * Tell the server to set everything having to do with this extension
339 * back to its initial state.
344 * the connection to the X server
346 register Display *dpy)
349 * pointer to xTestReset structure
354 if (XTestCheckExtInit(dpy) == -1)
357 * if the extension is not installed in the server
358 * then unlock the display and return -1.
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.
371 * GetReq is a macro defined in Xlibint.h.
373 GetReq(TestReset, req);
375 * fix up the request type code to what is needed
377 req->reqType = XTestReqCode;
379 * set the minor request type code to X_TestReset
381 req->XTestReqType = X_TestReset;
388 /******************************************************************************
390 * XTestQueryInputSize
392 * Returns the number of input actions in the server's input action buffer.
397 * the connection to the X server
399 register Display *dpy,
401 * the address of the place to put the number of input actions in the
402 * server's input action buffer
404 unsigned long *size_return)
407 * pointer to xTestQueryInputSize structure
409 xTestQueryInputSizeReq *req;
411 * pointer to xTestQueryInputSize structure
413 xTestQueryInputSizeReply rep;
416 if (XTestCheckExtInit(dpy) == -1)
419 * if the extension is not installed in the server
420 * then unlock the display and return -1.
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.
433 * GetReq is a macro defined in Xlibint.h.
435 GetReq(TestQueryInputSize, req);
437 * fix up the request type code to what is needed
439 req->reqType = XTestReqCode;
441 * set the minor request type code to X_TestQueryInputSize
443 req->XTestReqType = X_TestQueryInputSize;
445 * get a reply from the server
447 (void) _XReply (dpy, (xReply *) &rep, 0, xTrue);
449 * put the size in the caller's variable
451 *size_return = (unsigned long) rep.size_return;
458 /******************************************************************************
462 * Check to see if the XTest extension is installed in the server.
467 * the connection to the X server
469 register Display *dpy)
472 * if the extension has not been initialized, then do so
476 return(XTestInitExtension(dpy));
481 /******************************************************************************
485 * Attempt to initialize this extension in the server. Return 0 if it
486 * succeeds, -1 if it does not succeed.
491 * the connection to the X server
493 register Display *dpy)
500 * return value from XInitExtension
505 * attempt to initialize the extension
507 ret = XInitExtension(dpy, XTestEXTENSION_NAME);
509 * if the initialize failed, return -1
516 * the initialize succeeded, remember the major opcode
519 XTestReqCode = ret->major_opcode;
521 * set up the event handler for any events from
524 for (i = 0; i < XTestEVENT_COUNT; i++)
526 XESetWireToEvent(dpy,
531 * compute the event type codes for the events
534 XTestInputActionType += ret->first_event;
535 XTestFakeAckType += ret->first_event;
537 * everything worked ok
542 /******************************************************************************
546 * Handle XTest extension events.
547 * Reformat a wire event into an XEvent structure of the right type.
552 * the connection to the X server
556 * a pointer to where a host formatted event should be stored
557 * with the information copied to it
561 * a pointer to the wire event
565 XTestInputActionEvent *re = (XTestInputActionEvent *) reTemp;
566 xTestInputActionEvent *event = (xTestInputActionEvent *) eventTemp;
573 * pointer to where the input actions go in the host format event
577 * pointer to the input actions in the wire event
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.
586 re->type = event->type;
588 * set the display parameter in case it is needed (by who?)
591 if (re->type == XTestInputActionType)
594 * point at the first byte of input actions in the wire event
596 from = &(event->actions[0]);
598 * point at where the input action bytes go in the new event
600 to = &(re->actions[0]);
602 * copy the input action bytes from the wire event to
605 for (i = 0; i < XTestACTIONS_SIZE; i++)
610 else if (re->type == XTestFakeAckType)
613 * nothing else needs to be done
618 printf("XTestWireToEvent: UNKNOWN WIRE EVENT! type=%d\n",
620 printf("%s is giving up.\n", XTestEXTENSION_NAME);
626 /******************************************************************************
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.
638 unsigned int keycode,
639 unsigned int key_action)
642 * bounds check the key code
644 if (keycode < 8 || keycode > 255)
649 * use the commmon key/button handling routine
651 return(XTestKeyOrButton(display,
658 /******************************************************************************
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.
670 unsigned int button_number,
671 unsigned int button_action)
674 * bounds check the button number
676 if (button_number > 7)
681 * use the commmon key/button handling routine
683 return(XTestKeyOrButton(display,
690 /******************************************************************************
694 * Send input actions to the server to cause the server to think
695 * that the specified key/button was moved as specified.
706 * holds a key input action to be filled out and sent to the server
708 XTestKeyInfo keyinfo;
711 * bounds check the device id
713 if (device_id < 0 || device_id > XTestMAX_DEVICE_ID)
718 * fill out the key input action(s) as appropriate
724 * Check the delay. If it is larger than will fit in the
725 * key input action, send a delay input action.
727 if(XTestCheckDelay(display, &delay) == -1)
730 * an error occurred, return -1
737 keyinfo.header = XTestPackDeviceID(device_id) |
741 * set the key/button code
743 keyinfo.keycode = code;
747 keyinfo.delay_time = delay;
749 * pack the input action into a request to be sent to the
750 * server when the request is full or XTestFlush is called
752 return(XTestPackInputAction(display,
754 sizeof(XTestKeyInfo)));
757 * Check the delay. If it is larger than will fit in the
758 * key input action, send a delay input action.
760 if(XTestCheckDelay(display, &delay) == -1)
763 * an error occurred, return -1
770 keyinfo.header = XTestPackDeviceID(device_id) |
774 * set the key/button code
776 keyinfo.keycode = code;
780 keyinfo.delay_time = delay;
782 * pack the input action into a request to be sent to the
783 * server when the request is full or XTestFlush is called
785 return(XTestPackInputAction(display,
787 sizeof(XTestKeyInfo)));
790 * Check the delay. If it is larger than will fit in the
791 * key input action, send a delay input action.
793 if(XTestCheckDelay(display, &delay) == -1)
796 * an error occurred, return -1
801 * create a key/button-down input action header
803 keyinfo.header = XTestPackDeviceID(device_id) |
807 * set the key/button code
809 keyinfo.keycode = code;
813 keyinfo.delay_time = delay;
815 * pack the input action into a request to be sent to the
816 * server when the request is full or XTestFlush is called
818 if (XTestPackInputAction(display,
820 sizeof(XTestKeyInfo)) == -1)
823 * an error occurred, return -1
828 * set the delay to XTestSTROKE_DELAY_TIME
830 delay = XTestSTROKE_DELAY_TIME;
832 * Check the delay. If it is larger than will fit in the
833 * key input action, send a delay input action.
835 if(XTestCheckDelay(display, &delay) == -1)
838 * an error occurred, return -1
843 * create a key/button-up input action header
845 keyinfo.header = XTestPackDeviceID(device_id) |
849 * set the key/button code
851 keyinfo.keycode = code;
855 keyinfo.delay_time = delay;
857 * pack the input action into a request to be sent to the
858 * server when the request is full or XTestFlush is called
860 return(XTestPackInputAction(display,
862 sizeof(XTestKeyInfo)));
865 * invalid action value, return -1
871 /******************************************************************************
875 * Send input actions to the server to cause the server to think
876 * that the mouse was moved as specified.
882 unsigned long delay[],
888 * holds a motion input action to be filled out and sent to the server
890 XTestMotionInfo motioninfo;
892 * holds a jump input action to be filled out and sent to the server
894 XTestJumpInfo jumpinfo;
900 * holds the change in x and y directions from the current x and y
907 * bounds check the device id
909 if (device_id < 0 || device_id > XTestMAX_DEVICE_ID)
914 * if the count is 0, there is nothing to do. return 0
921 * loop through the pointer motions, creating the appropriate
922 * input actions for each motion
924 for (i = 0; i < count; i++)
927 * Check the delay. If it is larger than will fit in the
928 * input action, send a delay input action.
930 if(XTestCheckDelay(display, &(delay[i])) == -1)
933 * an error occurred, return -1
938 * compute the change from the current x and y coordinates
939 * to the new x and y coordinates
941 dx = x[i] - current_x;
942 dy = y[i] - current_y;
944 * update the current x and y coordinates
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.
953 if ((dx > XTestMOTION_MAX) || (dx < XTestMOTION_MIN) ||
954 (dy > XTestMOTION_MAX) || (dy < XTestMOTION_MIN))
957 * create a jump input action header
959 jumpinfo.header = XTestPackDeviceID(device_id) |
962 * set the x and y coordinates to jump to
964 jumpinfo.jumpx = x[i];
965 jumpinfo.jumpy = y[i];
969 jumpinfo.delay_time = delay[i];
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
975 if (XTestPackInputAction(display,
977 sizeof(XTestJumpInfo)) == -1)
980 * an error occurred, return -1
988 * create a motion input action header
990 motioninfo.header = XTestPackDeviceID(device_id) |
993 * compute the motion data byte
997 motioninfo.header |= XTestX_NEGATIVE;
1002 motioninfo.header |= XTestY_NEGATIVE;
1005 motioninfo.motion_data = XTestPackXMotionValue(dx);
1006 motioninfo.motion_data |= XTestPackYMotionValue(dy);
1008 * set the delay time
1010 motioninfo.delay_time = delay[i];
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
1016 if (XTestPackInputAction(display,
1017 (CARD8 *) &motioninfo,
1018 sizeof(XTestMotionInfo)) == -1)
1021 * an error occurred, return -1
1028 * if you get here, everything went ok
1033 /******************************************************************************
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.
1043 unsigned long *delay_addr)
1046 * holds a delay input action to be filled out and sent to the server
1048 XTestDelayInfo delayinfo;
1051 * if the delay value will fit in the input action,
1052 * then there is no need for a delay input action
1054 if (*delay_addr <= XTestSHORT_DELAY_TIME)
1059 * fill out a delay input action
1061 delayinfo.header = XTestPackDeviceID(XTestDELAY_DEVICE_ID);
1062 delayinfo.delay_time = *delay_addr;
1064 * all of the delay time will be accounted for in the
1065 * delay input action, so set the original delay value to 0
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
1072 return(XTestPackInputAction(display,
1073 (CARD8 *) &delayinfo,
1074 sizeof(XTestDelayInfo)));
1077 /******************************************************************************
1079 * XTestPackInputAction
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.
1086 XTestPackInputAction(
1101 * if we don't already know it, find out how many input actions
1102 * the server can handle at one time
1104 if (action_array_size == 0)
1106 if(XTestQueryInputSize(display, &action_array_size) == -1)
1109 * if an error, return -1
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
1119 if(((action_index + action_size) <= XTestMAX_ACTION_LIST_SIZE) &&
1120 ((action_count + 1) < action_array_size))
1123 * copy the input action into the buffer
1125 for (i = 0; i < action_size; i++)
1127 action_buf[action_index++] = *(action_addr++);
1130 * increment the action count
1134 * everything went ok, return 0
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.
1144 if (action_count >= action_array_size)
1146 ack_flag = XTestFAKE_ACK_REQUEST;
1150 ack_flag = XTestFAKE_ACK_NOT_NEEDED;
1153 * write the input actions to the server
1155 if (XTestWriteInputActions(display,
1156 (char *) &(action_buf[0]),
1166 * copy the input action into the buffer
1168 for (i = 0; i < action_size; i++)
1170 action_buf[action_index++] = *(action_addr++);
1173 * increment the action count
1179 /******************************************************************************
1181 * XTestWriteInputActions
1183 * Send input actions to the server.
1186 XTestWriteInputActions(
1188 char *action_list_addr,
1189 int action_list_size,
1193 * Holds an event. Used while waiting for an acknowledge event
1197 * points to XTestIdentifyMyEvent
1199 Bool (*func_ptr)(Display *, XEvent *, XPointer);
1202 * write the input actions to the server
1204 if (XTestFakeInput(display,
1210 * if an error, return -1
1215 * flush X's buffers to make sure that the server really gets
1220 * mark the input action buffer as empty
1224 * if we asked for an acknowledge event, then wait for it
1226 if (ack_flag == XTestFAKE_ACK_REQUEST)
1229 * point func_ptr at XTestIdentifyMyEvent
1231 func_ptr = XTestIdentifyMyEvent;
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
1238 XIfEvent(display, &event, func_ptr, NULL);
1240 * set the input action count back to 0
1245 * if we got here, then everything is ok, return 0
1250 /******************************************************************************
1252 * XTestIdentifyMyEvent
1254 * This function is called by XIfEvent to look at an event and see if
1255 * it is of XTestFakeAckType.
1258 XTestIdentifyMyEvent(
1261 * Holds the event that this routine is supposed to look at.
1265 * this points to any user-specified arguments (ignored)
1270 * if the event if of the correct type, return the Bool True,
1271 * otherwise return the Bool False.
1273 if (event_ptr->type == XTestFakeAckType)
1283 /******************************************************************************
1287 * Send any input actions in the input action buffer to the server.
1290 XTestFlush(Display *display)
1298 * if there are no input actions in the input action buffer,
1301 if (action_index == 0)
1306 * We have input actions to write to the server. We will
1307 * wait until the server has finished processing the input actions.
1309 ack_flag = XTestFAKE_ACK_REQUEST;
1311 * write the input actions to the server
1313 return(XTestWriteInputActions(display,
1314 (char *) &(action_buf[0]),