home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / extensions / server / xtest1di.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-12  |  21.2 KB  |  935 lines

  1. /*
  2.  *    File:  xtest1di.c
  3.  *
  4.  *    This file contains the device independent parts of the input
  5.  *    synthesis extension.
  6.  */
  7.  
  8. /*
  9.  
  10. Copyright 1986, 1987, 1988 by Hewlett-Packard Corporation
  11. Copyright 1986, 1987, 1988 by the Massachusetts Institute of Technology
  12.  
  13. Permission to use, copy, modify, and distribute this
  14. software and its documentation for any purpose and without
  15. fee is hereby granted, provided that the above copyright
  16. notice appear in all copies and that both that copyright
  17. notice and this permission notice appear in supporting
  18. documentation, and that the name of M.I.T. not be used in
  19. advertising or publicity pertaining to distribution of the
  20. software without specific, written prior permission.
  21.  
  22. Hewlett-Packard and M.I.T. make no representations about the 
  23. suitability of this software for any purpose.  It is provided 
  24. "as is" without express or implied warranty.
  25.  
  26. This software is not subject to any license of the American
  27. Telephone and Telegraph Company or of the Regents of the
  28. University of California.
  29.  
  30. */
  31.  
  32. /*****************************************************************************
  33.  * include files
  34.  ****************************************************************************/
  35.  
  36. #define     NEED_EVENTS
  37. #define     NEED_REPLIES
  38.  
  39. #include <stdio.h>
  40. #include "X.h"
  41. #include "Xproto.h"
  42. #include "misc.h"
  43. #include "os.h"
  44. #include "gcstruct.h"   
  45. #include "extnsionst.h"
  46. #include "dixstruct.h"
  47. #include "opaque.h"
  48. #define  XTestSERVER_SIDE
  49. #include "xtestext1.h"
  50.  
  51. /*****************************************************************************
  52.  * defines
  53.  ****************************************************************************/
  54.  
  55. /*****************************************************************************
  56.  * externals
  57.  ****************************************************************************/
  58.  
  59. /*
  60.  * holds the addresses of the routines that handle byte-swapping of replys
  61.  */
  62. extern void        (* ReplySwapVector[256]) ();
  63. /*
  64.  * holds the addresses of the routines that handle byte-swapping of events
  65.  */
  66. extern void        (* EventSwapVector[128]) ();
  67. /*
  68.  * id of client using XTestGetInput
  69.  *
  70.  * defined in xtest1dd.c
  71.  */
  72. extern ClientPtr    current_xtest_client;
  73. /*
  74.  * id of client using XTestFakeInput
  75.  *
  76.  * defined in xtest1dd.c
  77.  */
  78. extern ClientPtr    playback_client;
  79.  
  80. /*****************************************************************************
  81.  * variables
  82.  ****************************************************************************/
  83.  
  84. /*
  85.  * Holds the request type code for this extension.  The request type code
  86.  * for this extension may vary depending on how many extensions are installed
  87.  * already, so the initial value given below will be added to the base request
  88.  * code that is aquired when this extension is installed.
  89.  */
  90. static int         XTestReqCode = 0;
  91. /*
  92.  * Holds the two event type codes for this extension.  The event type codes
  93.  * for this extension may vary depending on how many extensions are installed
  94.  * already, so the initial values given below will be added to the base event
  95.  * code that is aquired when this extension is installed.
  96.  */
  97. int             XTestInputActionType = 0;
  98. int             XTestFakeAckType = 1;
  99. /*
  100.  * true => monitor stealing input
  101.  */
  102. int            on_steal_input = FALSE;
  103. /*
  104.  * true => monitor alone getting input
  105.  */
  106. int            exclusive_steal = FALSE;
  107. /*
  108.  * holds the resource type assigned to this extension
  109.  */
  110. static RESTYPE        XTestType;
  111. /*
  112.  * holds the resource ID for the client currently using XTestGetInput
  113.  */
  114. static XID        current_client_id;
  115.  
  116. /*****************************************************************************
  117.  * function declarations
  118.  ****************************************************************************/
  119.  
  120. static int    ProcXTestDispatch();
  121. static int    SProcXTestDispatch();
  122. static void    XTestResetProc();
  123. static int    ProcTestFakeInput();
  124. static int    SProcTestFakeInput();
  125. static int    ProcTestGetInput();
  126. static int    SProcTestGetInput();
  127. static int    ProcTestStopInput();
  128. static int    SProcTestStopInput();
  129. static int    ProcTestReset();
  130. static int    SProcTestReset();
  131. static int    ProcTestQueryInputSize();
  132. static int    SProcTestQueryInputSize();
  133. static void    SReplyXTestDispatch();
  134. static void    SEventXTestDispatch();
  135. void    NotImplemented();
  136.  
  137. void    abort_play_back();
  138. void    return_input_array_size();
  139. void    steal_input();
  140. void    stop_stealing_input();
  141. void    flush_input_actions();
  142. void    parse_fake_input();
  143.  
  144. static void    XTestCurrentClientGone();
  145.  
  146. /*****************************************************************************
  147.  *
  148.  *    XTestExtension1Init
  149.  *
  150.  *    Called from InitExtensions in main() or from QueryExtension() if the
  151.  *    extension is dynamically loaded.
  152.  *
  153.  *    XTestExtension1Init has no events or errors
  154.  *    (other than the core errors).
  155.  */
  156. void
  157. XTestExtension1Init()
  158. {
  159.     /*
  160.      * holds the pointer to the extension entry structure
  161.      */
  162.     ExtensionEntry    *extEntry;
  163.     /*
  164.      * This routine adds the extension to the server extension table.
  165.      */
  166.     ExtensionEntry    *AddExtension();
  167.  
  168.     extEntry = AddExtension(XTestEXTENSION_NAME,
  169.                 XTestEVENT_COUNT,
  170.                 0,
  171.                 ProcXTestDispatch,
  172.                 SProcXTestDispatch,
  173.                 XTestResetProc,
  174.                 StandardMinorOpcode);
  175.     if (extEntry)
  176.     {
  177.         /*
  178.          * remember the request code assigned to this extension
  179.          */
  180.         XTestReqCode = extEntry->base;
  181.         /*
  182.          * make an atom saying that this extension is present
  183.          */
  184.         (void) MakeAtom(XTestEXTENSION_NAME,
  185.                 strlen(XTestEXTENSION_NAME),
  186.                 TRUE);
  187.         /*
  188.          * remember the event codes assigned to this extension
  189.          */
  190.         XTestInputActionType += extEntry->eventBase;
  191.         XTestFakeAckType += extEntry->eventBase;
  192.         /*
  193.          * install the routine to handle byte-swapping the replies
  194.          * for this extension in the ReplySwapVector table
  195.          */
  196.         ReplySwapVector[XTestReqCode] = SReplyXTestDispatch;
  197.         /*
  198.          * install the routine to handle byte-swapping the events
  199.          * for this extension in the EventSwapVector table
  200.          */
  201.         EventSwapVector[XTestInputActionType] = SEventXTestDispatch;
  202.         EventSwapVector[XTestFakeAckType] = SEventXTestDispatch;
  203.         /*
  204.          * get the resource type for this extension
  205.          */
  206.         XTestType = CreateNewResourceType(XTestCurrentClientGone);
  207.         if (XTestType == 0)
  208.         {
  209.             FatalError("XTestExtension1Init: CreateNewResourceType failed\n");
  210.         }
  211.     } 
  212.     else 
  213.     {
  214.         FatalError("XTestExtension1Init: AddExtensions failed\n");
  215.     }
  216. }
  217.  
  218. /*****************************************************************************
  219.  *
  220.  *    ProcXTestDispatch
  221.  *
  222.  *
  223.  */
  224. static int
  225. ProcXTestDispatch(client)
  226.     register ClientPtr    client;
  227. {
  228.     REQUEST(xReq);
  229.     if (stuff->data == X_TestFakeInput)
  230.     {
  231.         return(ProcTestFakeInput(client));
  232.     }
  233.     else if (stuff->data == X_TestGetInput)
  234.     {
  235.         return(ProcTestGetInput(client));
  236.     }
  237.     else if (stuff->data == X_TestStopInput)
  238.     {
  239.         return(ProcTestStopInput(client));
  240.     }
  241.     else if (stuff->data == X_TestReset)
  242.     {
  243.         return(ProcTestReset(client));
  244.     }
  245.     else if (stuff->data == X_TestQueryInputSize)
  246.     {
  247.         return(ProcTestQueryInputSize(client));
  248.     }
  249.     else
  250.     {
  251.         SendErrorToClient(client,
  252.                   XTestReqCode,
  253.                   stuff->data,
  254.                   None,
  255.                   BadRequest);
  256.         return(BadRequest);
  257.     }
  258. }
  259.  
  260. /*****************************************************************************
  261.  *
  262.  *    SProcXTestDispatch
  263.  *
  264.  *
  265.  */
  266. static int
  267. SProcXTestDispatch(client)
  268.     register ClientPtr    client;
  269. {
  270.     REQUEST(xReq);
  271.     if (stuff->data == X_TestFakeInput)
  272.     {
  273.         return(SProcTestFakeInput(client));
  274.     }
  275.     else if (stuff->data == X_TestGetInput)
  276.     {
  277.         return(SProcTestGetInput(client));
  278.     }
  279.     else if (stuff->data == X_TestStopInput)
  280.     {
  281.         return(SProcTestStopInput(client));
  282.     }
  283.     else if (stuff->data == X_TestReset)
  284.     {
  285.         return(SProcTestReset(client));
  286.     }
  287.     else if (stuff->data == X_TestQueryInputSize)
  288.     {
  289.         return(SProcTestQueryInputSize(client));
  290.     }
  291.     else
  292.     {
  293.         SendErrorToClient(client,
  294.                   XTestReqCode,
  295.                   stuff->data,
  296.                   None,
  297.                   BadRequest);
  298.         return(BadRequest);
  299.     }
  300. }
  301.  
  302. /*****************************************************************************
  303.  *
  304.  *    SProcTestFakeInput
  305.  *
  306.  *
  307.  */
  308. static int
  309. SProcTestFakeInput(client)
  310.     register ClientPtr    client;
  311. {
  312.     /*
  313.      * used in the swaps and swapl macros for temporary storage space
  314.      */
  315.     register char    n;
  316.     /*
  317.      * index counter
  318.      */
  319.     int        i;
  320.     /*
  321.      * pointer to the next input action in the request
  322.      */
  323.     CARD8        *input_action_ptr;
  324.     /*
  325.      * holds the type of the next input action in the request
  326.      */
  327.     int        input_action_type;
  328.  
  329.     REQUEST(xTestFakeInputReq);
  330.     /*
  331.      * byte-swap the fields in the request
  332.      */
  333.     swaps(&stuff->length, n);
  334.     swapl(&stuff->ack, n);
  335.     /*
  336.      * have to parse and then byte-swap the input action list here
  337.      */
  338.     for (i = 0; i < XTestMAX_ACTION_LIST_SIZE;)
  339.     {
  340.         /*
  341.          * point to the next input action in the request
  342.          */
  343.         input_action_ptr = &(((xTestFakeInputReq *) stuff)->action_list[i]);
  344.         /*
  345.          * figure out what type of input action it is
  346.          */
  347.         input_action_type = (*input_action_ptr) & XTestACTION_TYPE_MASK;
  348.         /*
  349.          * byte-swap the input action according to it's type
  350.          */
  351.         switch (input_action_type)
  352.         {
  353.         case XTestKEY_ACTION:
  354.             /*
  355.              * byte-swap the delay_time field
  356.              */
  357.             swaps(&(((XTestKeyInfo *) input_action_ptr)->delay_time), n);
  358.             /*
  359.              * advance to the next input action
  360.              */
  361.             i += sizeof(XTestKeyInfo);
  362.             break;
  363.         case XTestMOTION_ACTION:
  364.             /*
  365.              * byte-swap the delay_time field
  366.              */
  367.             swaps(&(((XTestMotionInfo *) input_action_ptr)->delay_time), n);
  368.             /*
  369.              * advance to the next input action
  370.              */
  371.             i += sizeof(XTestMotionInfo);
  372.             break;
  373.         case XTestJUMP_ACTION:
  374.             /*
  375.              * byte-swap the jumpx field
  376.              */
  377.             swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpx), n);
  378.             /*
  379.              * byte-swap the jumpy field
  380.              */
  381.             swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpy), n);
  382.             /*
  383.              * byte-swap the delay_time field
  384.              */
  385.             swaps(&(((XTestJumpInfo *) input_action_ptr)->delay_time), n);
  386.             /*
  387.              * advance to the next input action
  388.              */
  389.             i += sizeof(XTestJumpInfo);
  390.             break;
  391.         default:
  392.             /*
  393.              * if this is a delay input action, then byte-swap it,
  394.              * otherwise we have reached the end of the input
  395.              * actions in this request
  396.              */
  397.             if (XTestUnpackDeviceID(*input_action_ptr) ==
  398.                 XTestDELAY_DEVICE_ID)
  399.             {
  400.                 /*
  401.                  * byte-swap the delay_time field
  402.                  */
  403.                 swapl(&(((XTestDelayInfo *) input_action_ptr)->delay_time), n);
  404.                 /*
  405.                  * advance to the next input action
  406.                  */
  407.                 i += sizeof(XTestDelayInfo);
  408.             }
  409.             else
  410.             {
  411.                 /*
  412.                  * if the input action header byte is 0 or
  413.                  * ill-formed, then there are no more input
  414.                  * actions in this request
  415.                  */
  416.                 i = XTestMAX_ACTION_LIST_SIZE;
  417.             }
  418.             break;
  419.         }
  420.     }
  421.     return(ProcTestFakeInput(client));
  422. }
  423.  
  424. /*****************************************************************************
  425.  *
  426.  *    SProcTestGetInput
  427.  *
  428.  *
  429.  */
  430. static int
  431. SProcTestGetInput(client)
  432.     register ClientPtr    client;
  433. {
  434.     /*
  435.      * used in the swaps and swapl macros for temporary storage space
  436.      */
  437.     register char    n;
  438.  
  439.     REQUEST(xTestGetInputReq);
  440.     /*
  441.      * byte-swap the fields in the request
  442.      */
  443.     swaps(&stuff->length, n);
  444.     swapl(&stuff->mode, n);
  445.     return(ProcTestGetInput(client));
  446. }
  447.  
  448. /*****************************************************************************
  449.  *
  450.  *    SProcTestStopInput
  451.  *
  452.  *
  453.  */
  454. static int
  455. SProcTestStopInput(client)
  456.     register ClientPtr    client;
  457. {
  458.     /*
  459.      * used in the swaps and swapl macros for temporary storage space
  460.      */
  461.     register char    n;
  462.  
  463.     REQUEST(xTestStopInputReq);
  464.     /*
  465.      * byte-swap the length field in the request
  466.      */
  467.     swaps(&stuff->length, n);
  468.     return(ProcTestStopInput(client));
  469. }
  470.  
  471. /*****************************************************************************
  472.  *
  473.  *    SProcTestReset
  474.  *
  475.  *
  476.  */
  477. static int
  478. SProcTestReset(client)
  479.     register ClientPtr    client;
  480. {
  481.     /*
  482.      * used in the swaps and swapl macros for temporary storage space
  483.      */
  484.     register char    n;
  485.  
  486.     REQUEST(xTestResetReq);
  487.     /*
  488.      * byte-swap the length field in the request
  489.      */
  490.     swaps(&stuff->length, n);
  491.     return(ProcTestReset(client));
  492. }
  493.  
  494. /*****************************************************************************
  495.  *
  496.  *    SProcTestQueryInputSize
  497.  *
  498.  *
  499.  */
  500. static int
  501. SProcTestQueryInputSize(client)
  502.     register ClientPtr    client;
  503. {
  504.     /*
  505.      * used in the swaps and swapl macros for temporary storage space
  506.      */
  507.     register char    n;
  508.  
  509.     REQUEST(xTestQueryInputSizeReq);
  510.     /*
  511.      * byte-swap the length field in the request
  512.      */
  513.     swaps(&stuff->length, n);
  514.     return(ProcTestQueryInputSize(client));
  515. }
  516.  
  517. /*****************************************************************************
  518.  *
  519.  *    ProcTestFakeInput
  520.  *
  521.  *
  522.  */
  523. static int
  524. ProcTestFakeInput(client)
  525.     register ClientPtr    client;
  526. {
  527.     REQUEST(xTestFakeInputReq);
  528.     REQUEST_SIZE_MATCH(xTestFakeInputReq);
  529.     if (playback_client == NULL || playback_client == client)
  530.     {
  531.         /*
  532.          * This extension does not need to clean up any
  533.          * server state when a client using this function
  534.          * "goes away".  The server will just process any
  535.          * input actions that have already been sent to it,
  536.          * and will then reset its association with a client.
  537.          */
  538.         parse_fake_input(client, (char *)stuff);
  539.         return(Success);
  540.     }
  541.     else
  542.     {
  543.         /*
  544.          * this is a request by another client to send fake
  545.          * input while the server is still being used
  546.          */
  547.         SendErrorToClient(client,
  548.                   XTestReqCode,
  549.                   X_TestFakeInput,
  550.                   None,
  551.                   BadAccess);
  552.         return(BadAccess);
  553.     }
  554. }
  555.  
  556. /*****************************************************************************
  557.  *
  558.  *    ProcTestGetInput
  559.  *
  560.  *
  561.  */
  562. static int
  563. ProcTestGetInput(client)
  564.     register ClientPtr    client;
  565. {
  566.     REQUEST(xTestGetInputReq);
  567.     REQUEST_SIZE_MATCH(xTestGetInputReq);
  568.     if (on_steal_input)
  569.     {
  570.         /*
  571.          * this is a request by another client to get fake input
  572.          * while the server is still sending input to the first client
  573.          */
  574.         SendErrorToClient(client,
  575.                   XTestReqCode,
  576.                   X_TestGetInput,
  577.                   None,
  578.                   BadAccess);
  579.         return(BadAccess);
  580.     }
  581.     else
  582.     { 
  583.         /*
  584.          * Set up a resource associated with the client using this
  585.          * function so that this extension gets called when the 
  586.          * client "goes away".  This allows this extension to
  587.          * clean up the server state.
  588.          */
  589.         current_client_id = FakeClientID(client->index);
  590.         AddResource(current_client_id,
  591.                 XTestType,
  592.                 0);
  593.         /*
  594.          * indicate that a client is stealing input
  595.          */
  596.         on_steal_input = TRUE;
  597.         if ((stuff->mode & XTestEXCLUSIVE) == 0)
  598.         {
  599.             exclusive_steal = FALSE;
  600.         }
  601.         else 
  602.         {
  603.             exclusive_steal = TRUE;
  604.         }
  605.         steal_input(client, stuff->mode);
  606.         return(Success);
  607.     }
  608. }
  609.  
  610. /*****************************************************************************
  611.  *
  612.  *    ProcTestStopInput
  613.  *
  614.  *
  615.  */
  616. static int
  617. ProcTestStopInput(client)
  618.     register ClientPtr    client;
  619. {
  620.     REQUEST(xTestStopInputReq);
  621.     REQUEST_SIZE_MATCH(xTestStopInputReq);
  622.     if (on_steal_input && (current_xtest_client == client)) 
  623.     { 
  624.         on_steal_input = FALSE;
  625.         exclusive_steal = FALSE;
  626.         stop_stealing_input();    
  627.         /*
  628.          * remove the resource associated with this client
  629.          */
  630.         FreeResource(current_client_id, RT_NONE);
  631.         return(Success);
  632.     }
  633.     else
  634.     {
  635.         /*
  636.          * this is a request to stop fake input when fake input has
  637.          * never been started or from a client that hasn't started
  638.          * fake input
  639.          */
  640.         SendErrorToClient(client,
  641.                   XTestReqCode,
  642.                   X_TestStopInput,
  643.                   None,
  644.                   BadAccess);
  645.         return(BadAccess);
  646.     }
  647. }
  648.  
  649. /*****************************************************************************
  650.  *
  651.  *    ProcTestReset
  652.  *
  653.  *
  654.  */
  655. static int
  656. ProcTestReset(client)
  657.     register ClientPtr    client;
  658. {
  659.     REQUEST(xTestResetReq);
  660.     REQUEST_SIZE_MATCH(xTestResetReq);
  661.     on_steal_input = FALSE;
  662.     exclusive_steal = FALSE;
  663.     /*
  664.      * defined in xtest1dd.c
  665.      */
  666.     stop_stealing_input();    
  667.     /*
  668.      * defined in xtest1dd.c
  669.      */
  670.     abort_play_back();
  671.     return(Success);
  672. }
  673.  
  674. /*****************************************************************************
  675.  *
  676.  *    ProcTestQueryInputSize
  677.  *
  678.  *
  679.  */
  680. static int
  681. ProcTestQueryInputSize(client)
  682.     register ClientPtr    client;
  683. {
  684.     REQUEST(xTestQueryInputSizeReq);
  685.     REQUEST_SIZE_MATCH(xTestQueryInputSizeReq);
  686.     /*
  687.      * defined in xtest1dd.c
  688.      */
  689.     return_input_array_size(client);
  690.     return(Success);
  691. }
  692.  
  693. /*****************************************************************************
  694.  *
  695.  *    XTestResetProc
  696.  *
  697.  *    This function is called by the server when the server has no clients
  698.  *    connected to it.  It must put eveything back the way it was before
  699.  *    this extension was installed.
  700.  */
  701. static void
  702. XTestResetProc()
  703. {
  704.     /*
  705.      * remove the routine to handle byte-swapping the replies
  706.      * for this extension in the ReplySwapVector table
  707.      */
  708.     ReplySwapVector[XTestReqCode] = NotImplemented;
  709.     /*
  710.      * remove the routine to handle byte-swapping the events
  711.      * for this extension in the EventSwapVector table
  712.      */
  713.     EventSwapVector[XTestInputActionType] = NotImplemented;
  714.     EventSwapVector[XTestFakeAckType] = NotImplemented;
  715.     /*
  716.      * reset the variables initialized just once at load time
  717.      */
  718.     XTestReqCode = 0;
  719.     XTestInputActionType = 0;
  720.     XTestFakeAckType = 1;
  721.     on_steal_input = FALSE;
  722.     exclusive_steal = FALSE;
  723. }
  724.  
  725. /*****************************************************************************
  726.  *
  727.  *    ProcTestQueryInputSize
  728.  *
  729.  *    This routine is called when a client that has asked for input actions
  730.  *    to be sent to it "goes away".  This routine must clean up the 
  731.  *    server state.
  732.  */
  733. /*ARGSUSED*/
  734. static void
  735. XTestCurrentClientGone(value, id)
  736.     int    value;
  737.     XID    id;
  738. {
  739.     /*
  740.      * defined in xtest1dd.c
  741.      */
  742.     flush_input_actions();
  743.     on_steal_input = FALSE;
  744.     exclusive_steal = FALSE;
  745.     /*
  746.      * defined in xtestdd.c
  747.      */
  748.     stop_stealing_input();    
  749. }
  750.  
  751. /*****************************************************************************
  752.  *
  753.  *    SReplyXTestDispatch
  754.  *
  755.  *    Swap any replies defined in this extension.
  756.  */
  757. static void
  758. SReplyXTestDispatch(client_ptr, size, reply_ptr)
  759.     ClientPtr    client_ptr;
  760.     int        size;
  761.     char        *reply_ptr;
  762. {
  763.     /*
  764.      * used in the swaps and swapl macros for temporary storage space
  765.      */
  766.     register char    n;
  767.     /*
  768.      * pointer to xTestQueryInputSizeReply
  769.      */
  770.     xTestQueryInputSizeReply    *rep_ptr;
  771.  
  772.     /*
  773.      * there is only one reply in this extension, so byte-swap it
  774.      */
  775.     rep_ptr = (xTestQueryInputSizeReply *) reply_ptr;
  776.     swaps(&(rep_ptr->sequenceNumber), n);
  777.     swapl(&(rep_ptr->length), n);
  778.     swapl(&(rep_ptr->size_return), n);
  779.     /*
  780.      * now write the swapped reply to the client
  781.      */
  782.     WriteToClient(client_ptr, size, reply_ptr);
  783. }
  784.  
  785. /*****************************************************************************
  786.  *
  787.  *    SEventXTestDispatch
  788.  *
  789.  *    Swap any events defined in this extension.
  790.  */
  791. static void
  792. SEventXTestDispatch(from, to)
  793.     xEvent    *from;
  794.     xEvent    *to;
  795. {
  796.     /*
  797.      * used in the swaps and swapl macros for temporary storage space
  798.      */
  799.     register char    n;
  800.     /*
  801.      * index counter
  802.      */
  803.     int        i;
  804.     /*
  805.      * pointer to the next input action in the event
  806.      */
  807.     CARD8        *input_action_ptr;
  808.     /*
  809.      * holds the type of the next input action in the event
  810.      */
  811.     int        input_action_type;
  812.  
  813.  
  814.     /*
  815.      * copy the type information from the "from" event to the "to" event
  816.      */
  817.     ((xTestInputActionEvent *) to)->type =
  818.     ((xTestInputActionEvent *) from)->type;
  819.     /*
  820.      * copy the sequence number information from the "from" event to the
  821.      * "to" event
  822.      */
  823.     ((xTestInputActionEvent *) to)->sequenceNumber =
  824.     ((xTestInputActionEvent *) from)->sequenceNumber;
  825.     /*
  826.      * byte-swap the sequence number in the "to" event
  827.      */
  828.     swaps(&(((xTestInputActionEvent *) to)->sequenceNumber), n);
  829.     /*
  830.      * If the event is an xTestInputActionEvent, then it needs more
  831.      * processing.  Otherwise, it is an xTestFakeAckEvent, which
  832.      * has no other information in it.
  833.      */
  834.     if ((((xTestInputActionEvent *) to)->type & 0x7f) ==
  835.         XTestInputActionType)
  836.     {
  837.         /*
  838.          * copy the input actions from the "from" event
  839.          * to the "to" event
  840.          */
  841.         for (i = 0; i < XTestACTIONS_SIZE;)
  842.         {
  843.             ((xTestInputActionEvent *) to)->actions[i] =
  844.             ((xTestInputActionEvent *) from)->actions[i];
  845.         }
  846.         /*
  847.          * byte-swap the input actions in the "to" event
  848.          */
  849.         for (i = 0; i < XTestACTIONS_SIZE;)
  850.         {
  851.             /*
  852.              * point to the next input action in the event
  853.              */
  854.             input_action_ptr = &(((xTestInputActionEvent *) to)->actions[i]);
  855.             /*
  856.              * figure out what type of input action it is
  857.              */
  858.             input_action_type = (*input_action_ptr) &
  859.                         XTestACTION_TYPE_MASK;
  860.             /*
  861.              * byte-swap the input action according to it's type
  862.              */
  863.             switch (input_action_type)
  864.             {
  865.             case XTestKEY_ACTION:
  866.                 /*
  867.                  * byte-swap the delay_time field
  868.                  */
  869.                 swaps(&(((XTestKeyInfo *) input_action_ptr)->delay_time), n);
  870.                 /*
  871.                  * advance to the next input action
  872.                  */
  873.                 i += sizeof(XTestKeyInfo);
  874.                 break;
  875.             case XTestMOTION_ACTION:
  876.                 /*
  877.                  * byte-swap the delay_time field
  878.                  */
  879.                 swaps(&(((XTestMotionInfo *) input_action_ptr)->delay_time), n);
  880.                 /*
  881.                  * advance to the next input action
  882.                  */
  883.                 i += sizeof(XTestMotionInfo);
  884.                 break;
  885.             case XTestJUMP_ACTION:
  886.                 /*
  887.                  * byte-swap the jumpx field
  888.                  */
  889.                 swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpx), n);
  890.                 /*
  891.                  * byte-swap the jumpy field
  892.                  */
  893.                 swaps(&(((XTestJumpInfo *) input_action_ptr)->jumpy), n);
  894.                 /*
  895.                  * byte-swap the delay_time field
  896.                  */
  897.                 swaps(&(((XTestJumpInfo *) input_action_ptr)->delay_time), n);
  898.                 /*
  899.                  * advance to the next input action
  900.                  */
  901.                 i += sizeof(XTestJumpInfo);
  902.                 break;
  903.             default:
  904.                 /*
  905.                  * if this is a delay input action, then
  906.                  * byte-swap it, otherwise we have reached the
  907.                  * end of the input actions in this event
  908.                  */
  909.                 if (XTestUnpackDeviceID(*input_action_ptr) ==
  910.                     XTestDELAY_DEVICE_ID)
  911.                 {
  912.                     /*
  913.                      * byte-swap the delay_time field
  914.                      */
  915.                     swapl(&(((XTestDelayInfo *) input_action_ptr)->delay_time), n);
  916.                     /*
  917.                      * advance to the next input action
  918.                      */
  919.                     i += sizeof(XTestDelayInfo);
  920.                 }
  921.                 else
  922.                 {
  923.                     /*
  924.                      * if the input action header byte is 0
  925.                      * or ill-formed, then there are no
  926.                      * more input actions in this event
  927.                      */
  928.                     i = XTestACTIONS_SIZE;
  929.                 }
  930.                 break;
  931.             }
  932.         }
  933.     }
  934. }
  935.