home *** CD-ROM | disk | FTP | other *** search
/ PC Shareware 1999 March / PCShareware-3-99.iso / IMPLE / DJGPP.RAR / DJGPP2 / XLIB-SR0.ZIP / SRC / EXTENSIO / XTESTEXT.C < prev    next >
C/C++ Source or Header  |  1991-01-24  |  29KB  |  1,291 lines

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