1/************************************************************
2
3Copyright 1989, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
26
27			All Rights Reserved
28
29Permission to use, copy, modify, and distribute this software and its
30documentation for any purpose and without fee is hereby granted,
31provided that the above copyright notice appear in all copies and that
32both that copyright notice and this permission notice appear in
33supporting documentation, and that the name of Hewlett-Packard not be
34used in advertising or publicity pertaining to distribution of the
35software without specific, written prior permission.
36
37HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43SOFTWARE.
44
45********************************************************/
46
47/********************************************************************
48 *
49 *  Dispatch routines and initialization routines for the X input extension.
50 *
51 */
52#define	 NUMTYPES 15
53
54#ifdef HAVE_DIX_CONFIG_H
55#include <dix-config.h>
56#endif
57
58#include "inputstr.h"
59#include "gcstruct.h"           /* pointer for extnsionst.h */
60#include "extnsionst.h"         /* extension entry   */
61#include <X11/extensions/XI.h>
62#include <X11/extensions/XIproto.h>
63#include <X11/extensions/XI2proto.h>
64#include <X11/extensions/geproto.h>
65#include "geext.h"              /* extension interfaces for ge */
66
67#include "dixevents.h"
68#include "exevents.h"
69#include "extinit.h"
70#include "exglobals.h"
71#include "swaprep.h"
72#include "privates.h"
73#include "protocol-versions.h"
74
75/* modules local to Xi */
76#include "allowev.h"
77#include "chgdctl.h"
78#include "chgfctl.h"
79#include "chgkbd.h"
80#include "chgprop.h"
81#include "chgptr.h"
82#include "closedev.h"
83#include "devbell.h"
84#include "getbmap.h"
85#include "getdctl.h"
86#include "getfctl.h"
87#include "getfocus.h"
88#include "getkmap.h"
89#include "getmmap.h"
90#include "getprop.h"
91#include "getselev.h"
92#include "getvers.h"
93#include "grabdev.h"
94#include "grabdevb.h"
95#include "grabdevk.h"
96#include "gtmotion.h"
97#include "listdev.h"
98#include "opendev.h"
99#include "queryst.h"
100#include "selectev.h"
101#include "sendexev.h"
102#include "chgkmap.h"
103#include "setbmap.h"
104#include "setdval.h"
105#include "setfocus.h"
106#include "setmmap.h"
107#include "setmode.h"
108#include "ungrdev.h"
109#include "ungrdevb.h"
110#include "ungrdevk.h"
111#include "xiallowev.h"
112#include "xiselectev.h"
113#include "xigrabdev.h"
114#include "xipassivegrab.h"
115#include "xisetdevfocus.h"
116#include "xiproperty.h"
117#include "xichangecursor.h"
118#include "xichangehierarchy.h"
119#include "xigetclientpointer.h"
120#include "xiquerydevice.h"
121#include "xiquerypointer.h"
122#include "xiqueryversion.h"
123#include "xisetclientpointer.h"
124#include "xiwarppointer.h"
125#include "xibarriers.h"
126
127/* Masks for XI events have to be aligned with core event (partially anyway).
128 * If DeviceButtonMotionMask is != ButtonMotionMask, event delivery
129 * breaks down. The device needs the dev->button->motionMask. If DBMM is
130 * the same as BMM, we can ensure that both core and device events can be
131 * delivered, without the need for extra structures in the DeviceIntRec. */
132const Mask DeviceProximityMask = (1L << 4);
133const Mask DeviceStateNotifyMask = (1L << 5);
134const Mask DevicePointerMotionHintMask = PointerMotionHintMask;
135const Mask DeviceButton1MotionMask = Button1MotionMask;
136const Mask DeviceButton2MotionMask = Button2MotionMask;
137const Mask DeviceButton3MotionMask = Button3MotionMask;
138const Mask DeviceButton4MotionMask = Button4MotionMask;
139const Mask DeviceButton5MotionMask = Button5MotionMask;
140const Mask DeviceButtonMotionMask = ButtonMotionMask;
141const Mask DeviceFocusChangeMask = (1L << 14);
142const Mask DeviceMappingNotifyMask = (1L << 15);
143const Mask ChangeDeviceNotifyMask = (1L << 16);
144const Mask DeviceButtonGrabMask = (1L << 17);
145const Mask DeviceOwnerGrabButtonMask = (1L << 17);
146const Mask DevicePresenceNotifyMask = (1L << 18);
147const Mask DevicePropertyNotifyMask = (1L << 19);
148const Mask XIAllMasks = (1L << 20) - 1;
149
150int ExtEventIndex;
151
152static struct dev_type {
153    Atom type;
154    const char *name;
155} dev_type[] = {
156    {0, XI_KEYBOARD},
157    {0, XI_MOUSE},
158    {0, XI_TABLET},
159    {0, XI_TOUCHSCREEN},
160    {0, XI_TOUCHPAD},
161    {0, XI_BARCODE},
162    {0, XI_BUTTONBOX},
163    {0, XI_KNOB_BOX},
164    {0, XI_ONE_KNOB},
165    {0, XI_NINE_KNOB},
166    {0, XI_TRACKBALL},
167    {0, XI_QUADRATURE},
168    {0, XI_ID_MODULE},
169    {0, XI_SPACEBALL},
170    {0, XI_DATAGLOVE},
171    {0, XI_EYETRACKER},
172    {0, XI_CURSORKEYS},
173    {0, XI_FOOTMOUSE}
174};
175
176CARD8 event_base[numInputClasses];
177XExtEventInfo EventInfo[32];
178
179static DeviceIntRec xi_all_devices;
180static DeviceIntRec xi_all_master_devices;
181
182/**
183 * Dispatch vector. Functions defined in here will be called when the matching
184 * request arrives.
185 */
186static int (*ProcIVector[]) (ClientPtr) = {
187    NULL,                       /*  0 */
188        ProcXGetExtensionVersion,       /*  1 */
189        ProcXListInputDevices,  /*  2 */
190        ProcXOpenDevice,        /*  3 */
191        ProcXCloseDevice,       /*  4 */
192        ProcXSetDeviceMode,     /*  5 */
193        ProcXSelectExtensionEvent,      /*  6 */
194        ProcXGetSelectedExtensionEvents,        /*  7 */
195        ProcXChangeDeviceDontPropagateList,     /*  8 */
196        ProcXGetDeviceDontPropagateList,        /*  9 */
197        ProcXGetDeviceMotionEvents,     /* 10 */
198        ProcXChangeKeyboardDevice,      /* 11 */
199        ProcXChangePointerDevice,       /* 12 */
200        ProcXGrabDevice,        /* 13 */
201        ProcXUngrabDevice,      /* 14 */
202        ProcXGrabDeviceKey,     /* 15 */
203        ProcXUngrabDeviceKey,   /* 16 */
204        ProcXGrabDeviceButton,  /* 17 */
205        ProcXUngrabDeviceButton,        /* 18 */
206        ProcXAllowDeviceEvents, /* 19 */
207        ProcXGetDeviceFocus,    /* 20 */
208        ProcXSetDeviceFocus,    /* 21 */
209        ProcXGetFeedbackControl,        /* 22 */
210        ProcXChangeFeedbackControl,     /* 23 */
211        ProcXGetDeviceKeyMapping,       /* 24 */
212        ProcXChangeDeviceKeyMapping,    /* 25 */
213        ProcXGetDeviceModifierMapping,  /* 26 */
214        ProcXSetDeviceModifierMapping,  /* 27 */
215        ProcXGetDeviceButtonMapping,    /* 28 */
216        ProcXSetDeviceButtonMapping,    /* 29 */
217        ProcXQueryDeviceState,  /* 30 */
218        ProcXSendExtensionEvent,        /* 31 */
219        ProcXDeviceBell,        /* 32 */
220        ProcXSetDeviceValuators,        /* 33 */
221        ProcXGetDeviceControl,  /* 34 */
222        ProcXChangeDeviceControl,       /* 35 */
223        /* XI 1.5 */
224        ProcXListDeviceProperties,      /* 36 */
225        ProcXChangeDeviceProperty,      /* 37 */
226        ProcXDeleteDeviceProperty,      /* 38 */
227        ProcXGetDeviceProperty, /* 39 */
228        /* XI 2 */
229        ProcXIQueryPointer,     /* 40 */
230        ProcXIWarpPointer,      /* 41 */
231        ProcXIChangeCursor,     /* 42 */
232        ProcXIChangeHierarchy,  /* 43 */
233        ProcXISetClientPointer, /* 44 */
234        ProcXIGetClientPointer, /* 45 */
235        ProcXISelectEvents,     /* 46 */
236        ProcXIQueryVersion,     /* 47 */
237        ProcXIQueryDevice,      /* 48 */
238        ProcXISetFocus,         /* 49 */
239        ProcXIGetFocus,         /* 50 */
240        ProcXIGrabDevice,       /* 51 */
241        ProcXIUngrabDevice,     /* 52 */
242        ProcXIAllowEvents,      /* 53 */
243        ProcXIPassiveGrabDevice,        /* 54 */
244        ProcXIPassiveUngrabDevice,      /* 55 */
245        ProcXIListProperties,   /* 56 */
246        ProcXIChangeProperty,   /* 57 */
247        ProcXIDeleteProperty,   /* 58 */
248        ProcXIGetProperty,      /* 59 */
249        ProcXIGetSelectedEvents, /* 60 */
250        ProcXIBarrierReleasePointer /* 61 */
251};
252
253/* For swapped clients */
254static int (*SProcIVector[]) (ClientPtr) = {
255    NULL,                       /*  0 */
256        SProcXGetExtensionVersion,      /*  1 */
257        SProcXListInputDevices, /*  2 */
258        SProcXOpenDevice,       /*  3 */
259        SProcXCloseDevice,      /*  4 */
260        SProcXSetDeviceMode,    /*  5 */
261        SProcXSelectExtensionEvent,     /*  6 */
262        SProcXGetSelectedExtensionEvents,       /*  7 */
263        SProcXChangeDeviceDontPropagateList,    /*  8 */
264        SProcXGetDeviceDontPropagateList,       /*  9 */
265        SProcXGetDeviceMotionEvents,    /* 10 */
266        SProcXChangeKeyboardDevice,     /* 11 */
267        SProcXChangePointerDevice,      /* 12 */
268        SProcXGrabDevice,       /* 13 */
269        SProcXUngrabDevice,     /* 14 */
270        SProcXGrabDeviceKey,    /* 15 */
271        SProcXUngrabDeviceKey,  /* 16 */
272        SProcXGrabDeviceButton, /* 17 */
273        SProcXUngrabDeviceButton,       /* 18 */
274        SProcXAllowDeviceEvents,        /* 19 */
275        SProcXGetDeviceFocus,   /* 20 */
276        SProcXSetDeviceFocus,   /* 21 */
277        SProcXGetFeedbackControl,       /* 22 */
278        SProcXChangeFeedbackControl,    /* 23 */
279        SProcXGetDeviceKeyMapping,      /* 24 */
280        SProcXChangeDeviceKeyMapping,   /* 25 */
281        SProcXGetDeviceModifierMapping, /* 26 */
282        SProcXSetDeviceModifierMapping, /* 27 */
283        SProcXGetDeviceButtonMapping,   /* 28 */
284        SProcXSetDeviceButtonMapping,   /* 29 */
285        SProcXQueryDeviceState, /* 30 */
286        SProcXSendExtensionEvent,       /* 31 */
287        SProcXDeviceBell,       /* 32 */
288        SProcXSetDeviceValuators,       /* 33 */
289        SProcXGetDeviceControl, /* 34 */
290        SProcXChangeDeviceControl,      /* 35 */
291        SProcXListDeviceProperties,     /* 36 */
292        SProcXChangeDeviceProperty,     /* 37 */
293        SProcXDeleteDeviceProperty,     /* 38 */
294        SProcXGetDeviceProperty,        /* 39 */
295        SProcXIQueryPointer,    /* 40 */
296        SProcXIWarpPointer,     /* 41 */
297        SProcXIChangeCursor,    /* 42 */
298        SProcXIChangeHierarchy, /* 43 */
299        SProcXISetClientPointer,        /* 44 */
300        SProcXIGetClientPointer,        /* 45 */
301        SProcXISelectEvents,    /* 46 */
302        SProcXIQueryVersion,    /* 47 */
303        SProcXIQueryDevice,     /* 48 */
304        SProcXISetFocus,        /* 49 */
305        SProcXIGetFocus,        /* 50 */
306        SProcXIGrabDevice,      /* 51 */
307        SProcXIUngrabDevice,    /* 52 */
308        SProcXIAllowEvents,     /* 53 */
309        SProcXIPassiveGrabDevice,       /* 54 */
310        SProcXIPassiveUngrabDevice,     /* 55 */
311        SProcXIListProperties,  /* 56 */
312        SProcXIChangeProperty,  /* 57 */
313        SProcXIDeleteProperty,  /* 58 */
314        SProcXIGetProperty,     /* 59 */
315        SProcXIGetSelectedEvents,       /* 60 */
316        SProcXIBarrierReleasePointer /* 61 */
317};
318
319/*****************************************************************
320 *
321 * Globals referenced elsewhere in the server.
322 *
323 */
324
325int IReqCode = 0;
326int IEventBase = 0;
327int BadDevice = 0;
328static int BadEvent = 1;
329int BadMode = 2;
330int DeviceBusy = 3;
331int BadClass = 4;
332
333int DeviceValuator;
334int DeviceKeyPress;
335int DeviceKeyRelease;
336int DeviceButtonPress;
337int DeviceButtonRelease;
338int DeviceMotionNotify;
339int DeviceFocusIn;
340int DeviceFocusOut;
341int ProximityIn;
342int ProximityOut;
343int DeviceStateNotify;
344int DeviceKeyStateNotify;
345int DeviceButtonStateNotify;
346int DeviceMappingNotify;
347int ChangeDeviceNotify;
348int DevicePresenceNotify;
349int DevicePropertyNotify;
350
351RESTYPE RT_INPUTCLIENT;
352
353/*****************************************************************
354 *
355 * Externs defined elsewhere in the X server.
356 *
357 */
358
359extern XExtensionVersion XIVersion;
360
361/*****************************************************************
362 *
363 * Versioning support
364 *
365 */
366
367DevPrivateKeyRec XIClientPrivateKeyRec;
368
369/*****************************************************************
370 *
371 * Declarations of local routines.
372 *
373 */
374
375/*************************************************************************
376 *
377 * ProcIDispatch - main dispatch routine for requests to this extension.
378 * This routine is used if server and client have the same byte ordering.
379 *
380 */
381
382static int
383ProcIDispatch(ClientPtr client)
384{
385    REQUEST(xReq);
386    if (stuff->data >= ARRAY_SIZE(ProcIVector) || !ProcIVector[stuff->data])
387        return BadRequest;
388
389    UpdateCurrentTimeIf();
390    return (*ProcIVector[stuff->data]) (client);
391}
392
393/*******************************************************************************
394 *
395 * SProcXDispatch
396 *
397 * Main swapped dispatch routine for requests to this extension.
398 * This routine is used if server and client do not have the same byte ordering.
399 *
400 */
401
402static int _X_COLD
403SProcIDispatch(ClientPtr client)
404{
405    REQUEST(xReq);
406    if (stuff->data >= ARRAY_SIZE(SProcIVector) || !SProcIVector[stuff->data])
407        return BadRequest;
408
409    UpdateCurrentTimeIf();
410    return (*SProcIVector[stuff->data]) (client);
411}
412
413/**********************************************************************
414 *
415 * SReplyIDispatch
416 * Swap any replies defined in this extension.
417 *
418 */
419
420static void _X_COLD
421SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
422{
423    /* All we look at is the type field */
424    /* This is common to all replies    */
425    if (rep->RepType == X_GetExtensionVersion)
426        SRepXGetExtensionVersion(client, len,
427                                 (xGetExtensionVersionReply *) rep);
428    else if (rep->RepType == X_ListInputDevices)
429        SRepXListInputDevices(client, len, (xListInputDevicesReply *) rep);
430    else if (rep->RepType == X_OpenDevice)
431        SRepXOpenDevice(client, len, (xOpenDeviceReply *) rep);
432    else if (rep->RepType == X_SetDeviceMode)
433        SRepXSetDeviceMode(client, len, (xSetDeviceModeReply *) rep);
434    else if (rep->RepType == X_GetSelectedExtensionEvents)
435        SRepXGetSelectedExtensionEvents(client, len,
436                                        (xGetSelectedExtensionEventsReply *)
437                                        rep);
438    else if (rep->RepType == X_GetDeviceDontPropagateList)
439        SRepXGetDeviceDontPropagateList(client, len,
440                                        (xGetDeviceDontPropagateListReply *)
441                                        rep);
442    else if (rep->RepType == X_GetDeviceMotionEvents)
443        SRepXGetDeviceMotionEvents(client, len,
444                                   (xGetDeviceMotionEventsReply *) rep);
445    else if (rep->RepType == X_GrabDevice)
446        SRepXGrabDevice(client, len, (xGrabDeviceReply *) rep);
447    else if (rep->RepType == X_GetDeviceFocus)
448        SRepXGetDeviceFocus(client, len, (xGetDeviceFocusReply *) rep);
449    else if (rep->RepType == X_GetFeedbackControl)
450        SRepXGetFeedbackControl(client, len, (xGetFeedbackControlReply *) rep);
451    else if (rep->RepType == X_GetDeviceKeyMapping)
452        SRepXGetDeviceKeyMapping(client, len,
453                                 (xGetDeviceKeyMappingReply *) rep);
454    else if (rep->RepType == X_GetDeviceModifierMapping)
455        SRepXGetDeviceModifierMapping(client, len,
456                                      (xGetDeviceModifierMappingReply *) rep);
457    else if (rep->RepType == X_SetDeviceModifierMapping)
458        SRepXSetDeviceModifierMapping(client, len,
459                                      (xSetDeviceModifierMappingReply *) rep);
460    else if (rep->RepType == X_GetDeviceButtonMapping)
461        SRepXGetDeviceButtonMapping(client, len,
462                                    (xGetDeviceButtonMappingReply *) rep);
463    else if (rep->RepType == X_SetDeviceButtonMapping)
464        SRepXSetDeviceButtonMapping(client, len,
465                                    (xSetDeviceButtonMappingReply *) rep);
466    else if (rep->RepType == X_QueryDeviceState)
467        SRepXQueryDeviceState(client, len, (xQueryDeviceStateReply *) rep);
468    else if (rep->RepType == X_SetDeviceValuators)
469        SRepXSetDeviceValuators(client, len, (xSetDeviceValuatorsReply *) rep);
470    else if (rep->RepType == X_GetDeviceControl)
471        SRepXGetDeviceControl(client, len, (xGetDeviceControlReply *) rep);
472    else if (rep->RepType == X_ChangeDeviceControl)
473        SRepXChangeDeviceControl(client, len,
474                                 (xChangeDeviceControlReply *) rep);
475    else if (rep->RepType == X_ListDeviceProperties)
476        SRepXListDeviceProperties(client, len,
477                                  (xListDevicePropertiesReply *) rep);
478    else if (rep->RepType == X_GetDeviceProperty)
479        SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep);
480    else if (rep->RepType == X_XIQueryPointer)
481        SRepXIQueryPointer(client, len, (xXIQueryPointerReply *) rep);
482    else if (rep->RepType == X_XIGetClientPointer)
483        SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply *) rep);
484    else if (rep->RepType == X_XIQueryVersion)
485        SRepXIQueryVersion(client, len, (xXIQueryVersionReply *) rep);
486    else if (rep->RepType == X_XIQueryDevice)
487        SRepXIQueryDevice(client, len, (xXIQueryDeviceReply *) rep);
488    else if (rep->RepType == X_XIGrabDevice)
489        SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
490    else if (rep->RepType == X_XIPassiveGrabDevice)
491        SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
492    else if (rep->RepType == X_XIListProperties)
493        SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
494    else if (rep->RepType == X_XIGetProperty)
495        SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
496    else if (rep->RepType == X_XIGetSelectedEvents)
497        SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep);
498    else if (rep->RepType == X_XIGetFocus)
499        SRepXIGetFocus(client, len, (xXIGetFocusReply *) rep);
500    else {
501        FatalError("XINPUT confused sending swapped reply");
502    }
503}
504
505/************************************************************************
506 *
507 * This function swaps the DeviceValuator event.
508 *
509 */
510
511static void
512SEventDeviceValuator(deviceValuator * from, deviceValuator * to)
513{
514    int i;
515    INT32 *ip;
516
517    *to = *from;
518    swaps(&to->sequenceNumber);
519    swaps(&to->device_state);
520    ip = &to->valuator0;
521    for (i = 0; i < 6; i++) {
522        swapl(ip + i);
523    }
524}
525
526static void
527SEventFocus(deviceFocus * from, deviceFocus * to)
528{
529    *to = *from;
530    swaps(&to->sequenceNumber);
531    swapl(&to->time);
532    swapl(&to->window);
533}
534
535static void
536SDeviceStateNotifyEvent(deviceStateNotify * from, deviceStateNotify * to)
537{
538    int i;
539    INT32 *ip;
540
541    *to = *from;
542    swaps(&to->sequenceNumber);
543    swapl(&to->time);
544    ip = &to->valuator0;
545    for (i = 0; i < 3; i++) {
546        swapl(ip + i);
547    }
548}
549
550static void
551SDeviceKeyStateNotifyEvent(deviceKeyStateNotify * from,
552                           deviceKeyStateNotify * to)
553{
554    *to = *from;
555    swaps(&to->sequenceNumber);
556}
557
558static void
559SDeviceButtonStateNotifyEvent(deviceButtonStateNotify * from,
560                              deviceButtonStateNotify * to)
561{
562    *to = *from;
563    swaps(&to->sequenceNumber);
564}
565
566static void
567SChangeDeviceNotifyEvent(changeDeviceNotify * from, changeDeviceNotify * to)
568{
569    *to = *from;
570    swaps(&to->sequenceNumber);
571    swapl(&to->time);
572}
573
574static void
575SDeviceMappingNotifyEvent(deviceMappingNotify * from, deviceMappingNotify * to)
576{
577    *to = *from;
578    swaps(&to->sequenceNumber);
579    swapl(&to->time);
580}
581
582static void
583SDevicePresenceNotifyEvent(devicePresenceNotify * from,
584                           devicePresenceNotify * to)
585{
586    *to = *from;
587    swaps(&to->sequenceNumber);
588    swapl(&to->time);
589    swaps(&to->control);
590}
591
592static void
593SDevicePropertyNotifyEvent(devicePropertyNotify * from,
594                           devicePropertyNotify * to)
595{
596    *to = *from;
597    swaps(&to->sequenceNumber);
598    swapl(&to->time);
599    swapl(&to->atom);
600}
601
602static void
603SDeviceLeaveNotifyEvent(xXILeaveEvent * from, xXILeaveEvent * to)
604{
605    *to = *from;
606    swaps(&to->sequenceNumber);
607    swapl(&to->length);
608    swaps(&to->evtype);
609    swaps(&to->deviceid);
610    swapl(&to->time);
611    swapl(&to->root);
612    swapl(&to->event);
613    swapl(&to->child);
614    swapl(&to->root_x);
615    swapl(&to->root_y);
616    swapl(&to->event_x);
617    swapl(&to->event_y);
618    swaps(&to->sourceid);
619    swaps(&to->buttons_len);
620    swapl(&to->mods.base_mods);
621    swapl(&to->mods.latched_mods);
622    swapl(&to->mods.locked_mods);
623}
624
625static void
626SDeviceChangedEvent(xXIDeviceChangedEvent * from, xXIDeviceChangedEvent * to)
627{
628    int i, j;
629    xXIAnyInfo *any;
630
631    *to = *from;
632    memcpy(&to[1], &from[1], from->length * 4);
633
634    any = (xXIAnyInfo *) &to[1];
635    for (i = 0; i < to->num_classes; i++) {
636        int length = any->length;
637
638        switch (any->type) {
639        case KeyClass:
640        {
641            xXIKeyInfo *ki = (xXIKeyInfo *) any;
642            uint32_t *key = (uint32_t *) &ki[1];
643
644            for (j = 0; j < ki->num_keycodes; j++, key++)
645                swapl(key);
646            swaps(&ki->num_keycodes);
647        }
648            break;
649        case ButtonClass:
650        {
651            xXIButtonInfo *bi = (xXIButtonInfo *) any;
652            Atom *labels = (Atom *) ((char *) bi + sizeof(xXIButtonInfo) +
653                                     pad_to_int32(bits_to_bytes
654                                                  (bi->num_buttons)));
655            for (j = 0; j < bi->num_buttons; j++)
656                swapl(&labels[j]);
657            swaps(&bi->num_buttons);
658        }
659            break;
660        case ValuatorClass:
661        {
662            xXIValuatorInfo *ai = (xXIValuatorInfo *) any;
663
664            swapl(&ai->label);
665            swapl(&ai->min.integral);
666            swapl(&ai->min.frac);
667            swapl(&ai->max.integral);
668            swapl(&ai->max.frac);
669            swapl(&ai->resolution);
670            swaps(&ai->number);
671        }
672            break;
673        }
674
675        swaps(&any->type);
676        swaps(&any->length);
677        swaps(&any->sourceid);
678
679        any = (xXIAnyInfo *) ((char *) any + length * 4);
680    }
681
682    swaps(&to->sequenceNumber);
683    swapl(&to->length);
684    swaps(&to->evtype);
685    swaps(&to->deviceid);
686    swapl(&to->time);
687    swaps(&to->num_classes);
688    swaps(&to->sourceid);
689
690}
691
692static void
693SDeviceEvent(xXIDeviceEvent * from, xXIDeviceEvent * to)
694{
695    int i;
696    char *ptr;
697    char *vmask;
698
699    memcpy(to, from, sizeof(xEvent) + from->length * 4);
700
701    swaps(&to->sequenceNumber);
702    swapl(&to->length);
703    swaps(&to->evtype);
704    swaps(&to->deviceid);
705    swapl(&to->time);
706    swapl(&to->detail);
707    swapl(&to->root);
708    swapl(&to->event);
709    swapl(&to->child);
710    swapl(&to->root_x);
711    swapl(&to->root_y);
712    swapl(&to->event_x);
713    swapl(&to->event_y);
714    swaps(&to->buttons_len);
715    swaps(&to->valuators_len);
716    swaps(&to->sourceid);
717    swapl(&to->mods.base_mods);
718    swapl(&to->mods.latched_mods);
719    swapl(&to->mods.locked_mods);
720    swapl(&to->mods.effective_mods);
721    swapl(&to->flags);
722
723    ptr = (char *) (&to[1]);
724    ptr += from->buttons_len * 4;
725    vmask = ptr;                /* valuator mask */
726    ptr += from->valuators_len * 4;
727    for (i = 0; i < from->valuators_len * 32; i++) {
728        if (BitIsOn(vmask, i)) {
729            swapl(((uint32_t *) ptr));
730            ptr += 4;
731            swapl(((uint32_t *) ptr));
732            ptr += 4;
733        }
734    }
735}
736
737static void
738SDeviceHierarchyEvent(xXIHierarchyEvent * from, xXIHierarchyEvent * to)
739{
740    int i;
741    xXIHierarchyInfo *info;
742
743    *to = *from;
744    memcpy(&to[1], &from[1], from->length * 4);
745    swaps(&to->sequenceNumber);
746    swapl(&to->length);
747    swaps(&to->evtype);
748    swaps(&to->deviceid);
749    swapl(&to->time);
750    swapl(&to->flags);
751    swaps(&to->num_info);
752
753    info = (xXIHierarchyInfo *) &to[1];
754    for (i = 0; i < from->num_info; i++) {
755        swaps(&info->deviceid);
756        swaps(&info->attachment);
757        info++;
758    }
759}
760
761static void
762SXIPropertyEvent(xXIPropertyEvent * from, xXIPropertyEvent * to)
763{
764    *to = *from;
765    swaps(&to->sequenceNumber);
766    swapl(&to->length);
767    swaps(&to->evtype);
768    swaps(&to->deviceid);
769    swapl(&to->property);
770}
771
772static void
773SRawEvent(xXIRawEvent * from, xXIRawEvent * to)
774{
775    int i;
776    FP3232 *values;
777    unsigned char *mask;
778
779    memcpy(to, from, sizeof(xEvent) + from->length * 4);
780
781    swaps(&to->sequenceNumber);
782    swapl(&to->length);
783    swaps(&to->evtype);
784    swaps(&to->deviceid);
785    swapl(&to->time);
786    swapl(&to->detail);
787
788    mask = (unsigned char *) &to[1];
789    values = (FP3232 *) (mask + from->valuators_len * 4);
790
791    for (i = 0; i < from->valuators_len * 4 * 8; i++) {
792        if (BitIsOn(mask, i)) {
793            /* for each bit set there are two FP3232 values on the wire, in
794             * the order abcABC for data and data_raw. Here we swap as if
795             * they were in aAbBcC order because it's easier and really
796             * doesn't matter.
797             */
798            swapl(&values->integral);
799            swapl(&values->frac);
800            values++;
801            swapl(&values->integral);
802            swapl(&values->frac);
803            values++;
804        }
805    }
806
807    swaps(&to->valuators_len);
808}
809
810static void
811STouchOwnershipEvent(xXITouchOwnershipEvent * from, xXITouchOwnershipEvent * to)
812{
813    *to = *from;
814    swaps(&to->sequenceNumber);
815    swapl(&to->length);
816    swaps(&to->evtype);
817    swaps(&to->deviceid);
818    swapl(&to->time);
819    swaps(&to->sourceid);
820    swapl(&to->touchid);
821    swapl(&to->flags);
822    swapl(&to->root);
823    swapl(&to->event);
824    swapl(&to->child);
825}
826
827static void
828SBarrierEvent(xXIBarrierEvent * from,
829              xXIBarrierEvent * to) {
830
831    *to = *from;
832
833    swaps(&to->sequenceNumber);
834    swapl(&to->length);
835    swaps(&to->evtype);
836    swapl(&to->time);
837    swaps(&to->deviceid);
838    swaps(&to->sourceid);
839    swapl(&to->event);
840    swapl(&to->root);
841    swapl(&to->root_x);
842    swapl(&to->root_y);
843
844    swapl(&to->dx.integral);
845    swapl(&to->dx.frac);
846    swapl(&to->dy.integral);
847    swapl(&to->dy.frac);
848    swapl(&to->dtime);
849    swapl(&to->barrier);
850    swapl(&to->eventid);
851}
852
853static void
854SGesturePinchEvent(xXIGesturePinchEvent* from,
855                   xXIGesturePinchEvent* to)
856{
857    *to = *from;
858
859    swaps(&to->sequenceNumber);
860    swapl(&to->length);
861    swaps(&to->evtype);
862    swaps(&to->deviceid);
863    swapl(&to->time);
864    swapl(&to->detail);
865    swapl(&to->root);
866    swapl(&to->event);
867    swapl(&to->child);
868    swapl(&to->root_x);
869    swapl(&to->root_y);
870    swapl(&to->event_x);
871    swapl(&to->event_y);
872
873    swapl(&to->delta_x);
874    swapl(&to->delta_y);
875    swapl(&to->delta_unaccel_x);
876    swapl(&to->delta_unaccel_y);
877    swapl(&to->scale);
878    swapl(&to->delta_angle);
879    swaps(&to->sourceid);
880
881    swapl(&to->mods.base_mods);
882    swapl(&to->mods.latched_mods);
883    swapl(&to->mods.locked_mods);
884    swapl(&to->mods.effective_mods);
885    swapl(&to->flags);
886}
887
888static void
889SGestureSwipeEvent(xXIGestureSwipeEvent* from,
890                   xXIGestureSwipeEvent* to)
891{
892    *to = *from;
893
894    swaps(&to->sequenceNumber);
895    swapl(&to->length);
896    swaps(&to->evtype);
897    swaps(&to->deviceid);
898    swapl(&to->time);
899    swapl(&to->detail);
900    swapl(&to->root);
901    swapl(&to->event);
902    swapl(&to->child);
903    swapl(&to->root_x);
904    swapl(&to->root_y);
905    swapl(&to->event_x);
906    swapl(&to->event_y);
907
908    swapl(&to->delta_x);
909    swapl(&to->delta_y);
910    swapl(&to->delta_unaccel_x);
911    swapl(&to->delta_unaccel_y);
912    swaps(&to->sourceid);
913
914    swapl(&to->mods.base_mods);
915    swapl(&to->mods.latched_mods);
916    swapl(&to->mods.locked_mods);
917    swapl(&to->mods.effective_mods);
918    swapl(&to->flags);
919}
920
921/** Event swapping function for XI2 events. */
922void _X_COLD
923XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
924{
925    switch (from->evtype) {
926    case XI_Enter:
927    case XI_Leave:
928    case XI_FocusIn:
929    case XI_FocusOut:
930        SDeviceLeaveNotifyEvent((xXILeaveEvent *) from, (xXILeaveEvent *) to);
931        break;
932    case XI_DeviceChanged:
933        SDeviceChangedEvent((xXIDeviceChangedEvent *) from,
934                            (xXIDeviceChangedEvent *) to);
935        break;
936    case XI_HierarchyChanged:
937        SDeviceHierarchyEvent((xXIHierarchyEvent *) from,
938                              (xXIHierarchyEvent *) to);
939        break;
940    case XI_PropertyEvent:
941        SXIPropertyEvent((xXIPropertyEvent *) from, (xXIPropertyEvent *) to);
942        break;
943    case XI_Motion:
944    case XI_KeyPress:
945    case XI_KeyRelease:
946    case XI_ButtonPress:
947    case XI_ButtonRelease:
948    case XI_TouchBegin:
949    case XI_TouchUpdate:
950    case XI_TouchEnd:
951        SDeviceEvent((xXIDeviceEvent *) from, (xXIDeviceEvent *) to);
952        break;
953    case XI_TouchOwnership:
954        STouchOwnershipEvent((xXITouchOwnershipEvent *) from,
955                             (xXITouchOwnershipEvent *) to);
956        break;
957    case XI_RawMotion:
958    case XI_RawKeyPress:
959    case XI_RawKeyRelease:
960    case XI_RawButtonPress:
961    case XI_RawButtonRelease:
962    case XI_RawTouchBegin:
963    case XI_RawTouchUpdate:
964    case XI_RawTouchEnd:
965        SRawEvent((xXIRawEvent *) from, (xXIRawEvent *) to);
966        break;
967    case XI_BarrierHit:
968    case XI_BarrierLeave:
969        SBarrierEvent((xXIBarrierEvent *) from,
970                      (xXIBarrierEvent *) to);
971        break;
972    case XI_GesturePinchBegin:
973    case XI_GesturePinchUpdate:
974    case XI_GesturePinchEnd:
975        SGesturePinchEvent((xXIGesturePinchEvent*) from,
976                           (xXIGesturePinchEvent*) to);
977        break;
978    case XI_GestureSwipeBegin:
979    case XI_GestureSwipeUpdate:
980    case XI_GestureSwipeEnd:
981        SGestureSwipeEvent((xXIGestureSwipeEvent*) from,
982                           (xXIGestureSwipeEvent*) to);
983        break;
984    default:
985        ErrorF("[Xi] Unknown event type to swap. This is a bug.\n");
986        break;
987    }
988}
989
990/**************************************************************************
991 *
992 * Record an event mask where there is no unique corresponding event type.
993 * We can't call SetMaskForEvent, since that would clobber the existing
994 * mask for that event.  MotionHint and ButtonMotion are examples.
995 *
996 * Since extension event types will never be less than 64, we can use
997 * 0-63 in the EventInfo array as the "type" to be used to look up this
998 * mask.  This means that the corresponding macros such as
999 * DevicePointerMotionHint must have access to the same constants.
1000 *
1001 */
1002
1003static void
1004SetEventInfo(Mask mask, int constant)
1005{
1006    EventInfo[ExtEventIndex].mask = mask;
1007    EventInfo[ExtEventIndex++].type = constant;
1008}
1009
1010/**************************************************************************
1011 *
1012 * Assign the specified mask to the specified event.
1013 *
1014 */
1015
1016static void
1017SetMaskForExtEvent(Mask mask, int event)
1018{
1019    int i;
1020
1021    EventInfo[ExtEventIndex].mask = mask;
1022    EventInfo[ExtEventIndex++].type = event;
1023
1024    if ((event < LASTEvent) || (event >= 128))
1025        FatalError("MaskForExtensionEvent: bogus event number");
1026
1027    for (i = 0; i < MAXDEVICES; i++)
1028        SetMaskForEvent(i, mask, event);
1029}
1030
1031/************************************************************************
1032 *
1033 * This function sets up extension event types and masks.
1034 *
1035 */
1036
1037static void
1038FixExtensionEvents(ExtensionEntry * extEntry)
1039{
1040    DeviceValuator = extEntry->eventBase;
1041    DeviceKeyPress = DeviceValuator + 1;
1042    DeviceKeyRelease = DeviceKeyPress + 1;
1043    DeviceButtonPress = DeviceKeyRelease + 1;
1044    DeviceButtonRelease = DeviceButtonPress + 1;
1045    DeviceMotionNotify = DeviceButtonRelease + 1;
1046    DeviceFocusIn = DeviceMotionNotify + 1;
1047    DeviceFocusOut = DeviceFocusIn + 1;
1048    ProximityIn = DeviceFocusOut + 1;
1049    ProximityOut = ProximityIn + 1;
1050    DeviceStateNotify = ProximityOut + 1;
1051    DeviceMappingNotify = DeviceStateNotify + 1;
1052    ChangeDeviceNotify = DeviceMappingNotify + 1;
1053    DeviceKeyStateNotify = ChangeDeviceNotify + 1;
1054    DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
1055    DevicePresenceNotify = DeviceButtonStateNotify + 1;
1056    DevicePropertyNotify = DevicePresenceNotify + 1;
1057
1058    event_base[KeyClass] = DeviceKeyPress;
1059    event_base[ButtonClass] = DeviceButtonPress;
1060    event_base[ValuatorClass] = DeviceMotionNotify;
1061    event_base[ProximityClass] = ProximityIn;
1062    event_base[FocusClass] = DeviceFocusIn;
1063    event_base[OtherClass] = DeviceStateNotify;
1064
1065    BadDevice += extEntry->errorBase;
1066    BadEvent += extEntry->errorBase;
1067    BadMode += extEntry->errorBase;
1068    DeviceBusy += extEntry->errorBase;
1069    BadClass += extEntry->errorBase;
1070
1071    SetMaskForExtEvent(KeyPressMask, DeviceKeyPress);
1072    SetCriticalEvent(DeviceKeyPress);
1073
1074    SetMaskForExtEvent(KeyReleaseMask, DeviceKeyRelease);
1075    SetCriticalEvent(DeviceKeyRelease);
1076
1077    SetMaskForExtEvent(ButtonPressMask, DeviceButtonPress);
1078    SetCriticalEvent(DeviceButtonPress);
1079
1080    SetMaskForExtEvent(ButtonReleaseMask, DeviceButtonRelease);
1081    SetCriticalEvent(DeviceButtonRelease);
1082
1083    SetMaskForExtEvent(DeviceProximityMask, ProximityIn);
1084    SetMaskForExtEvent(DeviceProximityMask, ProximityOut);
1085
1086    SetMaskForExtEvent(DeviceStateNotifyMask, DeviceStateNotify);
1087
1088    SetMaskForExtEvent(PointerMotionMask, DeviceMotionNotify);
1089    SetCriticalEvent(DeviceMotionNotify);
1090
1091    SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint);
1092    SetEventInfo(DeviceButton1MotionMask, _deviceButton1Motion);
1093    SetEventInfo(DeviceButton2MotionMask, _deviceButton2Motion);
1094    SetEventInfo(DeviceButton3MotionMask, _deviceButton3Motion);
1095    SetEventInfo(DeviceButton4MotionMask, _deviceButton4Motion);
1096    SetEventInfo(DeviceButton5MotionMask, _deviceButton5Motion);
1097    SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
1098
1099    SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
1100    SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut);
1101
1102    SetMaskForExtEvent(DeviceMappingNotifyMask, DeviceMappingNotify);
1103    SetMaskForExtEvent(ChangeDeviceNotifyMask, ChangeDeviceNotify);
1104
1105    SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab);
1106    SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
1107    SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
1108    SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify);
1109
1110    SetEventInfo(0, _noExtensionEvent);
1111}
1112
1113/************************************************************************
1114 *
1115 * This function restores extension event types and masks to their
1116 * initial state.
1117 *
1118 */
1119
1120static void
1121RestoreExtensionEvents(void)
1122{
1123    int i, j;
1124
1125    IReqCode = 0;
1126    IEventBase = 0;
1127
1128    for (i = 0; i < ExtEventIndex - 1; i++) {
1129        if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128)) {
1130            for (j = 0; j < MAXDEVICES; j++)
1131                SetMaskForEvent(j, 0, EventInfo[i].type);
1132        }
1133        EventInfo[i].mask = 0;
1134        EventInfo[i].type = 0;
1135    }
1136    ExtEventIndex = 0;
1137    DeviceValuator = 0;
1138    DeviceKeyPress = 1;
1139    DeviceKeyRelease = 2;
1140    DeviceButtonPress = 3;
1141    DeviceButtonRelease = 4;
1142    DeviceMotionNotify = 5;
1143    DeviceFocusIn = 6;
1144    DeviceFocusOut = 7;
1145    ProximityIn = 8;
1146    ProximityOut = 9;
1147    DeviceStateNotify = 10;
1148    DeviceMappingNotify = 11;
1149    ChangeDeviceNotify = 12;
1150    DeviceKeyStateNotify = 13;
1151    DeviceButtonStateNotify = 13;
1152    DevicePresenceNotify = 14;
1153    DevicePropertyNotify = 15;
1154
1155    BadDevice = 0;
1156    BadEvent = 1;
1157    BadMode = 2;
1158    DeviceBusy = 3;
1159    BadClass = 4;
1160
1161}
1162
1163/***********************************************************************
1164 *
1165 * IResetProc.
1166 * Remove reply-swapping routine.
1167 * Remove event-swapping routine.
1168 *
1169 */
1170
1171static void
1172IResetProc(ExtensionEntry * unused)
1173{
1174    ReplySwapVector[IReqCode] = ReplyNotSwappd;
1175    EventSwapVector[DeviceValuator] = NotImplemented;
1176    EventSwapVector[DeviceKeyPress] = NotImplemented;
1177    EventSwapVector[DeviceKeyRelease] = NotImplemented;
1178    EventSwapVector[DeviceButtonPress] = NotImplemented;
1179    EventSwapVector[DeviceButtonRelease] = NotImplemented;
1180    EventSwapVector[DeviceMotionNotify] = NotImplemented;
1181    EventSwapVector[DeviceFocusIn] = NotImplemented;
1182    EventSwapVector[DeviceFocusOut] = NotImplemented;
1183    EventSwapVector[ProximityIn] = NotImplemented;
1184    EventSwapVector[ProximityOut] = NotImplemented;
1185    EventSwapVector[DeviceStateNotify] = NotImplemented;
1186    EventSwapVector[DeviceKeyStateNotify] = NotImplemented;
1187    EventSwapVector[DeviceButtonStateNotify] = NotImplemented;
1188    EventSwapVector[DeviceMappingNotify] = NotImplemented;
1189    EventSwapVector[ChangeDeviceNotify] = NotImplemented;
1190    EventSwapVector[DevicePresenceNotify] = NotImplemented;
1191    EventSwapVector[DevicePropertyNotify] = NotImplemented;
1192    RestoreExtensionEvents();
1193
1194    free(xi_all_devices.name);
1195    free(xi_all_master_devices.name);
1196
1197    XIBarrierReset();
1198}
1199
1200/***********************************************************************
1201 *
1202 * Assign an id and type to an input device.
1203 *
1204 */
1205
1206void
1207AssignTypeAndName(DeviceIntPtr dev, Atom type, const char *name)
1208{
1209    dev->xinput_type = type;
1210    dev->name = strdup(name);
1211}
1212
1213/***********************************************************************
1214 *
1215 * Make device type atoms.
1216 *
1217 */
1218
1219static void
1220MakeDeviceTypeAtoms(void)
1221{
1222    int i;
1223
1224    for (i = 0; i < NUMTYPES; i++)
1225        dev_type[i].type =
1226            MakeAtom(dev_type[i].name, strlen(dev_type[i].name), 1);
1227}
1228
1229/*****************************************************************************
1230 *
1231 *	SEventIDispatch
1232 *
1233 *	Swap any events defined in this extension.
1234 */
1235#define DO_SWAP(func,type) func ((type *)from, (type *)to)
1236
1237static void _X_COLD
1238SEventIDispatch(xEvent *from, xEvent *to)
1239{
1240    int type = from->u.u.type & 0177;
1241
1242    if (type == DeviceValuator)
1243        DO_SWAP(SEventDeviceValuator, deviceValuator);
1244    else if (type == DeviceKeyPress) {
1245        SKeyButtonPtrEvent(from, to);
1246        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1247    }
1248    else if (type == DeviceKeyRelease) {
1249        SKeyButtonPtrEvent(from, to);
1250        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1251    }
1252    else if (type == DeviceButtonPress) {
1253        SKeyButtonPtrEvent(from, to);
1254        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1255    }
1256    else if (type == DeviceButtonRelease) {
1257        SKeyButtonPtrEvent(from, to);
1258        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1259    }
1260    else if (type == DeviceMotionNotify) {
1261        SKeyButtonPtrEvent(from, to);
1262        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1263    }
1264    else if (type == DeviceFocusIn)
1265        DO_SWAP(SEventFocus, deviceFocus);
1266    else if (type == DeviceFocusOut)
1267        DO_SWAP(SEventFocus, deviceFocus);
1268    else if (type == ProximityIn) {
1269        SKeyButtonPtrEvent(from, to);
1270        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1271    }
1272    else if (type == ProximityOut) {
1273        SKeyButtonPtrEvent(from, to);
1274        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1275    }
1276    else if (type == DeviceStateNotify)
1277        DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify);
1278    else if (type == DeviceKeyStateNotify)
1279        DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify);
1280    else if (type == DeviceButtonStateNotify)
1281        DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify);
1282    else if (type == DeviceMappingNotify)
1283        DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify);
1284    else if (type == ChangeDeviceNotify)
1285        DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify);
1286    else if (type == DevicePresenceNotify)
1287        DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify);
1288    else if (type == DevicePropertyNotify)
1289        DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify);
1290    else {
1291        FatalError("XInputExtension: Impossible event!\n");
1292    }
1293}
1294
1295/**********************************************************************
1296 *
1297 * IExtensionInit - initialize the input extension.
1298 *
1299 * Called from InitExtensions in main() or from QueryExtension() if the
1300 * extension is dynamically loaded.
1301 *
1302 * This extension has several events and errors.
1303 *
1304 * XI is mandatory nowadays, so if we fail to init XI, we die.
1305 */
1306
1307void
1308XInputExtensionInit(void)
1309{
1310    ExtensionEntry *extEntry;
1311
1312    XExtensionVersion thisversion = { XI_Present,
1313        SERVER_XI_MAJOR_VERSION,
1314        SERVER_XI_MINOR_VERSION,
1315    };
1316
1317    if (!dixRegisterPrivateKey
1318        (&XIClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XIClientRec)))
1319        FatalError("Cannot request private for XI.\n");
1320
1321    if (!XIBarrierInit())
1322        FatalError("Could not initialize barriers.\n");
1323
1324    extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
1325                            SProcIDispatch, IResetProc, StandardMinorOpcode);
1326    if (extEntry) {
1327        IReqCode = extEntry->base;
1328        IEventBase = extEntry->eventBase;
1329        XIVersion = thisversion;
1330        MakeDeviceTypeAtoms();
1331        RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone,
1332                                               "INPUTCLIENT");
1333        if (!RT_INPUTCLIENT)
1334            FatalError("Failed to add resource type for XI.\n");
1335        FixExtensionEvents(extEntry);
1336        ReplySwapVector[IReqCode] = (ReplySwapPtr) SReplyIDispatch;
1337        EventSwapVector[DeviceValuator] = SEventIDispatch;
1338        EventSwapVector[DeviceKeyPress] = SEventIDispatch;
1339        EventSwapVector[DeviceKeyRelease] = SEventIDispatch;
1340        EventSwapVector[DeviceButtonPress] = SEventIDispatch;
1341        EventSwapVector[DeviceButtonRelease] = SEventIDispatch;
1342        EventSwapVector[DeviceMotionNotify] = SEventIDispatch;
1343        EventSwapVector[DeviceFocusIn] = SEventIDispatch;
1344        EventSwapVector[DeviceFocusOut] = SEventIDispatch;
1345        EventSwapVector[ProximityIn] = SEventIDispatch;
1346        EventSwapVector[ProximityOut] = SEventIDispatch;
1347        EventSwapVector[DeviceStateNotify] = SEventIDispatch;
1348        EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch;
1349        EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch;
1350        EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
1351        EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
1352        EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
1353
1354        GERegisterExtension(IReqCode, XI2EventSwap);
1355
1356        memset(&xi_all_devices, 0, sizeof(xi_all_devices));
1357        memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices));
1358        xi_all_devices.id = XIAllDevices;
1359        xi_all_devices.name = strdup("XIAllDevices");
1360        xi_all_master_devices.id = XIAllMasterDevices;
1361        xi_all_master_devices.name = strdup("XIAllMasterDevices");
1362
1363        inputInfo.all_devices = &xi_all_devices;
1364        inputInfo.all_master_devices = &xi_all_master_devices;
1365
1366        XIResetProperties();
1367    }
1368    else {
1369        FatalError("IExtensionInit: AddExtensions failed\n");
1370    }
1371}
1372