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