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