extinit.c revision 35c4bbdf
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
383static void
384XIClientCallback(CallbackListPtr *list, void *closure, void *data)
385{
386    NewClientInfoRec *clientinfo = (NewClientInfoRec *) data;
387    ClientPtr pClient = clientinfo->client;
388    XIClientPtr pXIClient;
389
390    pXIClient = dixLookupPrivate(&pClient->devPrivates, XIClientPrivateKey);
391    pXIClient->major_version = 0;
392    pXIClient->minor_version = 0;
393}
394
395/*************************************************************************
396 *
397 * ProcIDispatch - main dispatch routine for requests to this extension.
398 * This routine is used if server and client have the same byte ordering.
399 *
400 */
401
402static int
403ProcIDispatch(ClientPtr client)
404{
405    REQUEST(xReq);
406    if (stuff->data >= ARRAY_SIZE(ProcIVector) || !ProcIVector[stuff->data])
407        return BadRequest;
408
409    return (*ProcIVector[stuff->data]) (client);
410}
411
412/*******************************************************************************
413 *
414 * SProcXDispatch
415 *
416 * Main swapped dispatch routine for requests to this extension.
417 * This routine is used if server and client do not have the same byte ordering.
418 *
419 */
420
421static int
422SProcIDispatch(ClientPtr client)
423{
424    REQUEST(xReq);
425    if (stuff->data >= ARRAY_SIZE(SProcIVector) || !SProcIVector[stuff->data])
426        return BadRequest;
427
428    return (*SProcIVector[stuff->data]) (client);
429}
430
431/**********************************************************************
432 *
433 * SReplyIDispatch
434 * Swap any replies defined in this extension.
435 *
436 */
437
438static void
439SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
440{
441    /* All we look at is the type field */
442    /* This is common to all replies    */
443    if (rep->RepType == X_GetExtensionVersion)
444        SRepXGetExtensionVersion(client, len,
445                                 (xGetExtensionVersionReply *) rep);
446    else if (rep->RepType == X_ListInputDevices)
447        SRepXListInputDevices(client, len, (xListInputDevicesReply *) rep);
448    else if (rep->RepType == X_OpenDevice)
449        SRepXOpenDevice(client, len, (xOpenDeviceReply *) rep);
450    else if (rep->RepType == X_SetDeviceMode)
451        SRepXSetDeviceMode(client, len, (xSetDeviceModeReply *) rep);
452    else if (rep->RepType == X_GetSelectedExtensionEvents)
453        SRepXGetSelectedExtensionEvents(client, len,
454                                        (xGetSelectedExtensionEventsReply *)
455                                        rep);
456    else if (rep->RepType == X_GetDeviceDontPropagateList)
457        SRepXGetDeviceDontPropagateList(client, len,
458                                        (xGetDeviceDontPropagateListReply *)
459                                        rep);
460    else if (rep->RepType == X_GetDeviceMotionEvents)
461        SRepXGetDeviceMotionEvents(client, len,
462                                   (xGetDeviceMotionEventsReply *) rep);
463    else if (rep->RepType == X_GrabDevice)
464        SRepXGrabDevice(client, len, (xGrabDeviceReply *) rep);
465    else if (rep->RepType == X_GetDeviceFocus)
466        SRepXGetDeviceFocus(client, len, (xGetDeviceFocusReply *) rep);
467    else if (rep->RepType == X_GetFeedbackControl)
468        SRepXGetFeedbackControl(client, len, (xGetFeedbackControlReply *) rep);
469    else if (rep->RepType == X_GetDeviceKeyMapping)
470        SRepXGetDeviceKeyMapping(client, len,
471                                 (xGetDeviceKeyMappingReply *) rep);
472    else if (rep->RepType == X_GetDeviceModifierMapping)
473        SRepXGetDeviceModifierMapping(client, len,
474                                      (xGetDeviceModifierMappingReply *) rep);
475    else if (rep->RepType == X_SetDeviceModifierMapping)
476        SRepXSetDeviceModifierMapping(client, len,
477                                      (xSetDeviceModifierMappingReply *) rep);
478    else if (rep->RepType == X_GetDeviceButtonMapping)
479        SRepXGetDeviceButtonMapping(client, len,
480                                    (xGetDeviceButtonMappingReply *) rep);
481    else if (rep->RepType == X_SetDeviceButtonMapping)
482        SRepXSetDeviceButtonMapping(client, len,
483                                    (xSetDeviceButtonMappingReply *) rep);
484    else if (rep->RepType == X_QueryDeviceState)
485        SRepXQueryDeviceState(client, len, (xQueryDeviceStateReply *) rep);
486    else if (rep->RepType == X_SetDeviceValuators)
487        SRepXSetDeviceValuators(client, len, (xSetDeviceValuatorsReply *) rep);
488    else if (rep->RepType == X_GetDeviceControl)
489        SRepXGetDeviceControl(client, len, (xGetDeviceControlReply *) rep);
490    else if (rep->RepType == X_ChangeDeviceControl)
491        SRepXChangeDeviceControl(client, len,
492                                 (xChangeDeviceControlReply *) rep);
493    else if (rep->RepType == X_ListDeviceProperties)
494        SRepXListDeviceProperties(client, len,
495                                  (xListDevicePropertiesReply *) rep);
496    else if (rep->RepType == X_GetDeviceProperty)
497        SRepXGetDeviceProperty(client, len, (xGetDevicePropertyReply *) rep);
498    else if (rep->RepType == X_XIQueryPointer)
499        SRepXIQueryPointer(client, len, (xXIQueryPointerReply *) rep);
500    else if (rep->RepType == X_XIGetClientPointer)
501        SRepXIGetClientPointer(client, len, (xXIGetClientPointerReply *) rep);
502    else if (rep->RepType == X_XIQueryVersion)
503        SRepXIQueryVersion(client, len, (xXIQueryVersionReply *) rep);
504    else if (rep->RepType == X_XIQueryDevice)
505        SRepXIQueryDevice(client, len, (xXIQueryDeviceReply *) rep);
506    else if (rep->RepType == X_XIGrabDevice)
507        SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
508    else if (rep->RepType == X_XIPassiveGrabDevice)
509        SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
510    else if (rep->RepType == X_XIListProperties)
511        SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
512    else if (rep->RepType == X_XIGetProperty)
513        SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
514    else if (rep->RepType == X_XIGetSelectedEvents)
515        SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep);
516    else if (rep->RepType == X_XIGetFocus)
517        SRepXIGetFocus(client, len, (xXIGetFocusReply *) rep);
518    else {
519        FatalError("XINPUT confused sending swapped reply");
520    }
521}
522
523/************************************************************************
524 *
525 * This function swaps the DeviceValuator event.
526 *
527 */
528
529static void
530SEventDeviceValuator(deviceValuator * from, deviceValuator * to)
531{
532    int i;
533    INT32 *ip B32;
534
535    *to = *from;
536    swaps(&to->sequenceNumber);
537    swaps(&to->device_state);
538    ip = &to->valuator0;
539    for (i = 0; i < 6; i++) {
540        swapl(ip + i);
541    }
542}
543
544static void
545SEventFocus(deviceFocus * from, deviceFocus * to)
546{
547    *to = *from;
548    swaps(&to->sequenceNumber);
549    swapl(&to->time);
550    swapl(&to->window);
551}
552
553static void
554SDeviceStateNotifyEvent(deviceStateNotify * from, deviceStateNotify * to)
555{
556    int i;
557    INT32 *ip B32;
558
559    *to = *from;
560    swaps(&to->sequenceNumber);
561    swapl(&to->time);
562    ip = &to->valuator0;
563    for (i = 0; i < 3; i++) {
564        swapl(ip + i);
565    }
566}
567
568static void
569SDeviceKeyStateNotifyEvent(deviceKeyStateNotify * from,
570                           deviceKeyStateNotify * to)
571{
572    *to = *from;
573    swaps(&to->sequenceNumber);
574}
575
576static void
577SDeviceButtonStateNotifyEvent(deviceButtonStateNotify * from,
578                              deviceButtonStateNotify * to)
579{
580    *to = *from;
581    swaps(&to->sequenceNumber);
582}
583
584static void
585SChangeDeviceNotifyEvent(changeDeviceNotify * from, changeDeviceNotify * to)
586{
587    *to = *from;
588    swaps(&to->sequenceNumber);
589    swapl(&to->time);
590}
591
592static void
593SDeviceMappingNotifyEvent(deviceMappingNotify * from, deviceMappingNotify * to)
594{
595    *to = *from;
596    swaps(&to->sequenceNumber);
597    swapl(&to->time);
598}
599
600static void
601SDevicePresenceNotifyEvent(devicePresenceNotify * from,
602                           devicePresenceNotify * to)
603{
604    *to = *from;
605    swaps(&to->sequenceNumber);
606    swapl(&to->time);
607    swaps(&to->control);
608}
609
610static void
611SDevicePropertyNotifyEvent(devicePropertyNotify * from,
612                           devicePropertyNotify * to)
613{
614    *to = *from;
615    swaps(&to->sequenceNumber);
616    swapl(&to->time);
617    swapl(&to->atom);
618}
619
620static void
621SDeviceLeaveNotifyEvent(xXILeaveEvent * from, xXILeaveEvent * to)
622{
623    *to = *from;
624    swaps(&to->sequenceNumber);
625    swapl(&to->length);
626    swaps(&to->evtype);
627    swaps(&to->deviceid);
628    swapl(&to->time);
629    swapl(&to->root);
630    swapl(&to->event);
631    swapl(&to->child);
632    swapl(&to->root_x);
633    swapl(&to->root_y);
634    swapl(&to->event_x);
635    swapl(&to->event_y);
636    swaps(&to->sourceid);
637    swaps(&to->buttons_len);
638    swapl(&to->mods.base_mods);
639    swapl(&to->mods.latched_mods);
640    swapl(&to->mods.locked_mods);
641}
642
643static void
644SDeviceChangedEvent(xXIDeviceChangedEvent * from, xXIDeviceChangedEvent * to)
645{
646    int i, j;
647    xXIAnyInfo *any;
648
649    *to = *from;
650    memcpy(&to[1], &from[1], from->length * 4);
651
652    any = (xXIAnyInfo *) &to[1];
653    for (i = 0; i < to->num_classes; i++) {
654        int length = any->length;
655
656        switch (any->type) {
657        case KeyClass:
658        {
659            xXIKeyInfo *ki = (xXIKeyInfo *) any;
660            uint32_t *key = (uint32_t *) &ki[1];
661
662            for (j = 0; j < ki->num_keycodes; j++, key++)
663                swapl(key);
664            swaps(&ki->num_keycodes);
665        }
666            break;
667        case ButtonClass:
668        {
669            xXIButtonInfo *bi = (xXIButtonInfo *) any;
670            Atom *labels = (Atom *) ((char *) bi + sizeof(xXIButtonInfo) +
671                                     pad_to_int32(bits_to_bytes
672                                                  (bi->num_buttons)));
673            for (j = 0; j < bi->num_buttons; j++)
674                swapl(&labels[j]);
675            swaps(&bi->num_buttons);
676        }
677            break;
678        case ValuatorClass:
679        {
680            xXIValuatorInfo *ai = (xXIValuatorInfo *) any;
681
682            swapl(&ai->label);
683            swapl(&ai->min.integral);
684            swapl(&ai->min.frac);
685            swapl(&ai->max.integral);
686            swapl(&ai->max.frac);
687            swapl(&ai->resolution);
688            swaps(&ai->number);
689        }
690            break;
691        }
692
693        swaps(&any->type);
694        swaps(&any->length);
695        swaps(&any->sourceid);
696
697        any = (xXIAnyInfo *) ((char *) any + length * 4);
698    }
699
700    swaps(&to->sequenceNumber);
701    swapl(&to->length);
702    swaps(&to->evtype);
703    swaps(&to->deviceid);
704    swapl(&to->time);
705    swaps(&to->num_classes);
706    swaps(&to->sourceid);
707
708}
709
710static void
711SDeviceEvent(xXIDeviceEvent * from, xXIDeviceEvent * to)
712{
713    int i;
714    char *ptr;
715    char *vmask;
716
717    memcpy(to, from, sizeof(xEvent) + from->length * 4);
718
719    swaps(&to->sequenceNumber);
720    swapl(&to->length);
721    swaps(&to->evtype);
722    swaps(&to->deviceid);
723    swapl(&to->time);
724    swapl(&to->detail);
725    swapl(&to->root);
726    swapl(&to->event);
727    swapl(&to->child);
728    swapl(&to->root_x);
729    swapl(&to->root_y);
730    swapl(&to->event_x);
731    swapl(&to->event_y);
732    swaps(&to->buttons_len);
733    swaps(&to->valuators_len);
734    swaps(&to->sourceid);
735    swapl(&to->mods.base_mods);
736    swapl(&to->mods.latched_mods);
737    swapl(&to->mods.locked_mods);
738    swapl(&to->mods.effective_mods);
739    swapl(&to->flags);
740
741    ptr = (char *) (&to[1]);
742    ptr += from->buttons_len * 4;
743    vmask = ptr;                /* valuator mask */
744    ptr += from->valuators_len * 4;
745    for (i = 0; i < from->valuators_len * 32; i++) {
746        if (BitIsOn(vmask, i)) {
747            swapl(((uint32_t *) ptr));
748            ptr += 4;
749            swapl(((uint32_t *) ptr));
750            ptr += 4;
751        }
752    }
753}
754
755static void
756SDeviceHierarchyEvent(xXIHierarchyEvent * from, xXIHierarchyEvent * to)
757{
758    int i;
759    xXIHierarchyInfo *info;
760
761    *to = *from;
762    memcpy(&to[1], &from[1], from->length * 4);
763    swaps(&to->sequenceNumber);
764    swapl(&to->length);
765    swaps(&to->evtype);
766    swaps(&to->deviceid);
767    swapl(&to->time);
768    swapl(&to->flags);
769    swaps(&to->num_info);
770
771    info = (xXIHierarchyInfo *) &to[1];
772    for (i = 0; i < from->num_info; i++) {
773        swaps(&info->deviceid);
774        swaps(&info->attachment);
775        info++;
776    }
777}
778
779static void
780SXIPropertyEvent(xXIPropertyEvent * from, xXIPropertyEvent * to)
781{
782    *to = *from;
783    swaps(&to->sequenceNumber);
784    swapl(&to->length);
785    swaps(&to->evtype);
786    swaps(&to->deviceid);
787    swapl(&to->property);
788}
789
790static void
791SRawEvent(xXIRawEvent * from, xXIRawEvent * to)
792{
793    int i;
794    FP3232 *values;
795    unsigned char *mask;
796
797    memcpy(to, from, sizeof(xEvent) + from->length * 4);
798
799    swaps(&to->sequenceNumber);
800    swapl(&to->length);
801    swaps(&to->evtype);
802    swaps(&to->deviceid);
803    swapl(&to->time);
804    swapl(&to->detail);
805
806    mask = (unsigned char *) &to[1];
807    values = (FP3232 *) (mask + from->valuators_len * 4);
808
809    for (i = 0; i < from->valuators_len * 4 * 8; i++) {
810        if (BitIsOn(mask, i)) {
811            /* for each bit set there are two FP3232 values on the wire, in
812             * the order abcABC for data and data_raw. Here we swap as if
813             * they were in aAbBcC order because it's easier and really
814             * doesn't matter.
815             */
816            swapl(&values->integral);
817            swapl(&values->frac);
818            values++;
819            swapl(&values->integral);
820            swapl(&values->frac);
821            values++;
822        }
823    }
824
825    swaps(&to->valuators_len);
826}
827
828static void
829STouchOwnershipEvent(xXITouchOwnershipEvent * from, xXITouchOwnershipEvent * to)
830{
831    *to = *from;
832    swaps(&to->sequenceNumber);
833    swapl(&to->length);
834    swaps(&to->evtype);
835    swaps(&to->deviceid);
836    swapl(&to->time);
837    swaps(&to->sourceid);
838    swapl(&to->touchid);
839    swapl(&to->flags);
840    swapl(&to->root);
841    swapl(&to->event);
842    swapl(&to->child);
843}
844
845static void
846SBarrierEvent(xXIBarrierEvent * from,
847              xXIBarrierEvent * to) {
848
849    *to = *from;
850
851    swaps(&to->sequenceNumber);
852    swapl(&to->length);
853    swaps(&to->evtype);
854    swapl(&to->time);
855    swaps(&to->deviceid);
856    swaps(&to->sourceid);
857    swapl(&to->event);
858    swapl(&to->root);
859    swapl(&to->root_x);
860    swapl(&to->root_y);
861
862    swapl(&to->dx.integral);
863    swapl(&to->dx.frac);
864    swapl(&to->dy.integral);
865    swapl(&to->dy.frac);
866    swapl(&to->dtime);
867    swapl(&to->barrier);
868    swapl(&to->eventid);
869}
870
871/** Event swapping function for XI2 events. */
872void
873XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
874{
875    switch (from->evtype) {
876    case XI_Enter:
877    case XI_Leave:
878    case XI_FocusIn:
879    case XI_FocusOut:
880        SDeviceLeaveNotifyEvent((xXILeaveEvent *) from, (xXILeaveEvent *) to);
881        break;
882    case XI_DeviceChanged:
883        SDeviceChangedEvent((xXIDeviceChangedEvent *) from,
884                            (xXIDeviceChangedEvent *) to);
885        break;
886    case XI_HierarchyChanged:
887        SDeviceHierarchyEvent((xXIHierarchyEvent *) from,
888                              (xXIHierarchyEvent *) to);
889        break;
890    case XI_PropertyEvent:
891        SXIPropertyEvent((xXIPropertyEvent *) from, (xXIPropertyEvent *) to);
892        break;
893    case XI_Motion:
894    case XI_KeyPress:
895    case XI_KeyRelease:
896    case XI_ButtonPress:
897    case XI_ButtonRelease:
898    case XI_TouchBegin:
899    case XI_TouchUpdate:
900    case XI_TouchEnd:
901        SDeviceEvent((xXIDeviceEvent *) from, (xXIDeviceEvent *) to);
902        break;
903    case XI_TouchOwnership:
904        STouchOwnershipEvent((xXITouchOwnershipEvent *) from,
905                             (xXITouchOwnershipEvent *) to);
906        break;
907    case XI_RawMotion:
908    case XI_RawKeyPress:
909    case XI_RawKeyRelease:
910    case XI_RawButtonPress:
911    case XI_RawButtonRelease:
912    case XI_RawTouchBegin:
913    case XI_RawTouchUpdate:
914    case XI_RawTouchEnd:
915        SRawEvent((xXIRawEvent *) from, (xXIRawEvent *) to);
916        break;
917    case XI_BarrierHit:
918    case XI_BarrierLeave:
919        SBarrierEvent((xXIBarrierEvent *) from,
920                      (xXIBarrierEvent *) to);
921        break;
922    default:
923        ErrorF("[Xi] Unknown event type to swap. This is a bug.\n");
924        break;
925    }
926}
927
928/**************************************************************************
929 *
930 * Allow the specified event to have its propagation suppressed.
931 * The default is to not allow suppression of propagation.
932 *
933 */
934
935static void
936AllowPropagateSuppress(Mask mask)
937{
938    int i;
939
940    for (i = 0; i < MAXDEVICES; i++)
941        PropagateMask[i] |= mask;
942}
943
944/**************************************************************************
945 *
946 * Record an event mask where there is no unique corresponding event type.
947 * We can't call SetMaskForEvent, since that would clobber the existing
948 * mask for that event.  MotionHint and ButtonMotion are examples.
949 *
950 * Since extension event types will never be less than 64, we can use
951 * 0-63 in the EventInfo array as the "type" to be used to look up this
952 * mask.  This means that the corresponding macros such as
953 * DevicePointerMotionHint must have access to the same constants.
954 *
955 */
956
957static void
958SetEventInfo(Mask mask, int constant)
959{
960    EventInfo[ExtEventIndex].mask = mask;
961    EventInfo[ExtEventIndex++].type = constant;
962}
963
964/**************************************************************************
965 *
966 * Allow the specified event to be restricted to being selected by one
967 * client at a time.
968 * The default is to allow more than one client to select the event.
969 *
970 */
971
972static void
973SetExclusiveAccess(Mask mask)
974{
975    int i;
976
977    for (i = 0; i < MAXDEVICES; i++)
978        ExtExclusiveMasks[i] |= mask;
979}
980
981/**************************************************************************
982 *
983 * Assign the specified mask to the specified event.
984 *
985 */
986
987static void
988SetMaskForExtEvent(Mask mask, int event)
989{
990    int i;
991
992    EventInfo[ExtEventIndex].mask = mask;
993    EventInfo[ExtEventIndex++].type = event;
994
995    if ((event < LASTEvent) || (event >= 128))
996        FatalError("MaskForExtensionEvent: bogus event number");
997
998    for (i = 0; i < MAXDEVICES; i++)
999        SetMaskForEvent(i, mask, event);
1000}
1001
1002/************************************************************************
1003 *
1004 * This function sets up extension event types and masks.
1005 *
1006 */
1007
1008static void
1009FixExtensionEvents(ExtensionEntry * extEntry)
1010{
1011    DeviceValuator = extEntry->eventBase;
1012    DeviceKeyPress = DeviceValuator + 1;
1013    DeviceKeyRelease = DeviceKeyPress + 1;
1014    DeviceButtonPress = DeviceKeyRelease + 1;
1015    DeviceButtonRelease = DeviceButtonPress + 1;
1016    DeviceMotionNotify = DeviceButtonRelease + 1;
1017    DeviceFocusIn = DeviceMotionNotify + 1;
1018    DeviceFocusOut = DeviceFocusIn + 1;
1019    ProximityIn = DeviceFocusOut + 1;
1020    ProximityOut = ProximityIn + 1;
1021    DeviceStateNotify = ProximityOut + 1;
1022    DeviceMappingNotify = DeviceStateNotify + 1;
1023    ChangeDeviceNotify = DeviceMappingNotify + 1;
1024    DeviceKeyStateNotify = ChangeDeviceNotify + 1;
1025    DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
1026    DevicePresenceNotify = DeviceButtonStateNotify + 1;
1027    DevicePropertyNotify = DevicePresenceNotify + 1;
1028
1029    event_base[KeyClass] = DeviceKeyPress;
1030    event_base[ButtonClass] = DeviceButtonPress;
1031    event_base[ValuatorClass] = DeviceMotionNotify;
1032    event_base[ProximityClass] = ProximityIn;
1033    event_base[FocusClass] = DeviceFocusIn;
1034    event_base[OtherClass] = DeviceStateNotify;
1035
1036    BadDevice += extEntry->errorBase;
1037    BadEvent += extEntry->errorBase;
1038    BadMode += extEntry->errorBase;
1039    DeviceBusy += extEntry->errorBase;
1040    BadClass += extEntry->errorBase;
1041
1042    SetMaskForExtEvent(DeviceKeyPressMask, DeviceKeyPress);
1043    AllowPropagateSuppress(DeviceKeyPressMask);
1044    SetCriticalEvent(DeviceKeyPress);
1045
1046    SetMaskForExtEvent(DeviceKeyReleaseMask, DeviceKeyRelease);
1047    AllowPropagateSuppress(DeviceKeyReleaseMask);
1048    SetCriticalEvent(DeviceKeyRelease);
1049
1050    SetMaskForExtEvent(DeviceButtonPressMask, DeviceButtonPress);
1051    AllowPropagateSuppress(DeviceButtonPressMask);
1052    SetCriticalEvent(DeviceButtonPress);
1053
1054    SetMaskForExtEvent(DeviceButtonReleaseMask, DeviceButtonRelease);
1055    AllowPropagateSuppress(DeviceButtonReleaseMask);
1056    SetCriticalEvent(DeviceButtonRelease);
1057
1058    SetMaskForExtEvent(DeviceProximityMask, ProximityIn);
1059    SetMaskForExtEvent(DeviceProximityMask, ProximityOut);
1060
1061    SetMaskForExtEvent(DeviceStateNotifyMask, DeviceStateNotify);
1062
1063    SetMaskForExtEvent(DevicePointerMotionMask, DeviceMotionNotify);
1064    AllowPropagateSuppress(DevicePointerMotionMask);
1065    SetCriticalEvent(DeviceMotionNotify);
1066
1067    SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint);
1068    SetEventInfo(DeviceButton1MotionMask, _deviceButton1Motion);
1069    SetEventInfo(DeviceButton2MotionMask, _deviceButton2Motion);
1070    SetEventInfo(DeviceButton3MotionMask, _deviceButton3Motion);
1071    SetEventInfo(DeviceButton4MotionMask, _deviceButton4Motion);
1072    SetEventInfo(DeviceButton5MotionMask, _deviceButton5Motion);
1073    SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
1074
1075    SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
1076    SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut);
1077
1078    SetMaskForExtEvent(DeviceMappingNotifyMask, DeviceMappingNotify);
1079    SetMaskForExtEvent(ChangeDeviceNotifyMask, ChangeDeviceNotify);
1080
1081    SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab);
1082    SetExclusiveAccess(DeviceButtonGrabMask);
1083
1084    SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
1085    SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
1086    SetMaskForExtEvent(DevicePropertyNotifyMask, DevicePropertyNotify);
1087
1088    SetEventInfo(0, _noExtensionEvent);
1089}
1090
1091/************************************************************************
1092 *
1093 * This function restores extension event types and masks to their
1094 * initial state.
1095 *
1096 */
1097
1098static void
1099RestoreExtensionEvents(void)
1100{
1101    int i, j;
1102
1103    IReqCode = 0;
1104    IEventBase = 0;
1105
1106    for (i = 0; i < ExtEventIndex - 1; i++) {
1107        if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128)) {
1108            for (j = 0; j < MAXDEVICES; j++)
1109                SetMaskForEvent(j, 0, EventInfo[i].type);
1110        }
1111        EventInfo[i].mask = 0;
1112        EventInfo[i].type = 0;
1113    }
1114    ExtEventIndex = 0;
1115    DeviceValuator = 0;
1116    DeviceKeyPress = 1;
1117    DeviceKeyRelease = 2;
1118    DeviceButtonPress = 3;
1119    DeviceButtonRelease = 4;
1120    DeviceMotionNotify = 5;
1121    DeviceFocusIn = 6;
1122    DeviceFocusOut = 7;
1123    ProximityIn = 8;
1124    ProximityOut = 9;
1125    DeviceStateNotify = 10;
1126    DeviceMappingNotify = 11;
1127    ChangeDeviceNotify = 12;
1128    DeviceKeyStateNotify = 13;
1129    DeviceButtonStateNotify = 13;
1130    DevicePresenceNotify = 14;
1131    DevicePropertyNotify = 15;
1132
1133    BadDevice = 0;
1134    BadEvent = 1;
1135    BadMode = 2;
1136    DeviceBusy = 3;
1137    BadClass = 4;
1138
1139}
1140
1141/***********************************************************************
1142 *
1143 * IResetProc.
1144 * Remove reply-swapping routine.
1145 * Remove event-swapping routine.
1146 *
1147 */
1148
1149static void
1150IResetProc(ExtensionEntry * unused)
1151{
1152    ReplySwapVector[IReqCode] = ReplyNotSwappd;
1153    EventSwapVector[DeviceValuator] = NotImplemented;
1154    EventSwapVector[DeviceKeyPress] = NotImplemented;
1155    EventSwapVector[DeviceKeyRelease] = NotImplemented;
1156    EventSwapVector[DeviceButtonPress] = NotImplemented;
1157    EventSwapVector[DeviceButtonRelease] = NotImplemented;
1158    EventSwapVector[DeviceMotionNotify] = NotImplemented;
1159    EventSwapVector[DeviceFocusIn] = NotImplemented;
1160    EventSwapVector[DeviceFocusOut] = NotImplemented;
1161    EventSwapVector[ProximityIn] = NotImplemented;
1162    EventSwapVector[ProximityOut] = NotImplemented;
1163    EventSwapVector[DeviceStateNotify] = NotImplemented;
1164    EventSwapVector[DeviceKeyStateNotify] = NotImplemented;
1165    EventSwapVector[DeviceButtonStateNotify] = NotImplemented;
1166    EventSwapVector[DeviceMappingNotify] = NotImplemented;
1167    EventSwapVector[ChangeDeviceNotify] = NotImplemented;
1168    EventSwapVector[DevicePresenceNotify] = NotImplemented;
1169    EventSwapVector[DevicePropertyNotify] = NotImplemented;
1170    RestoreExtensionEvents();
1171
1172    free(xi_all_devices.name);
1173    free(xi_all_master_devices.name);
1174
1175    XIBarrierReset();
1176}
1177
1178/***********************************************************************
1179 *
1180 * Assign an id and type to an input device.
1181 *
1182 */
1183
1184void
1185AssignTypeAndName(DeviceIntPtr dev, Atom type, const char *name)
1186{
1187    dev->xinput_type = type;
1188    dev->name = strdup(name);
1189}
1190
1191/***********************************************************************
1192 *
1193 * Make device type atoms.
1194 *
1195 */
1196
1197static void
1198MakeDeviceTypeAtoms(void)
1199{
1200    int i;
1201
1202    for (i = 0; i < NUMTYPES; i++)
1203        dev_type[i].type =
1204            MakeAtom(dev_type[i].name, strlen(dev_type[i].name), 1);
1205}
1206
1207/*****************************************************************************
1208 *
1209 *	SEventIDispatch
1210 *
1211 *	Swap any events defined in this extension.
1212 */
1213#define DO_SWAP(func,type) func ((type *)from, (type *)to)
1214
1215static void
1216SEventIDispatch(xEvent *from, xEvent *to)
1217{
1218    int type = from->u.u.type & 0177;
1219
1220    if (type == DeviceValuator)
1221        DO_SWAP(SEventDeviceValuator, deviceValuator);
1222    else if (type == DeviceKeyPress) {
1223        SKeyButtonPtrEvent(from, to);
1224        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1225    }
1226    else if (type == DeviceKeyRelease) {
1227        SKeyButtonPtrEvent(from, to);
1228        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1229    }
1230    else if (type == DeviceButtonPress) {
1231        SKeyButtonPtrEvent(from, to);
1232        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1233    }
1234    else if (type == DeviceButtonRelease) {
1235        SKeyButtonPtrEvent(from, to);
1236        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1237    }
1238    else if (type == DeviceMotionNotify) {
1239        SKeyButtonPtrEvent(from, to);
1240        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1241    }
1242    else if (type == DeviceFocusIn)
1243        DO_SWAP(SEventFocus, deviceFocus);
1244    else if (type == DeviceFocusOut)
1245        DO_SWAP(SEventFocus, deviceFocus);
1246    else if (type == ProximityIn) {
1247        SKeyButtonPtrEvent(from, to);
1248        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1249    }
1250    else if (type == ProximityOut) {
1251        SKeyButtonPtrEvent(from, to);
1252        to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
1253    }
1254    else if (type == DeviceStateNotify)
1255        DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify);
1256    else if (type == DeviceKeyStateNotify)
1257        DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify);
1258    else if (type == DeviceButtonStateNotify)
1259        DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify);
1260    else if (type == DeviceMappingNotify)
1261        DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify);
1262    else if (type == ChangeDeviceNotify)
1263        DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify);
1264    else if (type == DevicePresenceNotify)
1265        DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify);
1266    else if (type == DevicePropertyNotify)
1267        DO_SWAP(SDevicePropertyNotifyEvent, devicePropertyNotify);
1268    else {
1269        FatalError("XInputExtension: Impossible event!\n");
1270    }
1271}
1272
1273/**********************************************************************
1274 *
1275 * IExtensionInit - initialize the input extension.
1276 *
1277 * Called from InitExtensions in main() or from QueryExtension() if the
1278 * extension is dynamically loaded.
1279 *
1280 * This extension has several events and errors.
1281 *
1282 * XI is mandatory nowadays, so if we fail to init XI, we die.
1283 */
1284
1285void
1286XInputExtensionInit(void)
1287{
1288    ExtensionEntry *extEntry;
1289
1290    XExtensionVersion thisversion = { XI_Present,
1291        SERVER_XI_MAJOR_VERSION,
1292        SERVER_XI_MINOR_VERSION,
1293    };
1294
1295    if (!dixRegisterPrivateKey
1296        (&XIClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(XIClientRec)))
1297        FatalError("Cannot request private for XI.\n");
1298
1299    if (!AddCallback(&ClientStateCallback, XIClientCallback, 0))
1300        FatalError("Failed to add callback to XI.\n");
1301
1302    if (!XIBarrierInit())
1303        FatalError("Could not initialize barriers.\n");
1304
1305    extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
1306                            SProcIDispatch, IResetProc, StandardMinorOpcode);
1307    if (extEntry) {
1308        IReqCode = extEntry->base;
1309        IEventBase = extEntry->eventBase;
1310        XIVersion = thisversion;
1311        MakeDeviceTypeAtoms();
1312        RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone,
1313                                               "INPUTCLIENT");
1314        if (!RT_INPUTCLIENT)
1315            FatalError("Failed to add resource type for XI.\n");
1316        FixExtensionEvents(extEntry);
1317        ReplySwapVector[IReqCode] = (ReplySwapPtr) SReplyIDispatch;
1318        EventSwapVector[DeviceValuator] = SEventIDispatch;
1319        EventSwapVector[DeviceKeyPress] = SEventIDispatch;
1320        EventSwapVector[DeviceKeyRelease] = SEventIDispatch;
1321        EventSwapVector[DeviceButtonPress] = SEventIDispatch;
1322        EventSwapVector[DeviceButtonRelease] = SEventIDispatch;
1323        EventSwapVector[DeviceMotionNotify] = SEventIDispatch;
1324        EventSwapVector[DeviceFocusIn] = SEventIDispatch;
1325        EventSwapVector[DeviceFocusOut] = SEventIDispatch;
1326        EventSwapVector[ProximityIn] = SEventIDispatch;
1327        EventSwapVector[ProximityOut] = SEventIDispatch;
1328        EventSwapVector[DeviceStateNotify] = SEventIDispatch;
1329        EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch;
1330        EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch;
1331        EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
1332        EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
1333        EventSwapVector[DevicePresenceNotify] = SEventIDispatch;
1334
1335        GERegisterExtension(IReqCode, XI2EventSwap);
1336
1337        memset(&xi_all_devices, 0, sizeof(xi_all_devices));
1338        memset(&xi_all_master_devices, 0, sizeof(xi_all_master_devices));
1339        xi_all_devices.id = XIAllDevices;
1340        xi_all_devices.name = strdup("XIAllDevices");
1341        xi_all_master_devices.id = XIAllMasterDevices;
1342        xi_all_master_devices.name = strdup("XIAllMasterDevices");
1343
1344        inputInfo.all_devices = &xi_all_devices;
1345        inputInfo.all_master_devices = &xi_all_master_devices;
1346
1347        XIResetProperties();
1348    }
1349    else {
1350        FatalError("IExtensionInit: AddExtensions failed\n");
1351    }
1352}
1353