extinit.c revision 05b261ec
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#define	 NEED_EVENTS
56#define	 NEED_REPLIES
57#ifdef HAVE_DIX_CONFIG_H
58#include <dix-config.h>
59#endif
60
61#include <X11/X.h>
62#include <X11/Xproto.h>
63#include "inputstr.h"
64#include "gcstruct.h"	/* pointer for extnsionst.h */
65#include "extnsionst.h"	/* extension entry   */
66#include <X11/extensions/XI.h>
67#include <X11/extensions/XIproto.h>
68
69#include "dixevents.h"
70#include "exevents.h"
71#include "extinit.h"
72#include "exglobals.h"
73#include "swaprep.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 "getbmap.h"
86#include "getdctl.h"
87#include "getfctl.h"
88#include "getfocus.h"
89#include "getkmap.h"
90#include "getmmap.h"
91#include "getprop.h"
92#include "getselev.h"
93#include "getvers.h"
94#include "getvers.h"
95#include "grabdev.h"
96#include "grabdevb.h"
97#include "grabdevk.h"
98#include "gtmotion.h"
99#include "listdev.h"
100#include "opendev.h"
101#include "queryst.h"
102#include "selectev.h"
103#include "sendexev.h"
104#include "chgkmap.h"
105#include "setbmap.h"
106#include "setdval.h"
107#include "setfocus.h"
108#include "setmmap.h"
109#include "setmode.h"
110#include "ungrdev.h"
111#include "ungrdevb.h"
112#include "ungrdevk.h"
113
114static Mask lastExtEventMask = 1;
115int ExtEventIndex;
116Mask ExtValidMasks[EMASKSIZE];
117Mask ExtExclusiveMasks[EMASKSIZE];
118
119static struct dev_type
120{
121    Atom type;
122    char *name;
123} dev_type[] = {
124    {
125    0, XI_KEYBOARD}, {
126    0, XI_MOUSE}, {
127    0, XI_TABLET}, {
128    0, XI_TOUCHSCREEN}, {
129    0, XI_TOUCHPAD}, {
130    0, XI_BARCODE}, {
131    0, XI_BUTTONBOX}, {
132    0, XI_KNOB_BOX}, {
133    0, XI_ONE_KNOB}, {
134    0, XI_NINE_KNOB}, {
135    0, XI_TRACKBALL}, {
136    0, XI_QUADRATURE}, {
137    0, XI_ID_MODULE}, {
138    0, XI_SPACEBALL}, {
139    0, XI_DATAGLOVE}, {
140    0, XI_EYETRACKER}, {
141    0, XI_CURSORKEYS}, {
1420, XI_FOOTMOUSE}};
143
144CARD8 event_base[numInputClasses];
145XExtEventInfo EventInfo[32];
146
147/*****************************************************************
148 *
149 * Globals referenced elsewhere in the server.
150 *
151 */
152
153int IReqCode = 0;
154int BadDevice = 0;
155static int BadEvent = 1;
156int BadMode = 2;
157int DeviceBusy = 3;
158int BadClass = 4;
159
160Mask DevicePointerMotionMask;
161Mask DevicePointerMotionHintMask;
162Mask DeviceFocusChangeMask;
163Mask DeviceStateNotifyMask;
164static Mask ChangeDeviceNotifyMask;
165Mask DeviceMappingNotifyMask;
166Mask DeviceOwnerGrabButtonMask;
167Mask DeviceButtonGrabMask;
168Mask DeviceButtonMotionMask;
169Mask DevicePresenceNotifyMask;
170
171int DeviceValuator;
172int DeviceKeyPress;
173int DeviceKeyRelease;
174int DeviceButtonPress;
175int DeviceButtonRelease;
176int DeviceMotionNotify;
177int DeviceFocusIn;
178int DeviceFocusOut;
179int ProximityIn;
180int ProximityOut;
181int DeviceStateNotify;
182int DeviceKeyStateNotify;
183int DeviceButtonStateNotify;
184int DeviceMappingNotify;
185int ChangeDeviceNotify;
186int DevicePresenceNotify;
187
188int RT_INPUTCLIENT;
189
190/*****************************************************************
191 *
192 * Externs defined elsewhere in the X server.
193 *
194 */
195
196extern XExtensionVersion AllExtensionVersions[];
197
198Mask PropagateMask[MAX_DEVICES];
199
200/*****************************************************************
201 *
202 * Declarations of local routines.
203 *
204 */
205
206static XExtensionVersion thisversion = { XI_Present,
207    XI_Add_DevicePresenceNotify_Major,
208    XI_Add_DevicePresenceNotify_Minor
209};
210
211/*************************************************************************
212 *
213 * ProcIDispatch - main dispatch routine for requests to this extension.
214 * This routine is used if server and client have the same byte ordering.
215 *
216 */
217
218static int
219ProcIDispatch(ClientPtr client)
220{
221    REQUEST(xReq);
222    if (stuff->data == X_GetExtensionVersion)
223	return (ProcXGetExtensionVersion(client));
224    if (stuff->data == X_ListInputDevices)
225	return (ProcXListInputDevices(client));
226    else if (stuff->data == X_OpenDevice)
227	return (ProcXOpenDevice(client));
228    else if (stuff->data == X_CloseDevice)
229	return (ProcXCloseDevice(client));
230    else if (stuff->data == X_SetDeviceMode)
231	return (ProcXSetDeviceMode(client));
232    else if (stuff->data == X_SelectExtensionEvent)
233	return (ProcXSelectExtensionEvent(client));
234    else if (stuff->data == X_GetSelectedExtensionEvents)
235	return (ProcXGetSelectedExtensionEvents(client));
236    else if (stuff->data == X_ChangeDeviceDontPropagateList)
237	return (ProcXChangeDeviceDontPropagateList(client));
238    else if (stuff->data == X_GetDeviceDontPropagateList)
239	return (ProcXGetDeviceDontPropagateList(client));
240    else if (stuff->data == X_GetDeviceMotionEvents)
241	return (ProcXGetDeviceMotionEvents(client));
242    else if (stuff->data == X_ChangeKeyboardDevice)
243	return (ProcXChangeKeyboardDevice(client));
244    else if (stuff->data == X_ChangePointerDevice)
245	return (ProcXChangePointerDevice(client));
246    else if (stuff->data == X_GrabDevice)
247	return (ProcXGrabDevice(client));
248    else if (stuff->data == X_UngrabDevice)
249	return (ProcXUngrabDevice(client));
250    else if (stuff->data == X_GrabDeviceKey)
251	return (ProcXGrabDeviceKey(client));
252    else if (stuff->data == X_UngrabDeviceKey)
253	return (ProcXUngrabDeviceKey(client));
254    else if (stuff->data == X_GrabDeviceButton)
255	return (ProcXGrabDeviceButton(client));
256    else if (stuff->data == X_UngrabDeviceButton)
257	return (ProcXUngrabDeviceButton(client));
258    else if (stuff->data == X_AllowDeviceEvents)
259	return (ProcXAllowDeviceEvents(client));
260    else if (stuff->data == X_GetDeviceFocus)
261	return (ProcXGetDeviceFocus(client));
262    else if (stuff->data == X_SetDeviceFocus)
263	return (ProcXSetDeviceFocus(client));
264    else if (stuff->data == X_GetFeedbackControl)
265	return (ProcXGetFeedbackControl(client));
266    else if (stuff->data == X_ChangeFeedbackControl)
267	return (ProcXChangeFeedbackControl(client));
268    else if (stuff->data == X_GetDeviceKeyMapping)
269	return (ProcXGetDeviceKeyMapping(client));
270    else if (stuff->data == X_ChangeDeviceKeyMapping)
271	return (ProcXChangeDeviceKeyMapping(client));
272    else if (stuff->data == X_GetDeviceModifierMapping)
273	return (ProcXGetDeviceModifierMapping(client));
274    else if (stuff->data == X_SetDeviceModifierMapping)
275	return (ProcXSetDeviceModifierMapping(client));
276    else if (stuff->data == X_GetDeviceButtonMapping)
277	return (ProcXGetDeviceButtonMapping(client));
278    else if (stuff->data == X_SetDeviceButtonMapping)
279	return (ProcXSetDeviceButtonMapping(client));
280    else if (stuff->data == X_QueryDeviceState)
281	return (ProcXQueryDeviceState(client));
282    else if (stuff->data == X_SendExtensionEvent)
283	return (ProcXSendExtensionEvent(client));
284    else if (stuff->data == X_DeviceBell)
285	return (ProcXDeviceBell(client));
286    else if (stuff->data == X_SetDeviceValuators)
287	return (ProcXSetDeviceValuators(client));
288    else if (stuff->data == X_GetDeviceControl)
289	return (ProcXGetDeviceControl(client));
290    else if (stuff->data == X_ChangeDeviceControl)
291	return (ProcXChangeDeviceControl(client));
292    else {
293	SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
294    }
295    return (BadRequest);
296}
297
298/*******************************************************************************
299 *
300 * SProcXDispatch
301 *
302 * Main swapped dispatch routine for requests to this extension.
303 * This routine is used if server and client do not have the same byte ordering.
304 *
305 */
306
307static int
308SProcIDispatch(ClientPtr client)
309{
310    REQUEST(xReq);
311    if (stuff->data == X_GetExtensionVersion)
312	return (SProcXGetExtensionVersion(client));
313    if (stuff->data == X_ListInputDevices)
314	return (SProcXListInputDevices(client));
315    else if (stuff->data == X_OpenDevice)
316	return (SProcXOpenDevice(client));
317    else if (stuff->data == X_CloseDevice)
318	return (SProcXCloseDevice(client));
319    else if (stuff->data == X_SetDeviceMode)
320	return (SProcXSetDeviceMode(client));
321    else if (stuff->data == X_SelectExtensionEvent)
322	return (SProcXSelectExtensionEvent(client));
323    else if (stuff->data == X_GetSelectedExtensionEvents)
324	return (SProcXGetSelectedExtensionEvents(client));
325    else if (stuff->data == X_ChangeDeviceDontPropagateList)
326	return (SProcXChangeDeviceDontPropagateList(client));
327    else if (stuff->data == X_GetDeviceDontPropagateList)
328	return (SProcXGetDeviceDontPropagateList(client));
329    else if (stuff->data == X_GetDeviceMotionEvents)
330	return (SProcXGetDeviceMotionEvents(client));
331    else if (stuff->data == X_ChangeKeyboardDevice)
332	return (SProcXChangeKeyboardDevice(client));
333    else if (stuff->data == X_ChangePointerDevice)
334	return (SProcXChangePointerDevice(client));
335    else if (stuff->data == X_GrabDevice)
336	return (SProcXGrabDevice(client));
337    else if (stuff->data == X_UngrabDevice)
338	return (SProcXUngrabDevice(client));
339    else if (stuff->data == X_GrabDeviceKey)
340	return (SProcXGrabDeviceKey(client));
341    else if (stuff->data == X_UngrabDeviceKey)
342	return (SProcXUngrabDeviceKey(client));
343    else if (stuff->data == X_GrabDeviceButton)
344	return (SProcXGrabDeviceButton(client));
345    else if (stuff->data == X_UngrabDeviceButton)
346	return (SProcXUngrabDeviceButton(client));
347    else if (stuff->data == X_AllowDeviceEvents)
348	return (SProcXAllowDeviceEvents(client));
349    else if (stuff->data == X_GetDeviceFocus)
350	return (SProcXGetDeviceFocus(client));
351    else if (stuff->data == X_SetDeviceFocus)
352	return (SProcXSetDeviceFocus(client));
353    else if (stuff->data == X_GetFeedbackControl)
354	return (SProcXGetFeedbackControl(client));
355    else if (stuff->data == X_ChangeFeedbackControl)
356	return (SProcXChangeFeedbackControl(client));
357    else if (stuff->data == X_GetDeviceKeyMapping)
358	return (SProcXGetDeviceKeyMapping(client));
359    else if (stuff->data == X_ChangeDeviceKeyMapping)
360	return (SProcXChangeDeviceKeyMapping(client));
361    else if (stuff->data == X_GetDeviceModifierMapping)
362	return (SProcXGetDeviceModifierMapping(client));
363    else if (stuff->data == X_SetDeviceModifierMapping)
364	return (SProcXSetDeviceModifierMapping(client));
365    else if (stuff->data == X_GetDeviceButtonMapping)
366	return (SProcXGetDeviceButtonMapping(client));
367    else if (stuff->data == X_SetDeviceButtonMapping)
368	return (SProcXSetDeviceButtonMapping(client));
369    else if (stuff->data == X_QueryDeviceState)
370	return (SProcXQueryDeviceState(client));
371    else if (stuff->data == X_SendExtensionEvent)
372	return (SProcXSendExtensionEvent(client));
373    else if (stuff->data == X_DeviceBell)
374	return (SProcXDeviceBell(client));
375    else if (stuff->data == X_SetDeviceValuators)
376	return (SProcXSetDeviceValuators(client));
377    else if (stuff->data == X_GetDeviceControl)
378	return (SProcXGetDeviceControl(client));
379    else if (stuff->data == X_ChangeDeviceControl)
380	return (SProcXChangeDeviceControl(client));
381    else {
382	SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
383    }
384    return (BadRequest);
385}
386
387/**********************************************************************
388 *
389 * SReplyIDispatch
390 * Swap any replies defined in this extension.
391 *
392 */
393
394/* FIXME: this would be more concise and readable in ANSI C */
395#define DISPATCH(code) \
396    if (rep->RepType == X_##code) \
397	SRepX##code (client, len, (x##code##Reply *) rep)
398
399static void
400SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
401					/* All we look at is the type field */
402{	/* This is common to all replies    */
403    if (rep->RepType == X_GetExtensionVersion)
404	SRepXGetExtensionVersion(client, len,
405				 (xGetExtensionVersionReply *) rep);
406    else if (rep->RepType == X_ListInputDevices)
407	SRepXListInputDevices(client, len, (xListInputDevicesReply *) rep);
408    else if (rep->RepType == X_OpenDevice)
409	SRepXOpenDevice(client, len, (xOpenDeviceReply *) rep);
410    else if (rep->RepType == X_SetDeviceMode)
411	SRepXSetDeviceMode(client, len, (xSetDeviceModeReply *) rep);
412    else if (rep->RepType == X_GetSelectedExtensionEvents)
413	SRepXGetSelectedExtensionEvents(client, len,
414					(xGetSelectedExtensionEventsReply *)
415					rep);
416    else if (rep->RepType == X_GetDeviceDontPropagateList)
417	SRepXGetDeviceDontPropagateList(client, len,
418					(xGetDeviceDontPropagateListReply *)
419					rep);
420    else if (rep->RepType == X_GetDeviceMotionEvents)
421	SRepXGetDeviceMotionEvents(client, len,
422				   (xGetDeviceMotionEventsReply *) rep);
423    else if (rep->RepType == X_GrabDevice)
424	SRepXGrabDevice(client, len, (xGrabDeviceReply *) rep);
425    else if (rep->RepType == X_GetDeviceFocus)
426	SRepXGetDeviceFocus(client, len, (xGetDeviceFocusReply *) rep);
427    else if (rep->RepType == X_GetFeedbackControl)
428	SRepXGetFeedbackControl(client, len, (xGetFeedbackControlReply *) rep);
429    else if (rep->RepType == X_GetDeviceKeyMapping)
430	SRepXGetDeviceKeyMapping(client, len,
431				 (xGetDeviceKeyMappingReply *) rep);
432    else if (rep->RepType == X_GetDeviceModifierMapping)
433	SRepXGetDeviceModifierMapping(client, len,
434				      (xGetDeviceModifierMappingReply *) rep);
435    else if (rep->RepType == X_SetDeviceModifierMapping)
436	SRepXSetDeviceModifierMapping(client, len,
437				      (xSetDeviceModifierMappingReply *) rep);
438    else if (rep->RepType == X_GetDeviceButtonMapping)
439	SRepXGetDeviceButtonMapping(client, len,
440				    (xGetDeviceButtonMappingReply *) rep);
441    else if (rep->RepType == X_SetDeviceButtonMapping)
442	SRepXSetDeviceButtonMapping(client, len,
443				    (xSetDeviceButtonMappingReply *) rep);
444    else if (rep->RepType == X_QueryDeviceState)
445	SRepXQueryDeviceState(client, len, (xQueryDeviceStateReply *) rep);
446    else if (rep->RepType == X_SetDeviceValuators)
447	SRepXSetDeviceValuators(client, len, (xSetDeviceValuatorsReply *) rep);
448    else if (rep->RepType == X_GetDeviceControl)
449	SRepXGetDeviceControl(client, len, (xGetDeviceControlReply *) rep);
450    else if (rep->RepType == X_ChangeDeviceControl)
451	SRepXChangeDeviceControl(client, len,
452				 (xChangeDeviceControlReply *) rep);
453    else {
454	FatalError("XINPUT confused sending swapped reply");
455    }
456}
457
458/************************************************************************
459 *
460 * This function swaps the DeviceValuator event.
461 *
462 */
463
464static void
465SEventDeviceValuator(deviceValuator * from, deviceValuator * to)
466{
467    char n;
468    int i;
469    INT32 *ip B32;
470
471    *to = *from;
472    swaps(&to->sequenceNumber, n);
473    swaps(&to->device_state, n);
474    ip = &to->valuator0;
475    for (i = 0; i < 6; i++) {
476	swapl((ip + i), n);	/* macro - braces are required      */
477    }
478}
479
480static void
481SEventFocus(deviceFocus * from, deviceFocus * to)
482{
483    char n;
484
485    *to = *from;
486    swaps(&to->sequenceNumber, n);
487    swapl(&to->time, n);
488    swapl(&to->window, n);
489}
490
491static void
492SDeviceStateNotifyEvent(deviceStateNotify * from, deviceStateNotify * to)
493{
494    int i;
495    char n;
496    INT32 *ip B32;
497
498    *to = *from;
499    swaps(&to->sequenceNumber, n);
500    swapl(&to->time, n);
501    ip = &to->valuator0;
502    for (i = 0; i < 3; i++) {
503	swapl((ip + i), n);	/* macro - braces are required      */
504    }
505}
506
507static void
508SDeviceKeyStateNotifyEvent(deviceKeyStateNotify * from,
509			   deviceKeyStateNotify * to)
510{
511    char n;
512
513    *to = *from;
514    swaps(&to->sequenceNumber, n);
515}
516
517static void
518SDeviceButtonStateNotifyEvent(deviceButtonStateNotify * from,
519			      deviceButtonStateNotify * to)
520{
521    char n;
522
523    *to = *from;
524    swaps(&to->sequenceNumber, n);
525}
526
527static void
528SChangeDeviceNotifyEvent(changeDeviceNotify * from, changeDeviceNotify * to)
529{
530    char n;
531
532    *to = *from;
533    swaps(&to->sequenceNumber, n);
534    swapl(&to->time, n);
535}
536
537static void
538SDeviceMappingNotifyEvent(deviceMappingNotify * from, deviceMappingNotify * to)
539{
540    char n;
541
542    *to = *from;
543    swaps(&to->sequenceNumber, n);
544    swapl(&to->time, n);
545}
546
547static void
548SDevicePresenceNotifyEvent (devicePresenceNotify *from, devicePresenceNotify *to)
549{
550    char n;
551
552    *to = *from;
553    swaps(&to->sequenceNumber,n);
554    swapl(&to->time, n);
555    swaps(&to->control, n);
556}
557
558/**************************************************************************
559 *
560 * Allow the specified event to have its propagation suppressed.
561 * The default is to not allow suppression of propagation.
562 *
563 */
564
565static void
566AllowPropagateSuppress(Mask mask)
567{
568    int i;
569
570    for (i = 0; i < MAX_DEVICES; i++)
571	PropagateMask[i] |= mask;
572}
573
574/**************************************************************************
575 *
576 * Return the next available extension event mask.
577 *
578 */
579
580static Mask
581GetNextExtEventMask(void)
582{
583    int i;
584    Mask mask = lastExtEventMask;
585
586    if (lastExtEventMask == 0) {
587	FatalError("GetNextExtEventMask: no more events are available.");
588    }
589    lastExtEventMask <<= 1;
590
591    for (i = 0; i < MAX_DEVICES; i++)
592	ExtValidMasks[i] |= mask;
593    return mask;
594}
595
596/**************************************************************************
597 *
598 * Record an event mask where there is no unique corresponding event type.
599 * We can't call SetMaskForEvent, since that would clobber the existing
600 * mask for that event.  MotionHint and ButtonMotion are examples.
601 *
602 * Since extension event types will never be less than 64, we can use
603 * 0-63 in the EventInfo array as the "type" to be used to look up this
604 * mask.  This means that the corresponding macros such as
605 * DevicePointerMotionHint must have access to the same constants.
606 *
607 */
608
609static void
610SetEventInfo(Mask mask, int constant)
611{
612    EventInfo[ExtEventIndex].mask = mask;
613    EventInfo[ExtEventIndex++].type = constant;
614}
615
616/**************************************************************************
617 *
618 * Allow the specified event to be restricted to being selected by one
619 * client at a time.
620 * The default is to allow more than one client to select the event.
621 *
622 */
623
624static void
625SetExclusiveAccess(Mask mask)
626{
627    int i;
628
629    for (i = 0; i < MAX_DEVICES; i++)
630	ExtExclusiveMasks[i] |= mask;
631}
632
633/**************************************************************************
634 *
635 * Assign the specified mask to the specified event.
636 *
637 */
638
639static void
640SetMaskForExtEvent(Mask mask, int event)
641{
642
643    EventInfo[ExtEventIndex].mask = mask;
644    EventInfo[ExtEventIndex++].type = event;
645
646    if ((event < LASTEvent) || (event >= 128))
647	FatalError("MaskForExtensionEvent: bogus event number");
648    SetMaskForEvent(mask, event);
649}
650
651/************************************************************************
652 *
653 * This function sets up extension event types and masks.
654 *
655 */
656
657static void
658FixExtensionEvents(ExtensionEntry * extEntry)
659{
660    Mask mask;
661
662    DeviceValuator = extEntry->eventBase;
663    DeviceKeyPress = DeviceValuator + 1;
664    DeviceKeyRelease = DeviceKeyPress + 1;
665    DeviceButtonPress = DeviceKeyRelease + 1;
666    DeviceButtonRelease = DeviceButtonPress + 1;
667    DeviceMotionNotify = DeviceButtonRelease + 1;
668    DeviceFocusIn = DeviceMotionNotify + 1;
669    DeviceFocusOut = DeviceFocusIn + 1;
670    ProximityIn = DeviceFocusOut + 1;
671    ProximityOut = ProximityIn + 1;
672    DeviceStateNotify = ProximityOut + 1;
673    DeviceMappingNotify = DeviceStateNotify + 1;
674    ChangeDeviceNotify = DeviceMappingNotify + 1;
675    DeviceKeyStateNotify = ChangeDeviceNotify + 1;
676    DeviceButtonStateNotify = DeviceKeyStateNotify + 1;
677    DevicePresenceNotify = DeviceButtonStateNotify + 1;
678
679    event_base[KeyClass] = DeviceKeyPress;
680    event_base[ButtonClass] = DeviceButtonPress;
681    event_base[ValuatorClass] = DeviceMotionNotify;
682    event_base[ProximityClass] = ProximityIn;
683    event_base[FocusClass] = DeviceFocusIn;
684    event_base[OtherClass] = DeviceStateNotify;
685
686    BadDevice += extEntry->errorBase;
687    BadEvent += extEntry->errorBase;
688    BadMode += extEntry->errorBase;
689    DeviceBusy += extEntry->errorBase;
690    BadClass += extEntry->errorBase;
691
692    mask = GetNextExtEventMask();
693    SetMaskForExtEvent(mask, DeviceKeyPress);
694    AllowPropagateSuppress(mask);
695
696    mask = GetNextExtEventMask();
697    SetMaskForExtEvent(mask, DeviceKeyRelease);
698    AllowPropagateSuppress(mask);
699
700    mask = GetNextExtEventMask();
701    SetMaskForExtEvent(mask, DeviceButtonPress);
702    AllowPropagateSuppress(mask);
703
704    mask = GetNextExtEventMask();
705    SetMaskForExtEvent(mask, DeviceButtonRelease);
706    AllowPropagateSuppress(mask);
707
708    mask = GetNextExtEventMask();
709    SetMaskForExtEvent(mask, ProximityIn);
710    SetMaskForExtEvent(mask, ProximityOut);
711    AllowPropagateSuppress(mask);
712
713    mask = GetNextExtEventMask();
714    DeviceStateNotifyMask = mask;
715    SetMaskForExtEvent(mask, DeviceStateNotify);
716
717    mask = GetNextExtEventMask();
718    DevicePointerMotionMask = mask;
719    SetMaskForExtEvent(mask, DeviceMotionNotify);
720    AllowPropagateSuppress(mask);
721
722    DevicePointerMotionHintMask = GetNextExtEventMask();
723    SetEventInfo(DevicePointerMotionHintMask, _devicePointerMotionHint);
724    SetEventInfo(GetNextExtEventMask(), _deviceButton1Motion);
725    SetEventInfo(GetNextExtEventMask(), _deviceButton2Motion);
726    SetEventInfo(GetNextExtEventMask(), _deviceButton3Motion);
727    SetEventInfo(GetNextExtEventMask(), _deviceButton4Motion);
728    SetEventInfo(GetNextExtEventMask(), _deviceButton5Motion);
729    DeviceButtonMotionMask = GetNextExtEventMask();
730    SetEventInfo(DeviceButtonMotionMask, _deviceButtonMotion);
731
732    DeviceFocusChangeMask = GetNextExtEventMask();
733    SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusIn);
734    SetMaskForExtEvent(DeviceFocusChangeMask, DeviceFocusOut);
735
736    mask = GetNextExtEventMask();
737    SetMaskForExtEvent(mask, DeviceMappingNotify);
738    DeviceMappingNotifyMask = mask;
739
740    mask = GetNextExtEventMask();
741    SetMaskForExtEvent(mask, ChangeDeviceNotify);
742    ChangeDeviceNotifyMask = mask;
743
744    DeviceButtonGrabMask = GetNextExtEventMask();
745    SetEventInfo(DeviceButtonGrabMask, _deviceButtonGrab);
746    SetExclusiveAccess(DeviceButtonGrabMask);
747
748    DeviceOwnerGrabButtonMask = GetNextExtEventMask();
749    SetEventInfo(DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton);
750
751    DevicePresenceNotifyMask = GetNextExtEventMask();
752    SetEventInfo(DevicePresenceNotifyMask, _devicePresence);
753    SetEventInfo(0, _noExtensionEvent);
754}
755
756/************************************************************************
757 *
758 * This function restores extension event types and masks to their
759 * initial state.
760 *
761 */
762
763static void
764RestoreExtensionEvents(void)
765{
766    int i;
767
768    IReqCode = 0;
769
770    for (i = 0; i < ExtEventIndex - 1; i++) {
771	if ((EventInfo[i].type >= LASTEvent) && (EventInfo[i].type < 128))
772	    SetMaskForEvent(0, EventInfo[i].type);
773	EventInfo[i].mask = 0;
774	EventInfo[i].type = 0;
775    }
776    ExtEventIndex = 0;
777    lastExtEventMask = 1;
778    DeviceValuator = 0;
779    DeviceKeyPress = 1;
780    DeviceKeyRelease = 2;
781    DeviceButtonPress = 3;
782    DeviceButtonRelease = 4;
783    DeviceMotionNotify = 5;
784    DeviceFocusIn = 6;
785    DeviceFocusOut = 7;
786    ProximityIn = 8;
787    ProximityOut = 9;
788    DeviceStateNotify = 10;
789    DeviceMappingNotify = 11;
790    ChangeDeviceNotify = 12;
791    DeviceKeyStateNotify = 13;
792    DeviceButtonStateNotify = 13;
793    DevicePresenceNotify = 14;
794
795    BadDevice = 0;
796    BadEvent = 1;
797    BadMode = 2;
798    DeviceBusy = 3;
799    BadClass = 4;
800
801}
802
803/***********************************************************************
804 *
805 * IResetProc.
806 * Remove reply-swapping routine.
807 * Remove event-swapping routine.
808 *
809 */
810
811static void
812IResetProc(ExtensionEntry * unused)
813{
814
815    ReplySwapVector[IReqCode] = ReplyNotSwappd;
816    EventSwapVector[DeviceValuator] = NotImplemented;
817    EventSwapVector[DeviceKeyPress] = NotImplemented;
818    EventSwapVector[DeviceKeyRelease] = NotImplemented;
819    EventSwapVector[DeviceButtonPress] = NotImplemented;
820    EventSwapVector[DeviceButtonRelease] = NotImplemented;
821    EventSwapVector[DeviceMotionNotify] = NotImplemented;
822    EventSwapVector[DeviceFocusIn] = NotImplemented;
823    EventSwapVector[DeviceFocusOut] = NotImplemented;
824    EventSwapVector[ProximityIn] = NotImplemented;
825    EventSwapVector[ProximityOut] = NotImplemented;
826    EventSwapVector[DeviceStateNotify] = NotImplemented;
827    EventSwapVector[DeviceKeyStateNotify] = NotImplemented;
828    EventSwapVector[DeviceButtonStateNotify] = NotImplemented;
829    EventSwapVector[DeviceMappingNotify] = NotImplemented;
830    EventSwapVector[ChangeDeviceNotify] = NotImplemented;
831    EventSwapVector[DevicePresenceNotify] = NotImplemented;
832    RestoreExtensionEvents();
833}
834
835/***********************************************************************
836 *
837 * Assign an id and type to an input device.
838 *
839 */
840
841_X_EXPORT void
842AssignTypeAndName(DeviceIntPtr dev, Atom type, char *name)
843{
844    dev->type = type;
845    dev->name = (char *)xalloc(strlen(name) + 1);
846    strcpy(dev->name, name);
847}
848
849/***********************************************************************
850 *
851 * Make device type atoms.
852 *
853 */
854
855static void
856MakeDeviceTypeAtoms(void)
857{
858    int i;
859
860    for (i = 0; i < NUMTYPES; i++)
861	dev_type[i].type =
862	    MakeAtom(dev_type[i].name, strlen(dev_type[i].name), 1);
863}
864
865/**************************************************************************
866 * Return a DeviceIntPtr corresponding to a specified device id.
867 *
868 */
869
870DeviceIntPtr
871LookupDeviceIntRec(CARD8 id)
872{
873    DeviceIntPtr dev;
874
875    for (dev = inputInfo.devices; dev; dev = dev->next) {
876	if (dev->id == id)
877	    return dev;
878    }
879
880    for (dev = inputInfo.off_devices; dev; dev = dev->next) {
881	if (dev->id == id)
882	    return dev;
883    }
884
885    return NULL;
886}
887
888/*****************************************************************************
889 *
890 *	SEventIDispatch
891 *
892 *	Swap any events defined in this extension.
893 */
894#define DO_SWAP(func,type) func ((type *)from, (type *)to)
895
896static void
897SEventIDispatch(xEvent * from, xEvent * to)
898{
899    int type = from->u.u.type & 0177;
900
901    if (type == DeviceValuator)
902	DO_SWAP(SEventDeviceValuator, deviceValuator);
903    else if (type == DeviceKeyPress) {
904	SKeyButtonPtrEvent(from, to);
905	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
906    } else if (type == DeviceKeyRelease) {
907	SKeyButtonPtrEvent(from, to);
908	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
909    } else if (type == DeviceButtonPress) {
910	SKeyButtonPtrEvent(from, to);
911	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
912    } else if (type == DeviceButtonRelease) {
913	SKeyButtonPtrEvent(from, to);
914	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
915    } else if (type == DeviceMotionNotify) {
916	SKeyButtonPtrEvent(from, to);
917	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
918    } else if (type == DeviceFocusIn)
919	DO_SWAP(SEventFocus, deviceFocus);
920    else if (type == DeviceFocusOut)
921	DO_SWAP(SEventFocus, deviceFocus);
922    else if (type == ProximityIn) {
923	SKeyButtonPtrEvent(from, to);
924	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
925    } else if (type == ProximityOut) {
926	SKeyButtonPtrEvent(from, to);
927	to->u.keyButtonPointer.pad1 = from->u.keyButtonPointer.pad1;
928    } else if (type == DeviceStateNotify)
929	DO_SWAP(SDeviceStateNotifyEvent, deviceStateNotify);
930    else if (type == DeviceKeyStateNotify)
931	DO_SWAP(SDeviceKeyStateNotifyEvent, deviceKeyStateNotify);
932    else if (type == DeviceButtonStateNotify)
933	DO_SWAP(SDeviceButtonStateNotifyEvent, deviceButtonStateNotify);
934    else if (type == DeviceMappingNotify)
935	DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify);
936    else if (type == ChangeDeviceNotify)
937	DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify);
938    else {
939	FatalError("XInputExtension: Impossible event!\n");
940    }
941}
942
943/**********************************************************************
944 *
945 * IExtensionInit - initialize the input extension.
946 *
947 * Called from InitExtensions in main() or from QueryExtension() if the
948 * extension is dynamically loaded.
949 *
950 * This extension has several events and errors.
951 *
952 */
953
954void
955XInputExtensionInit(void)
956{
957    ExtensionEntry *extEntry;
958
959    extEntry = AddExtension(INAME, IEVENTS, IERRORS, ProcIDispatch,
960			    SProcIDispatch, IResetProc, StandardMinorOpcode);
961    if (extEntry) {
962	IReqCode = extEntry->base;
963	AllExtensionVersions[IReqCode - 128] = thisversion;
964	MakeDeviceTypeAtoms();
965	RT_INPUTCLIENT = CreateNewResourceType((DeleteType) InputClientGone);
966	FixExtensionEvents(extEntry);
967	ReplySwapVector[IReqCode] = (ReplySwapPtr) SReplyIDispatch;
968	EventSwapVector[DeviceValuator] = SEventIDispatch;
969	EventSwapVector[DeviceKeyPress] = SEventIDispatch;
970	EventSwapVector[DeviceKeyRelease] = SEventIDispatch;
971	EventSwapVector[DeviceButtonPress] = SEventIDispatch;
972	EventSwapVector[DeviceButtonRelease] = SEventIDispatch;
973	EventSwapVector[DeviceMotionNotify] = SEventIDispatch;
974	EventSwapVector[DeviceFocusIn] = SEventIDispatch;
975	EventSwapVector[DeviceFocusOut] = SEventIDispatch;
976	EventSwapVector[ProximityIn] = SEventIDispatch;
977	EventSwapVector[ProximityOut] = SEventIDispatch;
978	EventSwapVector[DeviceStateNotify] = SEventIDispatch;
979	EventSwapVector[DeviceKeyStateNotify] = SEventIDispatch;
980	EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch;
981	EventSwapVector[DeviceMappingNotify] = SEventIDispatch;
982	EventSwapVector[ChangeDeviceNotify] = SEventIDispatch;
983    } else {
984	FatalError("IExtensionInit: AddExtensions failed\n");
985    }
986}
987