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