tizen 2.4 release
[framework/uifw/xorg/server/xorg-server.git] / dix / devices.c
1 /************************************************************
2
3 Copyright 1987, 1998  The Open Group
4
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
24
25 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
26
27                         All Rights Reserved
28
29 Permission to use, copy, modify, and distribute this software and its
30 documentation for any purpose and without fee is hereby granted,
31 provided that the above copyright notice appear in all copies and that
32 both that copyright notice and this permission notice appear in
33 supporting documentation, and that the name of Digital not be
34 used in advertising or publicity pertaining to distribution of the
35 software without specific, written prior permission.
36
37 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43 SOFTWARE.
44
45 ********************************************************/
46
47 #ifdef HAVE_DIX_CONFIG_H
48 #include <dix-config.h>
49 #endif
50
51 #include <X11/X.h>
52 #include "misc.h"
53 #include "resource.h"
54 #include <X11/Xproto.h>
55 #include <X11/Xatom.h>
56 #include "windowstr.h"
57 #include "inputstr.h"
58 #include "scrnintstr.h"
59 #include "cursorstr.h"
60 #include "dixstruct.h"
61 #include "ptrveloc.h"
62 #include "site.h"
63 #include "xkbsrv.h"
64 #include "privates.h"
65 #include "xace.h"
66 #include "mi.h"
67
68 #include "dispatch.h"
69 #include "swaprep.h"
70 #include "dixevents.h"
71 #include "mipointer.h"
72 #include "eventstr.h"
73 #include "dixgrabs.h"
74
75 #include <X11/extensions/XI.h>
76 #include <X11/extensions/XI2.h>
77 #include <X11/extensions/XIproto.h>
78 #include <math.h>
79 #include <pixman.h>
80 #include "exglobals.h"
81 #include "exevents.h"
82 #include "xiquerydevice.h"      /* for SizeDeviceClasses */
83 #include "xiproperty.h"
84 #include "enterleave.h"         /* for EnterWindow() */
85 #include "xserver-properties.h"
86 #include "xichangehierarchy.h"  /* For XISendDeviceHierarchyEvent */
87 #include "syncsrv.h"
88
89 /** @file
90  * This file handles input device-related stuff.
91  */
92
93 static void RecalculateMasterButtons(DeviceIntPtr slave);
94
95 static void
96 DeviceSetTransform(DeviceIntPtr dev, float *transform_data)
97 {
98     struct pixman_f_transform scale;
99     struct pixman_f_transform transform;
100     double sx, sy;
101     int x, y;
102
103     /**
104      * calculate combined transformation matrix:
105      *
106      * M = InvScale * Transform * Scale
107      *
108      * So we can later transform points using M * p
109      *
110      * Where:
111      *  Scale scales coordinates into 0..1 range
112      *  Transform is the user supplied (affine) transform
113      *  InvScale scales coordinates back up into their native range
114      */
115     sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1;
116     sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
117
118     /* invscale */
119     pixman_f_transform_init_scale(&scale, sx, sy);
120     scale.m[0][2] = dev->valuator->axes[0].min_value;
121     scale.m[1][2] = dev->valuator->axes[1].min_value;
122
123     /* transform */
124     for (y = 0; y < 3; y++)
125         for (x = 0; x < 3; x++)
126             transform.m[y][x] = *transform_data++;
127
128     pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform);
129
130     /* scale */
131     pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
132     scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
133     scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
134
135     pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale);
136
137     /* remove translation component for relative movements */
138     dev->relative_transform = transform;
139     dev->relative_transform.m[0][2] = 0;
140     dev->relative_transform.m[1][2] = 0;
141 }
142
143 /**
144  * DIX property handler.
145  */
146 static int
147 DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
148                   BOOL checkonly)
149 {
150     if (property == XIGetKnownProperty(XI_PROP_ENABLED)) {
151         if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
152             return BadValue;
153
154         /* Don't allow disabling of VCP/VCK or XTest devices */
155         if ((dev == inputInfo.pointer ||
156              dev == inputInfo.keyboard ||
157              IsXTestDevice(dev, NULL))
158             &&!(*(CARD8 *) prop->data))
159             return BadAccess;
160
161         if (!checkonly) {
162             if ((*((CARD8 *) prop->data)) && !dev->enabled)
163                 EnableDevice(dev, TRUE);
164             else if (!(*((CARD8 *) prop->data)) && dev->enabled)
165                 DisableDevice(dev, TRUE);
166         }
167     }
168     else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) {
169         float *f = (float *) prop->data;
170         int i;
171
172         if (prop->format != 32 || prop->size != 9 ||
173             prop->type != XIGetKnownProperty(XATOM_FLOAT))
174             return BadValue;
175
176         for (i = 0; i < 9; i++)
177             if (!isfinite(f[i]))
178                 return BadValue;
179
180         if (!checkonly)
181             DeviceSetTransform(dev, f);
182     }
183
184     return Success;
185 }
186
187 /* Pair the keyboard to the pointer device. Keyboard events will follow the
188  * pointer sprite. Only applicable for master devices.
189  */
190 static int
191 PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd)
192 {
193     if (!ptr)
194         return BadDevice;
195
196     /* Don't allow pairing for slave devices */
197     if (!IsMaster(ptr) || !IsMaster(kbd))
198         return BadDevice;
199
200     if (ptr->spriteInfo->paired)
201         return BadDevice;
202
203     if (kbd->spriteInfo->spriteOwner) {
204         free(kbd->spriteInfo->sprite);
205         kbd->spriteInfo->sprite = NULL;
206         kbd->spriteInfo->spriteOwner = FALSE;
207     }
208
209     kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
210     kbd->spriteInfo->paired = ptr;
211     ptr->spriteInfo->paired = kbd;
212     return Success;
213 }
214
215 /**
216  * Find and return the next unpaired MD pointer device.
217  */
218 static DeviceIntPtr
219 NextFreePointerDevice(void)
220 {
221     DeviceIntPtr dev;
222
223     for (dev = inputInfo.devices; dev; dev = dev->next)
224         if (IsMaster(dev) &&
225             dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired)
226             return dev;
227     return NULL;
228 }
229
230 /**
231  * Create a new input device and init it to sane values. The device is added
232  * to the server's off_devices list.
233  *
234  * @param deviceProc Callback for device control function (switch dev on/off).
235  * @return The newly created device.
236  */
237 DeviceIntPtr
238 AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
239 {
240     DeviceIntPtr dev, *prev;    /* not a typo */
241     DeviceIntPtr devtmp;
242     int devid;
243     char devind[MAXDEVICES];
244     BOOL enabled;
245     float transform[9];
246
247     /* Find next available id, 0 and 1 are reserved */
248     memset(devind, 0, sizeof(char) * MAXDEVICES);
249     for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
250         devind[devtmp->id]++;
251     for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
252         devind[devtmp->id]++;
253     for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++);
254
255     if (devid >= MAXDEVICES)
256         return (DeviceIntPtr) NULL;
257     dev = calloc(1,
258                  sizeof(DeviceIntRec) +
259                  sizeof(SpriteInfoRec));
260     if (!dev)
261         return (DeviceIntPtr) NULL;
262
263     if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) {
264         free(dev);
265         return NULL;
266     }
267
268     if (!dev)
269         return (DeviceIntPtr) NULL;
270
271     dev->last.scroll = NULL;
272     dev->last.touches = NULL;
273     dev->id = devid;
274     dev->public.processInputProc = ProcessOtherEvent;
275     dev->public.realInputProc = ProcessOtherEvent;
276     dev->public.enqueueInputProc = EnqueueEvent;
277     dev->deviceProc = deviceProc;
278     dev->startup = autoStart;
279
280     /* device grab defaults */
281     dev->deviceGrab.grabTime = currentTime;
282     dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
283     dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
284     dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
285
286     XkbSetExtension(dev, ProcessKeyboardEvent);
287
288     dev->coreEvents = TRUE;
289
290     /* sprite defaults */
291     dev->spriteInfo = (SpriteInfoPtr) &dev[1];
292
293     /*  security creation/labeling check
294      */
295     if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
296         dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
297         free(dev);
298         return NULL;
299     }
300
301     inputInfo.numDevices++;
302
303     for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next);
304     *prev = dev;
305     dev->next = NULL;
306
307     enabled = FALSE;
308     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
309                            XA_INTEGER, 8, PropModeReplace, 1, &enabled, FALSE);
310     XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED),
311                                  FALSE);
312
313     /* unity matrix */
314     memset(transform, 0, sizeof(transform));
315     transform[0] = transform[4] = transform[8] = 1.0f;
316     dev->relative_transform.m[0][0] = 1.0;
317     dev->relative_transform.m[1][1] = 1.0;
318     dev->relative_transform.m[2][2] = 1.0;
319     dev->scale_and_transform = dev->relative_transform;
320
321     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
322                            XIGetKnownProperty(XATOM_FLOAT), 32,
323                            PropModeReplace, 9, transform, FALSE);
324     XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
325                                  FALSE);
326
327     XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
328
329     return dev;
330 }
331
332 void
333 SendDevicePresenceEvent(int deviceid, int type)
334 {
335     DeviceIntRec dummyDev = { .id =  XIAllDevices };
336     devicePresenceNotify ev = {
337         .type = DevicePresenceNotify,
338         .time = currentTime.milliseconds,
339         .devchange = type,
340         .deviceid = deviceid
341     };
342
343     SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
344                           (xEvent *) &ev, 1);
345 }
346
347 /**
348  * Enable the device through the driver, add the device to the device list.
349  * Switch device ON through the driver and push it onto the global device
350  * list. Initialize the DIX sprite or pair the device. All clients are
351  * notified about the device being enabled.
352  *
353  * A master pointer device needs to be enabled before a master keyboard
354  * device.
355  *
356  * @param The device to be enabled.
357  * @param sendevent True if an XI2 event should be sent.
358  * @return TRUE on success or FALSE otherwise.
359  */
360 Bool
361 EnableDevice(DeviceIntPtr dev, BOOL sendevent)
362 {
363     DeviceIntPtr *prev;
364     int ret;
365     DeviceIntPtr other;
366     BOOL enabled;
367     int flags[MAXDEVICES] = { 0 };
368
369     for (prev = &inputInfo.off_devices;
370          *prev && (*prev != dev); prev = &(*prev)->next);
371
372     if (!dev->spriteInfo->sprite) {
373         if (IsMaster(dev)) {
374             /* Sprites appear on first root window, so we can hardcode it */
375             if (dev->spriteInfo->spriteOwner) {
376                 InitializeSprite(dev, screenInfo.screens[0]->root);
377                 /* mode doesn't matter */
378                 EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
379             }
380             else {
381                 other = NextFreePointerDevice();
382                 BUG_RETURN_VAL_MSG(other == NULL, FALSE,
383                                    "[dix] cannot find pointer to pair with.\n");
384                 PairDevices(other, dev);
385             }
386         }
387         else {
388             if (dev->coreEvents)
389                 other = (IsPointerDevice(dev)) ? inputInfo.pointer:
390                     inputInfo.keyboard;
391             else
392                 other = NULL;   /* auto-float non-core devices */
393             AttachDevice(NULL, dev, other);
394         }
395     }
396
397     if ((*prev != dev) || !dev->inited ||
398         ((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) {
399         ErrorF("[dix] couldn't enable device %d\n", dev->id);
400         return FALSE;
401     }
402     dev->enabled = TRUE;
403     *prev = dev->next;
404
405     for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next);
406     *prev = dev;
407     dev->next = NULL;
408
409     enabled = TRUE;
410     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
411                            XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE);
412
413     SendDevicePresenceEvent(dev->id, DeviceEnabled);
414     if (sendevent) {
415         flags[dev->id] |= XIDeviceEnabled;
416         XISendDeviceHierarchyEvent(flags);
417     }
418
419     // IsFloating condition was brought from latest version at freedesktop xserver
420     if (!IsMaster(dev) && !IsFloating(dev))
421         XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
422
423     RecalculateMasterButtons(dev);
424
425     /* initialise an idle timer for this device*/
426     dev->idle_counter = SyncInitDeviceIdleTime(dev);
427
428     return TRUE;
429 }
430
431
432 /**
433  * Switch a device off through the driver and push it onto the off_devices
434  * list. A device will not send events while disabled. All clients are
435  * notified about the device being disabled.
436  *
437  * Master keyboard devices have to be disabled before master pointer devices
438  * otherwise things turn bad.
439  *
440  * @param sendevent True if an XI2 event should be sent.
441  * @return TRUE on success or FALSE otherwise.
442  */
443 Bool
444 DisableDevice(DeviceIntPtr dev, BOOL sendevent)
445 {
446     DeviceIntPtr *prev, other;
447     BOOL enabled;
448     int flags[MAXDEVICES] = { 0 };
449
450     if (!dev->enabled)
451         return TRUE;
452
453     for (prev = &inputInfo.devices;
454          *prev && (*prev != dev); prev = &(*prev)->next);
455     if (*prev != dev)
456         return FALSE;
457
458     TouchEndPhysicallyActiveTouches(dev);
459     ReleaseButtonsAndKeys(dev);
460     SyncRemoveDeviceIdleTime(dev->idle_counter);
461     dev->idle_counter = NULL;
462
463     /* float attached devices */
464     if (IsMaster(dev)) {
465         for (other = inputInfo.devices; other; other = other->next) {
466             if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
467                 AttachDevice(NULL, other, NULL);
468                 flags[other->id] |= XISlaveDetached;
469             }
470         }
471     }
472     else {
473         for (other = inputInfo.devices; other; other = other->next) {
474             if (IsMaster(other) && other->lastSlave == dev)
475                 other->lastSlave = NULL;
476         }
477     }
478
479     if (IsMaster(dev) && dev->spriteInfo->sprite) {
480         for (other = inputInfo.devices; other; other = other->next)
481             if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner)
482                 DisableDevice(other, sendevent);
483     }
484
485     if (dev->spriteInfo->paired)
486         dev->spriteInfo->paired = NULL;
487
488     (void) (*dev->deviceProc) (dev, DEVICE_OFF);
489     dev->enabled = FALSE;
490
491     FreeSprite(dev);
492
493     /* now that the device is disabled, we can reset the signal handler's
494      * last.slave */
495     OsBlockSignals();
496     for (other = inputInfo.devices; other; other = other->next) {
497         if (other->last.slave == dev)
498             other->last.slave = NULL;
499     }
500     OsReleaseSignals();
501
502     LeaveWindow(dev);
503     SetFocusOut(dev);
504
505     *prev = dev->next;
506     dev->next = inputInfo.off_devices;
507     inputInfo.off_devices = dev;
508
509     enabled = FALSE;
510     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
511                            XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE);
512
513     SendDevicePresenceEvent(dev->id, DeviceDisabled);
514     if (sendevent) {
515         flags[dev->id] = XIDeviceDisabled;
516         XISendDeviceHierarchyEvent(flags);
517     }
518
519     RecalculateMasterButtons(dev);
520
521     return TRUE;
522 }
523
524 void
525 DisableAllDevices(void)
526 {
527     DeviceIntPtr dev, tmp;
528
529     /* Disable slave devices first, excluding XTest devices */
530     nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
531         if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
532             DisableDevice(dev, FALSE);
533     }
534     /* Disable XTest devices */
535     nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
536         if (!IsMaster(dev))
537             DisableDevice(dev, FALSE);
538     }
539     /* master keyboards need to be disabled first */
540     nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
541         if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev))
542             DisableDevice(dev, FALSE);
543     }
544     nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
545         if (dev->enabled)
546             DisableDevice(dev, FALSE);
547     }
548 }
549
550 /**
551  * Initialise a new device through the driver and tell all clients about the
552  * new device.
553  *
554  * Must be called before EnableDevice.
555  * The device will NOT send events until it is enabled!
556  *
557  * @param sendevent True if an XI2 event should be sent.
558  * @return Success or an error code on failure.
559  */
560 int
561 ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
562 {
563     int ret = Success;
564     ScreenPtr pScreen = screenInfo.screens[0];
565
566     if (!dev || !dev->deviceProc)
567         return BadImplementation;
568
569     ret = (*dev->deviceProc) (dev, DEVICE_INIT);
570     dev->inited = (ret == Success);
571     if (!dev->inited)
572         return ret;
573
574     /* Initialize memory for sprites. */
575     if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
576         if (!pScreen->DeviceCursorInitialize(dev, pScreen))
577             ret = BadAlloc;
578
579     SendDevicePresenceEvent(dev->id, DeviceAdded);
580     if (sendevent) {
581         int flags[MAXDEVICES] = { 0 };
582         flags[dev->id] = XISlaveAdded;
583         XISendDeviceHierarchyEvent(flags);
584     }
585     return ret;
586 }
587
588 /**
589  * Ring the bell.
590  * The actual task of ringing the bell is the job of the DDX.
591  */
592 static void
593 CoreKeyboardBell(int volume, DeviceIntPtr pDev, void *arg, int something)
594 {
595     KeybdCtrl *ctrl = arg;
596
597     DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
598 }
599
600 static void
601 CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
602 {
603     return;
604 }
605
606 /**
607  * Device control function for the Virtual Core Keyboard.
608  */
609 int
610 CoreKeyboardProc(DeviceIntPtr pDev, int what)
611 {
612
613     switch (what) {
614     case DEVICE_INIT:
615         if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
616                                       CoreKeyboardCtl)) {
617             ErrorF("Keyboard initialization failed. This could be a missing "
618                    "or incorrect setup of xkeyboard-config.\n");
619             return BadValue;
620         }
621         return Success;
622
623     case DEVICE_ON:
624     case DEVICE_OFF:
625         return Success;
626
627     case DEVICE_CLOSE:
628         return Success;
629     }
630
631     return BadMatch;
632 }
633
634 /**
635  * Device control function for the Virtual Core Pointer.
636  */
637 int
638 CorePointerProc(DeviceIntPtr pDev, int what)
639 {
640 #define NBUTTONS 10
641 #define NAXES 2
642     BYTE map[NBUTTONS + 1];
643     int i = 0;
644     Atom btn_labels[NBUTTONS] = { 0 };
645     Atom axes_labels[NAXES] = { 0 };
646     ScreenPtr scr = screenInfo.screens[0];
647
648     switch (what) {
649     case DEVICE_INIT:
650         for (i = 1; i <= NBUTTONS; i++)
651             map[i] = i;
652
653         btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
654         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
655         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
656         btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
657         btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
658         btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
659         btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
660         /* don't know about the rest */
661
662         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
663         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
664
665         if (!InitPointerDeviceStruct
666             ((DevicePtr) pDev, map, NBUTTONS, btn_labels,
667              (PtrCtrlProcPtr) NoopDDA, GetMotionHistorySize(), NAXES,
668              axes_labels)) {
669             ErrorF("Could not initialize device '%s'. Out of memory.\n",
670                    pDev->name);
671             return BadAlloc;    /* IPDS only fails on allocs */
672         }
673         /* axisVal is per-screen, last.valuators is desktop-wide */
674         pDev->valuator->axisVal[0] = scr->width / 2;
675         pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x;
676         pDev->valuator->axisVal[1] = scr->height / 2;
677         pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y;
678         break;
679
680     case DEVICE_CLOSE:
681         break;
682
683     default:
684         break;
685     }
686
687     return Success;
688
689 #undef NBUTTONS
690 #undef NAXES
691 }
692
693 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
694 int
695 CoreTouchProc(DeviceIntPtr pDev, int what)
696 {
697 #define NBUTTONS 10
698 #define NTOUCHES 10
699 #define NAXES MAX_VALUATORS
700     int i = 0;
701     Atom axes_labels[NAXES] = { 0 };
702     Atom atom = None;
703     Atom btn_labels[NBUTTONS] = { 0 };
704     BYTE map[NBUTTONS + 1] = { 0 };
705     ScreenPtr scr = screenInfo.screens[0];
706     static char* abs_labels[] = {
707         AXIS_LABEL_PROP_ABS_X,              /* 0x00 */
708         AXIS_LABEL_PROP_ABS_Y,              /* 0x01 */
709         AXIS_LABEL_PROP_ABS_Z,              /* 0x02 */
710         AXIS_LABEL_PROP_ABS_RX,             /* 0x03 */
711         AXIS_LABEL_PROP_ABS_RY,             /* 0x04 */
712         AXIS_LABEL_PROP_ABS_RZ,             /* 0x05 */
713         AXIS_LABEL_PROP_ABS_THROTTLE,       /* 0x06 */
714         AXIS_LABEL_PROP_ABS_RUDDER,         /* 0x07 */
715         AXIS_LABEL_PROP_ABS_WHEEL,          /* 0x08 */
716         AXIS_LABEL_PROP_ABS_GAS,            /* 0x09 */
717         AXIS_LABEL_PROP_ABS_BRAKE,          /* 0x0a */
718         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
719         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
720         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
721         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
722         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
723         AXIS_LABEL_PROP_ABS_HAT0X,          /* 0x10 */
724         AXIS_LABEL_PROP_ABS_HAT0Y,          /* 0x11 */
725         AXIS_LABEL_PROP_ABS_HAT1X,          /* 0x12 */
726         AXIS_LABEL_PROP_ABS_HAT1Y,          /* 0x13 */
727         AXIS_LABEL_PROP_ABS_HAT2X,          /* 0x14 */
728         AXIS_LABEL_PROP_ABS_HAT2Y,          /* 0x15 */
729         AXIS_LABEL_PROP_ABS_HAT3X,          /* 0x16 */
730         AXIS_LABEL_PROP_ABS_HAT3Y,          /* 0x17 */
731         AXIS_LABEL_PROP_ABS_PRESSURE,       /* 0x18 */
732         AXIS_LABEL_PROP_ABS_DISTANCE,       /* 0x19 */
733         AXIS_LABEL_PROP_ABS_TILT_X,         /* 0x1a */
734         AXIS_LABEL_PROP_ABS_TILT_Y,         /* 0x1b */
735         AXIS_LABEL_PROP_ABS_TOOL_WIDTH,     /* 0x1c */
736         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
737         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
738         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
739         AXIS_LABEL_PROP_ABS_VOLUME          /* 0x20 */
740         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
741         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
742         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
743         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
744         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
745         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
746         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
747         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
748         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
749         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
750         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
751         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
752         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
753         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
754         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
755         AXIS_LABEL_PROP_ABS_MISC,           /* undefined */
756         AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR, /* 0x30 */
757         AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR, /* 0x31 */
758         AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR, /* 0x32 */
759         AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR, /* 0x33 */
760         AXIS_LABEL_PROP_ABS_MT_ORIENTATION, /* 0x34 */
761         AXIS_LABEL_PROP_ABS_MT_POSITION_X,  /* 0x35 */
762         AXIS_LABEL_PROP_ABS_MT_POSITION_Y,  /* 0x36 */
763         AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE,   /* 0x37 */
764         AXIS_LABEL_PROP_ABS_MT_BLOB_ID,     /* 0x38 */
765         AXIS_LABEL_PROP_ABS_MT_TRACKING_ID, /* 0x39 */
766         AXIS_LABEL_PROP_ABS_MT_PRESSURE,    /* 0x3a */
767     };
768
769     switch (what) {
770     case DEVICE_INIT:
771     for (i = 1; i <= NBUTTONS; i++)
772             map[i] = i;
773
774         btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
775         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
776         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
777         btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
778         btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
779         btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
780         btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
781
782         for (i = 0; i < NAXES; i++) {
783             atom = XIGetKnownProperty(abs_labels[i]);
784             if (!atom) { /* Should not happen */
785                 continue;
786             }
787             axes_labels[i] = atom;
788         }
789
790         if (!InitTouchDeviceStruct(pDev, MAX_VALUATORS, axes_labels,
791                     GetMotionHistorySize(), Absolute, NTOUCHES, XIDirectTouch,
792                     NBUTTONS, btn_labels, map)) {
793                     ErrorF("[CoreTouchProc] Could not initialize touch device '%s'. Out of memory.\n",
794                     pDev->name);
795                     return BadAlloc;
796         }
797
798         /* axisVal is per-screen, last.valuators is desktop-wide */
799         pDev->valuator->axisVal[0] = scr->width / 2;
800         pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x;
801         pDev->valuator->axisVal[1] = scr->height / 2;
802         pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y;
803         break;
804
805     case DEVICE_CLOSE:
806         break;
807
808     default:
809         break;
810     }
811
812     return Success;
813
814 #undef NBUTTONS
815 #undef NTOUCHES
816 #undef NAXES
817 }
818 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
819
820 /**
821  * Initialise the two core devices, VCP and VCK (see events.c).
822  * Both devices are not tied to physical devices, but guarantee that there is
823  * always a keyboard and a pointer present and keep the protocol semantics.
824  *
825  * Note that the server MUST have two core devices at all times, even if there
826  * is no physical device connected.
827  */
828 void
829 InitCoreDevices(void)
830 {
831     if (AllocDevicePair(serverClient, "Virtual core",
832                         &inputInfo.pointer, &inputInfo.keyboard,
833                         CorePointerProc, CoreKeyboardProc, TRUE) != Success)
834          FatalError("Failed to allocate core devices");
835
836     if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
837         ActivateDevice(inputInfo.keyboard, TRUE) != Success)
838          FatalError("Failed to activate core devices.");
839     if (!EnableDevice(inputInfo.pointer, TRUE) ||
840         !EnableDevice(inputInfo.keyboard, TRUE))
841          FatalError("Failed to enable core devices.");
842
843     InitXTestDevices();
844 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
845     InitXTestHWKeyTouchDevices();
846 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
847 }
848
849 /**
850  * Activate all switched-off devices and then enable all those devices.
851  *
852  * Will return an error if no core keyboard or core pointer is present.
853  * In theory this should never happen if you call InitCoreDevices() first.
854  *
855  * InitAndStartDevices needs to be called AFTER the windows are initialized.
856  * Devices will start sending events after InitAndStartDevices() has
857  * completed.
858  *
859  * @return Success or error code on failure.
860  */
861 int
862 InitAndStartDevices(void)
863 {
864     DeviceIntPtr dev, next;
865
866     for (dev = inputInfo.off_devices; dev; dev = dev->next) {
867         DebugF("(dix) initialising device %d\n", dev->id);
868         if (!dev->inited)
869             ActivateDevice(dev, TRUE);
870     }
871
872     /* enable real devices */
873     for (dev = inputInfo.off_devices; dev; dev = next) {
874         DebugF("(dix) enabling device %d\n", dev->id);
875         next = dev->next;
876         if (dev->inited && dev->startup)
877             EnableDevice(dev, TRUE);
878     }
879
880     return Success;
881 }
882
883 /**
884  * Free the given device class and reset the pointer to NULL.
885  */
886 static void
887 FreeDeviceClass(int type, void **class)
888 {
889     if (!(*class))
890         return;
891
892     switch (type) {
893     case KeyClass:
894     {
895         KeyClassPtr *k = (KeyClassPtr *) class;
896
897         if ((*k)->xkbInfo) {
898             XkbFreeInfo((*k)->xkbInfo);
899             (*k)->xkbInfo = NULL;
900         }
901         free((*k));
902         break;
903     }
904     case ButtonClass:
905     {
906         ButtonClassPtr *b = (ButtonClassPtr *) class;
907
908         free((*b)->xkb_acts);
909         free((*b));
910         break;
911     }
912     case ValuatorClass:
913     {
914         ValuatorClassPtr *v = (ValuatorClassPtr *) class;
915
916         free((*v)->motion);
917         free((*v));
918         break;
919     }
920     case XITouchClass:
921     {
922         TouchClassPtr *t = (TouchClassPtr *) class;
923         int i;
924
925         for (i = 0; i < (*t)->num_touches; i++) {
926             free((*t)->touches[i].sprite.spriteTrace);
927             free((*t)->touches[i].listeners);
928             free((*t)->touches[i].valuators);
929         }
930
931         free((*t)->touches);
932         free((*t));
933         break;
934     }
935     case FocusClass:
936     {
937         FocusClassPtr *f = (FocusClassPtr *) class;
938
939         free((*f)->trace);
940         free((*f));
941         break;
942     }
943     case ProximityClass:
944     {
945         ProximityClassPtr *p = (ProximityClassPtr *) class;
946
947         free((*p));
948         break;
949     }
950     }
951     *class = NULL;
952 }
953
954 static void
955 FreeFeedbackClass(int type, void **class)
956 {
957     if (!(*class))
958         return;
959
960     switch (type) {
961     case KbdFeedbackClass:
962     {
963         KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr *) class;
964         KbdFeedbackPtr k, knext;
965
966         for (k = (*kbdfeed); k; k = knext) {
967             knext = k->next;
968             if (k->xkb_sli)
969                 XkbFreeSrvLedInfo(k->xkb_sli);
970             free(k);
971         }
972         break;
973     }
974     case PtrFeedbackClass:
975     {
976         PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr *) class;
977         PtrFeedbackPtr p, pnext;
978
979         for (p = (*ptrfeed); p; p = pnext) {
980             pnext = p->next;
981             free(p);
982         }
983         break;
984     }
985     case IntegerFeedbackClass:
986     {
987         IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr *) class;
988         IntegerFeedbackPtr i, inext;
989
990         for (i = (*intfeed); i; i = inext) {
991             inext = i->next;
992             free(i);
993         }
994         break;
995     }
996     case StringFeedbackClass:
997     {
998         StringFeedbackPtr *stringfeed = (StringFeedbackPtr *) class;
999         StringFeedbackPtr s, snext;
1000
1001         for (s = (*stringfeed); s; s = snext) {
1002             snext = s->next;
1003             free(s->ctrl.symbols_supported);
1004             free(s->ctrl.symbols_displayed);
1005             free(s);
1006         }
1007         break;
1008     }
1009     case BellFeedbackClass:
1010     {
1011         BellFeedbackPtr *bell = (BellFeedbackPtr *) class;
1012         BellFeedbackPtr b, bnext;
1013
1014         for (b = (*bell); b; b = bnext) {
1015             bnext = b->next;
1016             free(b);
1017         }
1018         break;
1019     }
1020     case LedFeedbackClass:
1021     {
1022         LedFeedbackPtr *leds = (LedFeedbackPtr *) class;
1023         LedFeedbackPtr l, lnext;
1024
1025         for (l = (*leds); l; l = lnext) {
1026             lnext = l->next;
1027             if (l->xkb_sli)
1028                 XkbFreeSrvLedInfo(l->xkb_sli);
1029             free(l);
1030         }
1031         break;
1032     }
1033     }
1034     *class = NULL;
1035 }
1036
1037 static void
1038 FreeAllDeviceClasses(ClassesPtr classes)
1039 {
1040     if (!classes)
1041         return;
1042
1043     FreeDeviceClass(KeyClass, (void *) &classes->key);
1044     FreeDeviceClass(ValuatorClass, (void *) &classes->valuator);
1045     FreeDeviceClass(XITouchClass, (void *) &classes->touch);
1046     FreeDeviceClass(ButtonClass, (void *) &classes->button);
1047     FreeDeviceClass(FocusClass, (void *) &classes->focus);
1048     FreeDeviceClass(ProximityClass, (void *) &classes->proximity);
1049
1050     FreeFeedbackClass(KbdFeedbackClass, (void *) &classes->kbdfeed);
1051     FreeFeedbackClass(PtrFeedbackClass, (void *) &classes->ptrfeed);
1052     FreeFeedbackClass(IntegerFeedbackClass, (void *) &classes->intfeed);
1053     FreeFeedbackClass(StringFeedbackClass, (void *) &classes->stringfeed);
1054     FreeFeedbackClass(BellFeedbackClass, (void *) &classes->bell);
1055     FreeFeedbackClass(LedFeedbackClass, (void *) &classes->leds);
1056
1057 }
1058
1059 /**
1060  * Close down a device and free all resources.
1061  * Once closed down, the driver will probably not expect you that you'll ever
1062  * enable it again and free associated structs. If you want the device to just
1063  * be disabled, DisableDevice().
1064  * Don't call this function directly, use RemoveDevice() instead.
1065  */
1066 static void
1067 CloseDevice(DeviceIntPtr dev)
1068 {
1069     ScreenPtr screen = screenInfo.screens[0];
1070     ClassesPtr classes;
1071     int j;
1072
1073     if (!dev)
1074         return;
1075
1076     XIDeleteAllDeviceProperties(dev);
1077
1078     if (dev->inited)
1079         (void) (*dev->deviceProc) (dev, DEVICE_CLOSE);
1080
1081     FreeSprite(dev);
1082
1083     if (IsMaster(dev))
1084         screen->DeviceCursorCleanup(dev, screen);
1085
1086     /* free acceleration info */
1087     if (dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
1088         dev->valuator->accelScheme.AccelCleanupProc(dev);
1089
1090     while (dev->xkb_interest)
1091         XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource);
1092
1093     free(dev->name);
1094
1095     classes = (ClassesPtr) &dev->key;
1096     FreeAllDeviceClasses(classes);
1097
1098     if (IsMaster(dev)) {
1099         classes = dev->unused_classes;
1100         FreeAllDeviceClasses(classes);
1101         free(classes);
1102     }
1103
1104     /* a client may have the device set as client pointer */
1105     for (j = 0; j < currentMaxClients; j++) {
1106         if (clients[j] && clients[j]->clientPtr == dev) {
1107             clients[j]->clientPtr = NULL;
1108             clients[j]->clientPtr = PickPointer(clients[j]);
1109         }
1110     }
1111
1112     if (dev->deviceGrab.grab)
1113         FreeGrab(dev->deviceGrab.grab);
1114     free(dev->deviceGrab.sync.event);
1115     free(dev->config_info);     /* Allocated in xf86ActivateDevice. */
1116     free(dev->last.scroll);
1117     for (j = 0; j < dev->last.num_touches; j++)
1118         free(dev->last.touches[j].valuators);
1119     free(dev->last.touches);
1120     dev->config_info = NULL;
1121     dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
1122     free(dev);
1123 }
1124
1125 /**
1126  * Shut down all devices of one list and free all resources.
1127  */
1128 static
1129     void
1130 CloseDeviceList(DeviceIntPtr *listHead)
1131 {
1132     /* Used to mark devices that we tried to free */
1133     Bool freedIds[MAXDEVICES];
1134     DeviceIntPtr dev;
1135     int i;
1136
1137     if (listHead == NULL)
1138         return;
1139
1140     for (i = 0; i < MAXDEVICES; i++)
1141         freedIds[i] = FALSE;
1142
1143     dev = *listHead;
1144     while (dev != NULL) {
1145         freedIds[dev->id] = TRUE;
1146         DeleteInputDeviceRequest(dev);
1147
1148         dev = *listHead;
1149         while (dev != NULL && freedIds[dev->id])
1150             dev = dev->next;
1151     }
1152 }
1153
1154 /**
1155  * Shut down all devices, free all resources, etc.
1156  * Only useful if you're shutting down the server!
1157  */
1158 void
1159 CloseDownDevices(void)
1160 {
1161     DeviceIntPtr dev;
1162
1163     OsBlockSignals();
1164
1165     /* Float all SDs before closing them. Note that at this point resources
1166      * (e.g. cursors) have been freed already, so we can't just call
1167      * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
1168      * to NULL and pretend nothing happened.
1169      */
1170     for (dev = inputInfo.devices; dev; dev = dev->next) {
1171         if (!IsMaster(dev) && !IsFloating(dev))
1172             dev->master = NULL;
1173     }
1174
1175     CloseDeviceList(&inputInfo.devices);
1176     CloseDeviceList(&inputInfo.off_devices);
1177
1178     CloseDevice(inputInfo.pointer);
1179
1180     CloseDevice(inputInfo.keyboard);
1181
1182     inputInfo.devices = NULL;
1183     inputInfo.off_devices = NULL;
1184     inputInfo.keyboard = NULL;
1185     inputInfo.pointer = NULL;
1186
1187     XkbDeleteRulesDflts();
1188     XkbDeleteRulesUsed();
1189
1190     OsReleaseSignals();
1191 }
1192
1193 /**
1194  * Signal all devices that we're in the process of aborting.
1195  * This function is called from a signal handler.
1196  */
1197 void
1198 AbortDevices(void)
1199 {
1200     DeviceIntPtr dev;
1201     nt_list_for_each_entry(dev, inputInfo.devices, next) {
1202         if (!IsMaster(dev))
1203             (*dev->deviceProc) (dev, DEVICE_ABORT);
1204     }
1205
1206     nt_list_for_each_entry(dev, inputInfo.off_devices, next) {
1207         if (!IsMaster(dev))
1208             (*dev->deviceProc) (dev, DEVICE_ABORT);
1209     }
1210 }
1211
1212 /**
1213  * Remove the cursor sprite for all devices. This needs to be done before any
1214  * resources are freed or any device is deleted.
1215  */
1216 void
1217 UndisplayDevices(void)
1218 {
1219     DeviceIntPtr dev;
1220     ScreenPtr screen = screenInfo.screens[0];
1221
1222     for (dev = inputInfo.devices; dev; dev = dev->next)
1223         screen->DisplayCursor(dev, screen, NullCursor);
1224 }
1225
1226 /**
1227  * Remove a device from the device list, closes it and thus frees all
1228  * resources.
1229  * Removes both enabled and disabled devices and notifies all devices about
1230  * the removal of the device.
1231  *
1232  * No PresenceNotify is sent for device that the client never saw. This can
1233  * happen if a malloc fails during the addition of master devices. If
1234  * dev->init is FALSE it means the client never received a DeviceAdded event,
1235  * so let's not send a DeviceRemoved event either.
1236  *
1237  * @param sendevent True if an XI2 event should be sent.
1238  */
1239 int
1240 RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
1241 {
1242     DeviceIntPtr prev, tmp, next;
1243     int ret = BadMatch;
1244     ScreenPtr screen = screenInfo.screens[0];
1245     int deviceid;
1246     int initialized;
1247     int flags[MAXDEVICES] = { 0 };
1248
1249     DebugF("(dix) removing device %d\n", dev->id);
1250
1251     if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
1252         return BadImplementation;
1253
1254     initialized = dev->inited;
1255     deviceid = dev->id;
1256
1257     if (initialized) {
1258         if (DevHasCursor(dev))
1259             screen->DisplayCursor(dev, screen, NullCursor);
1260
1261         DisableDevice(dev, sendevent);
1262         flags[dev->id] = XIDeviceDisabled;
1263     }
1264
1265     prev = NULL;
1266     for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
1267         next = tmp->next;
1268         if (tmp == dev) {
1269
1270             if (prev == NULL)
1271                 inputInfo.devices = next;
1272             else
1273                 prev->next = next;
1274
1275             flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1276             CloseDevice(tmp);
1277             ret = Success;
1278         }
1279     }
1280
1281     prev = NULL;
1282     for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
1283         next = tmp->next;
1284         if (tmp == dev) {
1285             flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1286             CloseDevice(tmp);
1287
1288             if (prev == NULL)
1289                 inputInfo.off_devices = next;
1290             else
1291                 prev->next = next;
1292
1293             ret = Success;
1294         }
1295     }
1296
1297     if (ret == Success && initialized) {
1298         inputInfo.numDevices--;
1299         SendDevicePresenceEvent(deviceid, DeviceRemoved);
1300         if (sendevent)
1301             XISendDeviceHierarchyEvent(flags);
1302     }
1303
1304     return ret;
1305 }
1306
1307 int
1308 NumMotionEvents(void)
1309 {
1310     /* only called to fill data in initial connection reply.
1311      * VCP is ok here, it is the only fixed device we have. */
1312     return inputInfo.pointer->valuator->numMotionEvents;
1313 }
1314
1315 int
1316 dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
1317 {
1318     DeviceIntPtr dev;
1319     int rc;
1320
1321     *pDev = NULL;
1322
1323     for (dev = inputInfo.devices; dev; dev = dev->next) {
1324         if (dev->id == id)
1325             goto found;
1326     }
1327     for (dev = inputInfo.off_devices; dev; dev = dev->next) {
1328         if (dev->id == id)
1329             goto found;
1330     }
1331     return BadDevice;
1332
1333  found:
1334     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
1335     if (rc == Success)
1336         *pDev = dev;
1337     return rc;
1338 }
1339
1340 void
1341 QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
1342 {
1343     if (inputInfo.keyboard) {
1344         *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
1345         *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
1346     }
1347 }
1348
1349 /* Notably, this function does not expand the destination's keycode range, or
1350  * notify clients. */
1351 Bool
1352 SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
1353 {
1354     int i, j;
1355     KeySym *tmp;
1356     int rowDif = src->minKeyCode - dst->minKeyCode;
1357
1358     /* if keysym map size changes, grow map first */
1359     if (src->mapWidth < dst->mapWidth) {
1360         for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
1361 #define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
1362 #define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
1363             for (j = 0; j < src->mapWidth; j++)
1364                 dst->map[DI(i, j)] = src->map[SI(i, j)];
1365             for (j = src->mapWidth; j < dst->mapWidth; j++)
1366                 dst->map[DI(i, j)] = NoSymbol;
1367 #undef SI
1368 #undef DI
1369         }
1370         return TRUE;
1371     }
1372     else if (src->mapWidth > dst->mapWidth) {
1373         i = sizeof(KeySym) * src->mapWidth *
1374             (dst->maxKeyCode - dst->minKeyCode + 1);
1375         tmp = calloc(sizeof(KeySym), i);
1376         if (!tmp)
1377             return FALSE;
1378
1379         if (dst->map) {
1380             for (i = 0; i <= dst->maxKeyCode - dst->minKeyCode; i++)
1381                 memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
1382                         dst->mapWidth * sizeof(KeySym));
1383             free(dst->map);
1384         }
1385         dst->mapWidth = src->mapWidth;
1386         dst->map = tmp;
1387     }
1388     else if (!dst->map) {
1389         i = sizeof(KeySym) * src->mapWidth *
1390             (dst->maxKeyCode - dst->minKeyCode + 1);
1391         tmp = calloc(sizeof(KeySym), i);
1392         if (!tmp)
1393             return FALSE;
1394
1395         dst->map = tmp;
1396         dst->mapWidth = src->mapWidth;
1397     }
1398
1399     memmove(&dst->map[rowDif * dst->mapWidth], src->map,
1400             (src->maxKeyCode - src->minKeyCode + 1) *
1401             dst->mapWidth * sizeof(KeySym));
1402
1403     return TRUE;
1404 }
1405
1406 Bool
1407 InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels,
1408                             CARD8 *map)
1409 {
1410     ButtonClassPtr butc;
1411     int i;
1412
1413     BUG_RETURN_VAL(dev == NULL, FALSE);
1414     BUG_RETURN_VAL(dev->button != NULL, FALSE);
1415     BUG_RETURN_VAL(numButtons >= MAX_BUTTONS, FALSE);
1416
1417     butc = calloc(1, sizeof(ButtonClassRec));
1418     if (!butc)
1419         return FALSE;
1420     butc->numButtons = numButtons;
1421     butc->sourceid = dev->id;
1422     for (i = 1; i <= numButtons; i++)
1423         butc->map[i] = map[i];
1424     for (i = numButtons + 1; i < MAP_LENGTH; i++)
1425         butc->map[i] = i;
1426     memcpy(butc->labels, labels, numButtons * sizeof(Atom));
1427     dev->button = butc;
1428     return TRUE;
1429 }
1430
1431 /**
1432  * Allocate a valuator class and set up the pointers for the axis values
1433  * appropriately.
1434  *
1435  * @param src If non-NULL, the memory is reallocated from src. If NULL, the
1436  * memory is calloc'd.
1437  * @parma numAxes Number of axes to allocate.
1438  * @return The allocated valuator struct.
1439  */
1440 ValuatorClassPtr
1441 AllocValuatorClass(ValuatorClassPtr src, int numAxes)
1442 {
1443     ValuatorClassPtr v;
1444
1445     /* force alignment with double */
1446     union align_u {
1447         ValuatorClassRec valc;
1448         double d;
1449     } *align;
1450     int size;
1451
1452     size =
1453         sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo));
1454     align = (union align_u *) realloc(src, size);
1455
1456     if (!align)
1457         return NULL;
1458
1459     if (!src)
1460         memset(align, 0, size);
1461
1462     v = &align->valc;
1463     v->numAxes = numAxes;
1464     v->axisVal = (double *) (align + 1);
1465     v->axes = (AxisInfoPtr) (v->axisVal + numAxes);
1466
1467     return v;
1468 }
1469
1470 Bool
1471 InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
1472                               int numMotionEvents, int mode)
1473 {
1474     int i;
1475     ValuatorClassPtr valc;
1476
1477     BUG_RETURN_VAL(dev == NULL, FALSE);
1478
1479     if (numAxes > MAX_VALUATORS) {
1480         LogMessage(X_WARNING,
1481                    "Device '%s' has %d axes, only using first %d.\n",
1482                    dev->name, numAxes, MAX_VALUATORS);
1483         numAxes = MAX_VALUATORS;
1484     }
1485
1486     valc = AllocValuatorClass(NULL, numAxes);
1487     if (!valc)
1488         return FALSE;
1489
1490     dev->last.scroll = valuator_mask_new(numAxes);
1491     if (!dev->last.scroll) {
1492         free(valc);
1493         return FALSE;
1494     }
1495
1496     valc->sourceid = dev->id;
1497     valc->motion = NULL;
1498     valc->first_motion = 0;
1499     valc->last_motion = 0;
1500     valc->h_scroll_axis = -1;
1501     valc->v_scroll_axis = -1;
1502
1503     valc->numMotionEvents = numMotionEvents;
1504     valc->motionHintWindow = NullWindow;
1505
1506     if ((mode & OutOfProximity) && !dev->proximity)
1507         InitProximityClassDeviceStruct(dev);
1508
1509     dev->valuator = valc;
1510
1511     AllocateMotionHistory(dev);
1512
1513     for (i = 0; i < numAxes; i++) {
1514         InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS,
1515                                NO_AXIS_LIMITS, 0, 0, 0, mode);
1516         valc->axisVal[i] = 0;
1517     }
1518
1519     dev->last.numValuators = numAxes;
1520
1521     if (IsMaster(dev) ||        /* do not accelerate master or xtest devices */
1522         IsXTestDevice(dev, NULL))
1523         InitPointerAccelerationScheme(dev, PtrAccelNoOp);
1524     else
1525         InitPointerAccelerationScheme(dev, PtrAccelDefault);
1526     return TRUE;
1527 }
1528
1529 /* global list of acceleration schemes */
1530 ValuatorAccelerationRec pointerAccelerationScheme[] = {
1531     {PtrAccelNoOp, NULL, NULL, NULL, NULL},
1532     {PtrAccelPredictable, acceleratePointerPredictable, NULL,
1533      InitPredictableAccelerationScheme, AccelerationDefaultCleanup},
1534     {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL},
1535     {-1, NULL, NULL, NULL, NULL}        /* terminator */
1536 };
1537
1538 /**
1539  * install an acceleration scheme. returns TRUE on success, and should not
1540  * change anything if unsuccessful.
1541  */
1542 Bool
1543 InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme)
1544 {
1545     int x, i = -1;
1546     ValuatorClassPtr val;
1547
1548     val = dev->valuator;
1549
1550     if (!val)
1551         return FALSE;
1552
1553     if (IsMaster(dev) && scheme != PtrAccelNoOp)
1554         return FALSE;
1555
1556     for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
1557         if (pointerAccelerationScheme[x].number == scheme) {
1558             i = x;
1559             break;
1560         }
1561     }
1562
1563     if (-1 == i)
1564         return FALSE;
1565
1566     if (val->accelScheme.AccelCleanupProc)
1567         val->accelScheme.AccelCleanupProc(dev);
1568
1569     if (pointerAccelerationScheme[i].AccelInitProc) {
1570         if (!pointerAccelerationScheme[i].AccelInitProc(dev,
1571                                             &pointerAccelerationScheme[i])) {
1572             return FALSE;
1573         }
1574     }
1575     else {
1576         val->accelScheme = pointerAccelerationScheme[i];
1577     }
1578     return TRUE;
1579 }
1580
1581 Bool
1582 InitFocusClassDeviceStruct(DeviceIntPtr dev)
1583 {
1584     FocusClassPtr focc;
1585
1586     BUG_RETURN_VAL(dev == NULL, FALSE);
1587     BUG_RETURN_VAL(dev->focus != NULL, FALSE);
1588
1589     focc = malloc(sizeof(FocusClassRec));
1590     if (!focc)
1591         return FALSE;
1592     focc->win = PointerRootWin;
1593     focc->revert = None;
1594     focc->time = currentTime;
1595     focc->trace = (WindowPtr *) NULL;
1596     focc->traceSize = 0;
1597     focc->traceGood = 0;
1598     focc->sourceid = dev->id;
1599     dev->focus = focc;
1600     return TRUE;
1601 }
1602
1603 Bool
1604 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
1605 {
1606     PtrFeedbackPtr feedc;
1607
1608     BUG_RETURN_VAL(dev == NULL, FALSE);
1609
1610     feedc = malloc(sizeof(PtrFeedbackClassRec));
1611     if (!feedc)
1612         return FALSE;
1613     feedc->CtrlProc = controlProc;
1614     feedc->ctrl = defaultPointerControl;
1615     feedc->ctrl.id = 0;
1616     if ((feedc->next = dev->ptrfeed))
1617         feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
1618     dev->ptrfeed = feedc;
1619     (*controlProc) (dev, &feedc->ctrl);
1620     return TRUE;
1621 }
1622
1623 static LedCtrl defaultLedControl = {
1624     DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0
1625 };
1626
1627 static BellCtrl defaultBellControl = {
1628     DEFAULT_BELL,
1629     DEFAULT_BELL_PITCH,
1630     DEFAULT_BELL_DURATION,
1631     0
1632 };
1633
1634 static IntegerCtrl defaultIntegerControl = {
1635     DEFAULT_INT_RESOLUTION,
1636     DEFAULT_INT_MIN_VALUE,
1637     DEFAULT_INT_MAX_VALUE,
1638     DEFAULT_INT_DISPLAYED,
1639     0
1640 };
1641
1642 Bool
1643 InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev,
1644                                     StringCtrlProcPtr controlProc,
1645                                     int max_symbols, int num_symbols_supported,
1646                                     KeySym * symbols)
1647 {
1648     int i;
1649     StringFeedbackPtr feedc;
1650
1651     BUG_RETURN_VAL(dev == NULL, FALSE);
1652
1653     feedc = malloc(sizeof(StringFeedbackClassRec));
1654     if (!feedc)
1655         return FALSE;
1656     feedc->CtrlProc = controlProc;
1657     feedc->ctrl.num_symbols_supported = num_symbols_supported;
1658     feedc->ctrl.num_symbols_displayed = 0;
1659     feedc->ctrl.max_symbols = max_symbols;
1660     feedc->ctrl.symbols_supported =
1661         malloc(sizeof(KeySym) * num_symbols_supported);
1662     feedc->ctrl.symbols_displayed = malloc(sizeof(KeySym) * max_symbols);
1663     if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) {
1664         free(feedc->ctrl.symbols_supported);
1665         free(feedc->ctrl.symbols_displayed);
1666         free(feedc);
1667         return FALSE;
1668     }
1669     for (i = 0; i < num_symbols_supported; i++)
1670         *(feedc->ctrl.symbols_supported + i) = *symbols++;
1671     for (i = 0; i < max_symbols; i++)
1672         *(feedc->ctrl.symbols_displayed + i) = (KeySym) 0;
1673     feedc->ctrl.id = 0;
1674     if ((feedc->next = dev->stringfeed))
1675         feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
1676     dev->stringfeed = feedc;
1677     (*controlProc) (dev, &feedc->ctrl);
1678     return TRUE;
1679 }
1680
1681 Bool
1682 InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
1683                                   BellCtrlProcPtr controlProc)
1684 {
1685     BellFeedbackPtr feedc;
1686
1687     BUG_RETURN_VAL(dev == NULL, FALSE);
1688
1689     feedc = malloc(sizeof(BellFeedbackClassRec));
1690     if (!feedc)
1691         return FALSE;
1692     feedc->CtrlProc = controlProc;
1693     feedc->BellProc = bellProc;
1694     feedc->ctrl = defaultBellControl;
1695     feedc->ctrl.id = 0;
1696     if ((feedc->next = dev->bell))
1697         feedc->ctrl.id = dev->bell->ctrl.id + 1;
1698     dev->bell = feedc;
1699     (*controlProc) (dev, &feedc->ctrl);
1700     return TRUE;
1701 }
1702
1703 Bool
1704 InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev, LedCtrlProcPtr controlProc)
1705 {
1706     LedFeedbackPtr feedc;
1707
1708     BUG_RETURN_VAL(dev == NULL, FALSE);
1709
1710     feedc = malloc(sizeof(LedFeedbackClassRec));
1711     if (!feedc)
1712         return FALSE;
1713     feedc->CtrlProc = controlProc;
1714     feedc->ctrl = defaultLedControl;
1715     feedc->ctrl.id = 0;
1716     if ((feedc->next = dev->leds))
1717         feedc->ctrl.id = dev->leds->ctrl.id + 1;
1718     feedc->xkb_sli = NULL;
1719     dev->leds = feedc;
1720     (*controlProc) (dev, &feedc->ctrl);
1721     return TRUE;
1722 }
1723
1724 Bool
1725 InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev,
1726                                      IntegerCtrlProcPtr controlProc)
1727 {
1728     IntegerFeedbackPtr feedc;
1729
1730     BUG_RETURN_VAL(dev == NULL, FALSE);
1731
1732     feedc = malloc(sizeof(IntegerFeedbackClassRec));
1733     if (!feedc)
1734         return FALSE;
1735     feedc->CtrlProc = controlProc;
1736     feedc->ctrl = defaultIntegerControl;
1737     feedc->ctrl.id = 0;
1738     if ((feedc->next = dev->intfeed))
1739         feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
1740     dev->intfeed = feedc;
1741     (*controlProc) (dev, &feedc->ctrl);
1742     return TRUE;
1743 }
1744
1745 Bool
1746 InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
1747                         Atom *btn_labels, PtrCtrlProcPtr controlProc,
1748                         int numMotionEvents, int numAxes, Atom *axes_labels)
1749 {
1750     DeviceIntPtr dev = (DeviceIntPtr) device;
1751
1752     BUG_RETURN_VAL(dev == NULL, FALSE);
1753     BUG_RETURN_VAL(dev->button != NULL, FALSE);
1754     BUG_RETURN_VAL(dev->valuator != NULL, FALSE);
1755     BUG_RETURN_VAL(dev->ptrfeed != NULL, FALSE);
1756
1757     return (InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
1758             InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
1759                                           numMotionEvents, Relative) &&
1760             InitPtrFeedbackClassDeviceStruct(dev, controlProc));
1761 }
1762
1763 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
1764 Bool
1765 InitTouchDeviceStruct(DeviceIntPtr device, int numAxes,
1766                     Atom *axes_labels, int numMotionEvents, int valuatormode, int numTouches,
1767                     unsigned int touchMode, int numButtons, Atom *btn_labels, CARD8 *map)
1768 {
1769     BUG_RETURN_VAL(device == NULL, FALSE);
1770     BUG_RETURN_VAL(device->button != NULL, FALSE);
1771     BUG_RETURN_VAL(device->valuator != NULL, FALSE);
1772     BUG_RETURN_VAL(device->ptrfeed != NULL, FALSE);
1773
1774     return (InitValuatorClassDeviceStruct(device, numAxes, axes_labels,
1775                                           numMotionEvents, valuatormode) &&
1776                  InitTouchClassDeviceStruct(device, numTouches, touchMode, numAxes) &&
1777                  InitButtonClassDeviceStruct(device, numButtons, btn_labels, map));
1778 }
1779 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
1780
1781
1782 /**
1783  * Sets up multitouch capabilities on @device.
1784  *
1785  * @max_touches The maximum number of simultaneous touches, or 0 for unlimited.
1786  * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch).
1787  * @num_axes The number of touch valuator axes.
1788  */
1789 Bool
1790 InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
1791                            unsigned int mode, unsigned int num_axes)
1792 {
1793     TouchClassPtr touch;
1794     int i;
1795
1796     BUG_RETURN_VAL(device == NULL, FALSE);
1797     BUG_RETURN_VAL(device->touch != NULL, FALSE);
1798     BUG_RETURN_VAL(device->valuator == NULL, FALSE);
1799
1800     /* Check the mode is valid, and at least X and Y axes. */
1801     BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE);
1802     BUG_RETURN_VAL(num_axes < 2, FALSE);
1803
1804     if (num_axes > MAX_VALUATORS) {
1805         LogMessage(X_WARNING,
1806                    "Device '%s' has %d touch axes, only using first %d.\n",
1807                    device->name, num_axes, MAX_VALUATORS);
1808         num_axes = MAX_VALUATORS;
1809     }
1810
1811     touch = calloc(1, sizeof(*touch));
1812     if (!touch)
1813         return FALSE;
1814
1815     touch->max_touches = max_touches;
1816     if (max_touches == 0)
1817         max_touches = 5;        /* arbitrary number plucked out of the air */
1818     touch->touches = calloc(max_touches, sizeof(*touch->touches));
1819     if (!touch->touches)
1820         goto err;
1821     touch->num_touches = max_touches;
1822     for (i = 0; i < max_touches; i++)
1823         TouchInitTouchPoint(touch, device->valuator, i);
1824
1825     touch->mode = mode;
1826     touch->sourceid = device->id;
1827
1828     device->touch = touch;
1829     device->last.touches = calloc(max_touches, sizeof(*device->last.touches));
1830     device->last.num_touches = touch->num_touches;
1831     for (i = 0; i < touch->num_touches; i++)
1832         TouchInitDDXTouchPoint(device, &device->last.touches[i]);
1833
1834     return TRUE;
1835
1836  err:
1837     for (i = 0; i < touch->num_touches; i++)
1838         TouchFreeTouchPoint(device, i);
1839
1840     free(touch->touches);
1841     free(touch);
1842
1843     return FALSE;
1844 }
1845
1846 /*
1847  * Check if the given buffer contains elements between low (inclusive) and
1848  * high (inclusive) only.
1849  *
1850  * @return TRUE if the device map is invalid, FALSE otherwise.
1851  */
1852 Bool
1853 BadDeviceMap(BYTE * buff, int length, unsigned low, unsigned high, XID *errval)
1854 {
1855     int i;
1856
1857     for (i = 0; i < length; i++)
1858         if (buff[i]) {          /* only check non-zero elements */
1859             if ((low > buff[i]) || (high < buff[i])) {
1860                 *errval = buff[i];
1861                 return TRUE;
1862             }
1863         }
1864     return FALSE;
1865 }
1866
1867 int
1868 ProcSetModifierMapping(ClientPtr client)
1869 {
1870     xSetModifierMappingReply rep;
1871     int rc;
1872
1873     REQUEST(xSetModifierMappingReq);
1874     REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
1875
1876     if (client->req_len != ((stuff->numKeyPerModifier << 1) +
1877                             bytes_to_int32(sizeof(xSetModifierMappingReq))))
1878         return BadLength;
1879
1880     rep = (xSetModifierMappingReply) {
1881         .type = X_Reply,
1882         .sequenceNumber = client->sequence,
1883         .length = 0
1884     };
1885
1886     rc = change_modmap(client, PickKeyboard(client), (KeyCode *) &stuff[1],
1887                        stuff->numKeyPerModifier);
1888     if (rc == MappingFailed || rc == -1)
1889         return BadValue;
1890     if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
1891         rc != MappingBusy)
1892         return rc;
1893
1894     rep.success = rc;
1895
1896     WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
1897     return Success;
1898 }
1899
1900 int
1901 ProcGetModifierMapping(ClientPtr client)
1902 {
1903     xGetModifierMappingReply rep;
1904     int max_keys_per_mod = 0;
1905     KeyCode *modkeymap = NULL;
1906
1907     REQUEST_SIZE_MATCH(xReq);
1908
1909     generate_modkeymap(client, PickKeyboard(client), &modkeymap,
1910                        &max_keys_per_mod);
1911
1912     rep = (xGetModifierMappingReply) {
1913         .type = X_Reply,
1914         .numKeyPerModifier = max_keys_per_mod,
1915         .sequenceNumber = client->sequence,
1916     /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1917         .length = max_keys_per_mod << 1
1918     };
1919
1920     WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
1921     WriteToClient(client, max_keys_per_mod * 8, modkeymap);
1922
1923     free(modkeymap);
1924
1925     return Success;
1926 }
1927
1928 int
1929 ProcChangeKeyboardMapping(ClientPtr client)
1930 {
1931     REQUEST(xChangeKeyboardMappingReq);
1932     unsigned len;
1933     KeySymsRec keysyms;
1934     DeviceIntPtr pDev, tmp;
1935     int rc;
1936
1937     REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
1938
1939     len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
1940     if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
1941         return BadLength;
1942
1943     pDev = PickKeyboard(client);
1944
1945     if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
1946         (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
1947         client->errorValue = stuff->firstKeyCode;
1948         return BadValue;
1949
1950     }
1951     if (((unsigned) (stuff->firstKeyCode + stuff->keyCodes - 1) >
1952          pDev->key->xkbInfo->desc->max_key_code) ||
1953         (stuff->keySymsPerKeyCode == 0)) {
1954         client->errorValue = stuff->keySymsPerKeyCode;
1955         return BadValue;
1956     }
1957
1958     keysyms.minKeyCode = stuff->firstKeyCode;
1959     keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
1960     keysyms.mapWidth = stuff->keySymsPerKeyCode;
1961     keysyms.map = (KeySym *) &stuff[1];
1962
1963     rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1964     if (rc != Success)
1965         return rc;
1966
1967     XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
1968                           stuff->keyCodes, NULL, client);
1969
1970     for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
1971         if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev)
1972             continue;
1973         if (!tmp->key)
1974             continue;
1975
1976         rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1977         if (rc != Success)
1978             continue;
1979
1980         XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
1981                               stuff->keyCodes, NULL, client);
1982     }
1983
1984     return Success;
1985 }
1986
1987 int
1988 ProcSetPointerMapping(ClientPtr client)
1989 {
1990     BYTE *map;
1991     int ret;
1992     int i, j;
1993     DeviceIntPtr ptr = PickPointer(client);
1994     xSetPointerMappingReply rep;
1995
1996     REQUEST(xSetPointerMappingReq);
1997     REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
1998
1999     if (client->req_len !=
2000         bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
2001         return BadLength;
2002
2003     rep = (xSetPointerMappingReply) {
2004         .type = X_Reply,
2005         .success = MappingSuccess,
2006         .sequenceNumber = client->sequence,
2007         .length = 0
2008     };
2009     map = (BYTE *) &stuff[1];
2010
2011     /* So we're bounded here by the number of core buttons.  This check
2012      * probably wants disabling through XFixes. */
2013     /* MPX: With ClientPointer, we can return the right number of buttons.
2014      * Let's just hope nobody changed ClientPointer between GetPointerMapping
2015      * and SetPointerMapping
2016      */
2017     if (stuff->nElts != ptr->button->numButtons) {
2018         client->errorValue = stuff->nElts;
2019         return BadValue;
2020     }
2021
2022     /* Core protocol specs don't allow for duplicate mappings; this check
2023      * almost certainly wants disabling through XFixes too. */
2024     for (i = 0; i < stuff->nElts; i++) {
2025         for (j = i + 1; j < stuff->nElts; j++) {
2026             if (map[i] && map[i] == map[j]) {
2027                 client->errorValue = map[i];
2028                 return BadValue;
2029             }
2030         }
2031     }
2032
2033     ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
2034     if (ret == MappingBusy)
2035         rep.success = ret;
2036     else if (ret == -1)
2037         return BadValue;
2038     else if (ret != Success)
2039         return ret;
2040
2041     WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
2042     return Success;
2043 }
2044
2045 int
2046 ProcGetKeyboardMapping(ClientPtr client)
2047 {
2048     xGetKeyboardMappingReply rep;
2049     DeviceIntPtr kbd = PickKeyboard(client);
2050     XkbDescPtr xkb;
2051     KeySymsPtr syms;
2052     int rc;
2053
2054     REQUEST(xGetKeyboardMappingReq);
2055     REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
2056
2057     rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
2058     if (rc != Success)
2059         return rc;
2060
2061     xkb = kbd->key->xkbInfo->desc;
2062
2063     if ((stuff->firstKeyCode < xkb->min_key_code) ||
2064         (stuff->firstKeyCode > xkb->max_key_code)) {
2065         client->errorValue = stuff->firstKeyCode;
2066         return BadValue;
2067     }
2068     if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
2069         client->errorValue = stuff->count;
2070         return BadValue;
2071     }
2072
2073     syms = XkbGetCoreMap(kbd);
2074     if (!syms)
2075         return BadAlloc;
2076
2077     rep = (xGetKeyboardMappingReply) {
2078         .type = X_Reply,
2079         .keySymsPerKeyCode = syms->mapWidth,
2080         .sequenceNumber = client->sequence,
2081         /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
2082         .length = syms->mapWidth * stuff->count
2083     };
2084     WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
2085     client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
2086     WriteSwappedDataToClient(client,
2087                              syms->mapWidth * stuff->count * sizeof(KeySym),
2088                              &syms->map[syms->mapWidth * (stuff->firstKeyCode -
2089                                                           syms->minKeyCode)]);
2090     free(syms->map);
2091     free(syms);
2092
2093     return Success;
2094 }
2095
2096 int
2097 ProcGetPointerMapping(ClientPtr client)
2098 {
2099     xGetPointerMappingReply rep;
2100
2101     /* Apps may get different values each time they call GetPointerMapping as
2102      * the ClientPointer could change. */
2103     DeviceIntPtr ptr = PickPointer(client);
2104     ButtonClassPtr butc = ptr->button;
2105     int nElts;
2106     int rc;
2107
2108     REQUEST_SIZE_MATCH(xReq);
2109
2110     rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
2111     if (rc != Success)
2112         return rc;
2113
2114     nElts = (butc) ? butc->numButtons : 0;
2115     rep = (xGetPointerMappingReply) {
2116         .type = X_Reply,
2117         .nElts = nElts,
2118         .sequenceNumber = client->sequence,
2119         .length = ((unsigned) nElts + (4 - 1)) / 4
2120     };
2121     WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
2122     if (butc)
2123         WriteToClient(client, nElts, &butc->map[1]);
2124     return Success;
2125 }
2126
2127 void
2128 NoteLedState(DeviceIntPtr keybd, int led, Bool on)
2129 {
2130     KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
2131
2132     if (on)
2133         ctrl->leds |= ((Leds) 1 << (led - 1));
2134     else
2135         ctrl->leds &= ~((Leds) 1 << (led - 1));
2136 }
2137
2138 int
2139 Ones(unsigned long mask)
2140 {                               /* HACKMEM 169 */
2141     unsigned long y;
2142
2143     y = (mask >> 1) & 033333333333;
2144     y = mask - y - ((y >> 1) & 033333333333);
2145     return (((y + (y >> 3)) & 030707070707) % 077);
2146 }
2147
2148 static int
2149 DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist,
2150                         BITS32 vmask)
2151 {
2152 #define DO_ALL    (-1)
2153     KeybdCtrl ctrl;
2154     int t;
2155     int led = DO_ALL;
2156     int key = DO_ALL;
2157     BITS32 index2;
2158     int mask = vmask, i;
2159     XkbEventCauseRec cause;
2160
2161     ctrl = keybd->kbdfeed->ctrl;
2162     while (vmask) {
2163         index2 = (BITS32) lowbit(vmask);
2164         vmask &= ~index2;
2165         switch (index2) {
2166         case KBKeyClickPercent:
2167             t = (INT8) *vlist;
2168             vlist++;
2169             if (t == -1) {
2170                 t = defaultKeyboardControl.click;
2171             }
2172             else if (t < 0 || t > 100) {
2173                 client->errorValue = t;
2174                 return BadValue;
2175             }
2176             ctrl.click = t;
2177             break;
2178         case KBBellPercent:
2179             t = (INT8) *vlist;
2180             vlist++;
2181             if (t == -1) {
2182                 t = defaultKeyboardControl.bell;
2183             }
2184             else if (t < 0 || t > 100) {
2185                 client->errorValue = t;
2186                 return BadValue;
2187             }
2188             ctrl.bell = t;
2189             break;
2190         case KBBellPitch:
2191             t = (INT16) *vlist;
2192             vlist++;
2193             if (t == -1) {
2194                 t = defaultKeyboardControl.bell_pitch;
2195             }
2196             else if (t < 0) {
2197                 client->errorValue = t;
2198                 return BadValue;
2199             }
2200             ctrl.bell_pitch = t;
2201             break;
2202         case KBBellDuration:
2203             t = (INT16) *vlist;
2204             vlist++;
2205             if (t == -1)
2206                 t = defaultKeyboardControl.bell_duration;
2207             else if (t < 0) {
2208                 client->errorValue = t;
2209                 return BadValue;
2210             }
2211             ctrl.bell_duration = t;
2212             break;
2213         case KBLed:
2214             led = (CARD8) *vlist;
2215             vlist++;
2216             if (led < 1 || led > 32) {
2217                 client->errorValue = led;
2218                 return BadValue;
2219             }
2220             if (!(mask & KBLedMode))
2221                 return BadMatch;
2222             break;
2223         case KBLedMode:
2224             t = (CARD8) *vlist;
2225             vlist++;
2226             if (t == LedModeOff) {
2227                 if (led == DO_ALL)
2228                     ctrl.leds = 0x0;
2229                 else
2230                     ctrl.leds &= ~(((Leds) (1)) << (led - 1));
2231             }
2232             else if (t == LedModeOn) {
2233                 if (led == DO_ALL)
2234                     ctrl.leds = ~0L;
2235                 else
2236                     ctrl.leds |= (((Leds) (1)) << (led - 1));
2237             }
2238             else {
2239                 client->errorValue = t;
2240                 return BadValue;
2241             }
2242
2243             XkbSetCauseCoreReq(&cause, X_ChangeKeyboardControl, client);
2244             XkbSetIndicators(keybd, ((led == DO_ALL) ? ~0L : (1L << (led - 1))),
2245                              ctrl.leds, &cause);
2246             ctrl.leds = keybd->kbdfeed->ctrl.leds;
2247
2248             break;
2249         case KBKey:
2250             key = (KeyCode) *vlist;
2251             vlist++;
2252             if ((KeyCode) key < keybd->key->xkbInfo->desc->min_key_code ||
2253                 (KeyCode) key > keybd->key->xkbInfo->desc->max_key_code) {
2254                 client->errorValue = key;
2255                 return BadValue;
2256             }
2257             if (!(mask & KBAutoRepeatMode))
2258                 return BadMatch;
2259             break;
2260         case KBAutoRepeatMode:
2261             i = (key >> 3);
2262             mask = (1 << (key & 7));
2263             t = (CARD8) *vlist;
2264             vlist++;
2265             if (key != DO_ALL)
2266                 XkbDisableComputedAutoRepeats(keybd, key);
2267             if (t == AutoRepeatModeOff) {
2268                 if (key == DO_ALL)
2269                     ctrl.autoRepeat = FALSE;
2270                 else
2271                     ctrl.autoRepeats[i] &= ~mask;
2272             }
2273             else if (t == AutoRepeatModeOn) {
2274                 if (key == DO_ALL)
2275                     ctrl.autoRepeat = TRUE;
2276                 else
2277                     ctrl.autoRepeats[i] |= mask;
2278             }
2279             else if (t == AutoRepeatModeDefault) {
2280                 if (key == DO_ALL)
2281                     ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
2282                 else
2283                     ctrl.autoRepeats[i] =
2284                         (ctrl.autoRepeats[i] & ~mask) |
2285                         (defaultKeyboardControl.autoRepeats[i] & mask);
2286             }
2287             else {
2288                 client->errorValue = t;
2289                 return BadValue;
2290             }
2291             break;
2292         default:
2293             client->errorValue = mask;
2294             return BadValue;
2295         }
2296     }
2297     keybd->kbdfeed->ctrl = ctrl;
2298
2299     /* The XKB RepeatKeys control and core protocol global autorepeat */
2300     /* value are linked */
2301     XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
2302
2303     return Success;
2304
2305 #undef DO_ALL
2306 }
2307
2308 /**
2309  * Changes kbd control on the ClientPointer and all attached SDs.
2310  */
2311 int
2312 ProcChangeKeyboardControl(ClientPtr client)
2313 {
2314     XID *vlist;
2315     BITS32 vmask;
2316     int ret = Success, error = Success;
2317     DeviceIntPtr pDev = NULL, keyboard;
2318
2319     REQUEST(xChangeKeyboardControlReq);
2320
2321     REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
2322
2323     vmask = stuff->mask;
2324     vlist = (XID *) &stuff[1];
2325
2326     if (client->req_len !=
2327         (sizeof(xChangeKeyboardControlReq) >> 2) + Ones(vmask))
2328         return BadLength;
2329
2330     keyboard = PickKeyboard(client);
2331
2332     for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2333         if ((pDev == keyboard ||
2334              (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2335             && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2336             ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
2337             if (ret != Success)
2338                 return ret;
2339         }
2340     }
2341
2342     for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2343         if ((pDev == keyboard ||
2344              (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2345             && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2346             ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
2347             if (ret != Success)
2348                 error = ret;
2349         }
2350     }
2351
2352     return error;
2353 }
2354
2355 int
2356 ProcGetKeyboardControl(ClientPtr client)
2357 {
2358     int rc, i;
2359     DeviceIntPtr kbd = PickKeyboard(client);
2360     KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
2361     xGetKeyboardControlReply rep;
2362
2363     REQUEST_SIZE_MATCH(xReq);
2364
2365     rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
2366     if (rc != Success)
2367         return rc;
2368
2369     rep = (xGetKeyboardControlReply) {
2370         .type = X_Reply,
2371         .globalAutoRepeat = ctrl->autoRepeat,
2372         .sequenceNumber = client->sequence,
2373         .length = 5,
2374         .ledMask = ctrl->leds,
2375         .keyClickPercent = ctrl->click,
2376         .bellPercent = ctrl->bell,
2377         .bellPitch = ctrl->bell_pitch,
2378         .bellDuration = ctrl->bell_duration
2379     };
2380     for (i = 0; i < 32; i++)
2381         rep.map[i] = ctrl->autoRepeats[i];
2382     WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
2383     return Success;
2384 }
2385
2386 int
2387 ProcBell(ClientPtr client)
2388 {
2389     DeviceIntPtr dev, keybd = PickKeyboard(client);
2390     int base = keybd->kbdfeed->ctrl.bell;
2391     int newpercent;
2392     int rc;
2393
2394     REQUEST(xBellReq);
2395     REQUEST_SIZE_MATCH(xBellReq);
2396
2397     if (stuff->percent < -100 || stuff->percent > 100) {
2398         client->errorValue = stuff->percent;
2399         return BadValue;
2400     }
2401
2402     newpercent = (base * stuff->percent) / 100;
2403     if (stuff->percent < 0)
2404         newpercent = base + newpercent;
2405     else
2406         newpercent = base - newpercent + stuff->percent;
2407
2408     for (dev = inputInfo.devices; dev; dev = dev->next) {
2409         if ((dev == keybd ||
2410              (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
2411             dev->kbdfeed && dev->kbdfeed->BellProc) {
2412
2413             rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
2414             if (rc != Success)
2415                 return rc;
2416             XkbHandleBell(FALSE, FALSE, dev, newpercent,
2417                           &dev->kbdfeed->ctrl, 0, None, NULL, client);
2418         }
2419     }
2420
2421     return Success;
2422 }
2423
2424 int
2425 ProcChangePointerControl(ClientPtr client)
2426 {
2427     DeviceIntPtr dev, mouse = PickPointer(client);
2428     PtrCtrl ctrl;               /* might get BadValue part way through */
2429     int rc;
2430
2431     REQUEST(xChangePointerControlReq);
2432     REQUEST_SIZE_MATCH(xChangePointerControlReq);
2433
2434     ctrl = mouse->ptrfeed->ctrl;
2435     if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
2436         client->errorValue = stuff->doAccel;
2437         return BadValue;
2438     }
2439     if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
2440         client->errorValue = stuff->doThresh;
2441         return BadValue;
2442     }
2443     if (stuff->doAccel) {
2444         if (stuff->accelNum == -1) {
2445             ctrl.num = defaultPointerControl.num;
2446         }
2447         else if (stuff->accelNum < 0) {
2448             client->errorValue = stuff->accelNum;
2449             return BadValue;
2450         }
2451         else {
2452             ctrl.num = stuff->accelNum;
2453         }
2454
2455         if (stuff->accelDenum == -1) {
2456             ctrl.den = defaultPointerControl.den;
2457         }
2458         else if (stuff->accelDenum <= 0) {
2459             client->errorValue = stuff->accelDenum;
2460             return BadValue;
2461         }
2462         else {
2463             ctrl.den = stuff->accelDenum;
2464         }
2465     }
2466     if (stuff->doThresh) {
2467         if (stuff->threshold == -1) {
2468             ctrl.threshold = defaultPointerControl.threshold;
2469         }
2470         else if (stuff->threshold < 0) {
2471             client->errorValue = stuff->threshold;
2472             return BadValue;
2473         }
2474         else {
2475             ctrl.threshold = stuff->threshold;
2476         }
2477     }
2478
2479     for (dev = inputInfo.devices; dev; dev = dev->next) {
2480         if ((dev == mouse ||
2481              (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2482             dev->ptrfeed) {
2483             rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
2484             if (rc != Success)
2485                 return rc;
2486         }
2487     }
2488
2489     for (dev = inputInfo.devices; dev; dev = dev->next) {
2490         if ((dev == mouse ||
2491              (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2492             dev->ptrfeed) {
2493             dev->ptrfeed->ctrl = ctrl;
2494         }
2495     }
2496
2497     return Success;
2498 }
2499
2500 int
2501 ProcGetPointerControl(ClientPtr client)
2502 {
2503     DeviceIntPtr ptr = PickPointer(client);
2504     PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
2505     xGetPointerControlReply rep;
2506     int rc;
2507
2508     REQUEST_SIZE_MATCH(xReq);
2509
2510     rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
2511     if (rc != Success)
2512         return rc;
2513
2514     rep = (xGetPointerControlReply) {
2515         .type = X_Reply,
2516         .sequenceNumber = client->sequence,
2517         .length = 0,
2518         .accelNumerator = ctrl->num,
2519         .accelDenominator = ctrl->den,
2520         .threshold = ctrl->threshold
2521     };
2522     WriteReplyToClient(client, sizeof(xGenericReply), &rep);
2523     return Success;
2524 }
2525
2526 void
2527 MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
2528 {
2529     GrabPtr grab = dev->deviceGrab.grab;
2530
2531     if ((grab && SameClient(grab, client) &&
2532          ((grab->eventMask & PointerMotionHintMask) ||
2533           (grab->ownerEvents &&
2534            (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2535             PointerMotionHintMask)))) ||
2536         (!grab &&
2537          (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2538           PointerMotionHintMask)))
2539         dev->valuator->motionHintWindow = NullWindow;
2540 }
2541
2542 int
2543 ProcGetMotionEvents(ClientPtr client)
2544 {
2545     WindowPtr pWin;
2546     xTimecoord *coords = (xTimecoord *) NULL;
2547     xGetMotionEventsReply rep;
2548     int i, count, xmin, xmax, ymin, ymax, rc;
2549     unsigned long nEvents;
2550     DeviceIntPtr mouse = PickPointer(client);
2551     TimeStamp start, stop;
2552
2553     REQUEST(xGetMotionEventsReq);
2554     REQUEST_SIZE_MATCH(xGetMotionEventsReq);
2555
2556     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2557     if (rc != Success)
2558         return rc;
2559     rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
2560     if (rc != Success)
2561         return rc;
2562
2563     if (mouse->valuator->motionHintWindow)
2564         MaybeStopHint(mouse, client);
2565     rep = (xGetMotionEventsReply) {
2566         .type = X_Reply,
2567         .sequenceNumber = client->sequence
2568     };
2569     nEvents = 0;
2570     start = ClientTimeToServerTime(stuff->start);
2571     stop = ClientTimeToServerTime(stuff->stop);
2572     if ((CompareTimeStamps(start, stop) != LATER) &&
2573         (CompareTimeStamps(start, currentTime) != LATER) &&
2574         mouse->valuator->numMotionEvents) {
2575         if (CompareTimeStamps(stop, currentTime) == LATER)
2576             stop = currentTime;
2577         count = GetMotionHistory(mouse, &coords, start.milliseconds,
2578                                  stop.milliseconds, pWin->drawable.pScreen,
2579                                  TRUE);
2580         xmin = pWin->drawable.x - wBorderWidth(pWin);
2581         xmax = pWin->drawable.x + (int) pWin->drawable.width +
2582             wBorderWidth(pWin);
2583         ymin = pWin->drawable.y - wBorderWidth(pWin);
2584         ymax = pWin->drawable.y + (int) pWin->drawable.height +
2585             wBorderWidth(pWin);
2586         for (i = 0; i < count; i++)
2587             if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
2588                 (ymin <= coords[i].y) && (coords[i].y < ymax)) {
2589                 coords[nEvents].time = coords[i].time;
2590                 coords[nEvents].x = coords[i].x - pWin->drawable.x;
2591                 coords[nEvents].y = coords[i].y - pWin->drawable.y;
2592                 nEvents++;
2593             }
2594     }
2595     rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
2596     rep.nEvents = nEvents;
2597     WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
2598     if (nEvents) {
2599         client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
2600         WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
2601                                  (char *) coords);
2602     }
2603     free(coords);
2604     return Success;
2605 }
2606
2607 int
2608 ProcQueryKeymap(ClientPtr client)
2609 {
2610     xQueryKeymapReply rep;
2611     int rc, i;
2612     DeviceIntPtr keybd = PickKeyboard(client);
2613     CARD8 *down = keybd->key->down;
2614
2615     REQUEST_SIZE_MATCH(xReq);
2616     rep = (xQueryKeymapReply) {
2617         .type = X_Reply,
2618         .sequenceNumber = client->sequence,
2619         .length = 2
2620     };
2621
2622     rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
2623     /* If rc is Success, we're allowed to copy out the keymap.
2624      * If it's BadAccess, we leave it empty & lie to the client.
2625      */
2626     if (rc == Success) {
2627         for (i = 0; i < 32; i++)
2628             rep.map[i] = down[i];
2629     }
2630     else if (rc != BadAccess)
2631         return rc;
2632
2633     WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
2634
2635     return Success;
2636 }
2637
2638 /**
2639  * Recalculate the number of buttons for the master device. The number of
2640  * buttons on the master device is equal to the number of buttons on the
2641  * slave device with the highest number of buttons.
2642  */
2643 static void
2644 RecalculateMasterButtons(DeviceIntPtr slave)
2645 {
2646     DeviceIntPtr dev, master;
2647     int maxbuttons = 0;
2648
2649     if (!slave->button || IsMaster(slave))
2650         return;
2651
2652     master = GetMaster(slave, MASTER_POINTER);
2653     if (!master)
2654         return;
2655
2656     for (dev = inputInfo.devices; dev; dev = dev->next) {
2657         if (IsMaster(dev) ||
2658             GetMaster(dev, MASTER_ATTACHED) != master || !dev->button)
2659             continue;
2660
2661         maxbuttons = max(maxbuttons, dev->button->numButtons);
2662     }
2663
2664     if (master->button && master->button->numButtons != maxbuttons) {
2665         int i;
2666         DeviceChangedEvent event = {
2667             .header = ET_Internal,
2668             .type = ET_DeviceChanged,
2669             .time = GetTimeInMillis(),
2670             .deviceid = master->id,
2671             .flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE,
2672             .buttons.num_buttons = maxbuttons
2673         };
2674
2675         master->button->numButtons = maxbuttons;
2676
2677         memcpy(&event.buttons.names, master->button->labels, maxbuttons *
2678                sizeof(Atom));
2679
2680         if (master->valuator) {
2681             event.num_valuators = master->valuator->numAxes;
2682             for (i = 0; i < event.num_valuators; i++) {
2683                 event.valuators[i].min = master->valuator->axes[i].min_value;
2684                 event.valuators[i].max = master->valuator->axes[i].max_value;
2685                 event.valuators[i].resolution =
2686                     master->valuator->axes[i].resolution;
2687                 event.valuators[i].mode = master->valuator->axes[i].mode;
2688                 event.valuators[i].name = master->valuator->axes[i].label;
2689             }
2690         }
2691
2692         if (master->key) {
2693             event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
2694             event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
2695         }
2696
2697         XISendDeviceChangedEvent(master, &event);
2698     }
2699 }
2700
2701 /**
2702  * Generate release events for all keys/button currently down on this
2703  * device.
2704  */
2705 void
2706 ReleaseButtonsAndKeys(DeviceIntPtr dev)
2707 {
2708     InternalEvent *eventlist = InitEventList(GetMaximumEventsNum());
2709     ButtonClassPtr b = dev->button;
2710     KeyClassPtr k = dev->key;
2711     int i, j, nevents;
2712
2713     if (!eventlist)             /* no release events for you */
2714         return;
2715
2716     /* Release all buttons */
2717     for (i = 0; b && i < b->numButtons; i++) {
2718         if (BitIsOn(b->down, i)) {
2719             nevents =
2720                 GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
2721             for (j = 0; j < nevents; j++)
2722                 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2723         }
2724     }
2725
2726     /* Release all keys */
2727     for (i = 0; k && i < MAP_LENGTH; i++) {
2728         if (BitIsOn(k->down, i)) {
2729             nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
2730             for (j = 0; j < nevents; j++)
2731                 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2732         }
2733     }
2734
2735     FreeEventList(eventlist, GetMaximumEventsNum());
2736 }
2737
2738 /**
2739  * Attach device 'dev' to device 'master'.
2740  * Client is set to the client that issued the request, or NULL if it comes
2741  * from some internal automatic pairing.
2742  *
2743  * Master may be NULL to set the device floating.
2744  *
2745  * We don't allow multi-layer hierarchies right now. You can't attach a slave
2746  * to another slave.
2747  */
2748 int
2749 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
2750 {
2751     ScreenPtr screen;
2752
2753     if (!dev || IsMaster(dev))
2754         return BadDevice;
2755
2756     if (master && !IsMaster(master))    /* can't attach to slaves */
2757         return BadDevice;
2758
2759     /* set from floating to floating? */
2760     if (IsFloating(dev) && !master && dev->enabled)
2761         return Success;
2762
2763     /* free the existing sprite. */
2764     if (IsFloating(dev) && dev->spriteInfo->paired == dev) {
2765         screen = miPointerGetScreen(dev);
2766         screen->DeviceCursorCleanup(dev, screen);
2767         free(dev->spriteInfo->sprite);
2768     }
2769
2770     dev->master = master;
2771
2772     /* If device is set to floating, we need to create a sprite for it,
2773      * otherwise things go bad. However, we don't want to render the cursor,
2774      * so we reset spriteOwner.
2775      * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
2776      * alloc new memory but overwrite the previous one.
2777      */
2778     if (!master) {
2779         WindowPtr currentRoot;
2780
2781         if (dev->spriteInfo->sprite)
2782             currentRoot = GetCurrentRootWindow(dev);
2783         else                    /* new device auto-set to floating */
2784             currentRoot = screenInfo.screens[0]->root;
2785
2786         /* we need to init a fake sprite */
2787         screen = currentRoot->drawable.pScreen;
2788         screen->DeviceCursorInitialize(dev, screen);
2789         dev->spriteInfo->sprite = NULL;
2790         InitializeSprite(dev, currentRoot);
2791         dev->spriteInfo->spriteOwner = FALSE;
2792         dev->spriteInfo->paired = dev;
2793     }
2794     else {
2795         dev->spriteInfo->sprite = master->spriteInfo->sprite;
2796         dev->spriteInfo->paired = master;
2797         dev->spriteInfo->spriteOwner = FALSE;
2798
2799         XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
2800         RecalculateMasterButtons(master);
2801     }
2802
2803     /* XXX: in theory, the MD should change back to its old, original
2804      * classes when the last SD is detached. Thanks to the XTEST devices,
2805      * we'll always have an SD attached until the MD is removed.
2806      * So let's not worry about that.
2807      */
2808
2809     return Success;
2810 }
2811
2812 /**
2813  * Return the device paired with the given device or NULL.
2814  * Returns the device paired with the parent master if the given device is a
2815  * slave device.
2816  */
2817 DeviceIntPtr
2818 GetPairedDevice(DeviceIntPtr dev)
2819 {
2820     if (!IsMaster(dev) && !IsFloating(dev))
2821         dev = GetMaster(dev, MASTER_ATTACHED);
2822
2823     return dev->spriteInfo->paired;
2824 }
2825
2826 /**
2827  * Returns the requested master for this device.
2828  * The return values are:
2829  * - MASTER_ATTACHED: the master for this device or NULL for a floating
2830  *   slave.
2831  * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a
2832  *   floating slave
2833  * - MASTER_POINTER: the master keyboard for this device or NULL for a
2834  *   floating slave
2835  * - POINTER_OR_FLOAT: the master pointer for this device or the device for
2836  *   a floating slave
2837  * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for
2838  *   a floating slave
2839  *
2840  * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED,
2841  * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT.
2842  * @return The requested master device
2843  */
2844 DeviceIntPtr
2845 GetMaster(DeviceIntPtr dev, int which)
2846 {
2847     DeviceIntPtr master;
2848
2849     if (IsMaster(dev))
2850         master = dev;
2851     else {
2852         master = dev->master;
2853         if (!master &&
2854             (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT))
2855             return dev;
2856     }
2857
2858     if (master && which != MASTER_ATTACHED) {
2859         if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) {
2860             if (master->type != MASTER_KEYBOARD)
2861                 master = GetPairedDevice(master);
2862         }
2863         else {
2864             if (master->type != MASTER_POINTER)
2865                 master = GetPairedDevice(master);
2866         }
2867     }
2868
2869     return master;
2870 }
2871
2872 /**
2873  * Create a new device pair (== one pointer, one keyboard device).
2874  * Only allocates the devices, you will need to call ActivateDevice() and
2875  * EnableDevice() manually.
2876  * Either a master or a slave device can be created depending on
2877  * the value for master.
2878  */
2879 int
2880 AllocDevicePair(ClientPtr client, const char *name,
2881                 DeviceIntPtr *ptr,
2882                 DeviceIntPtr *keybd,
2883                 DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master)
2884 {
2885     DeviceIntPtr pointer;
2886     DeviceIntPtr keyboard;
2887     char *dev_name;
2888
2889     *ptr = *keybd = NULL;
2890
2891     XkbInitPrivates();
2892
2893     pointer = AddInputDevice(client, ptr_proc, TRUE);
2894
2895     if (!pointer)
2896         return BadAlloc;
2897
2898     if (asprintf(&dev_name, "%s pointer", name) == -1) {
2899         RemoveDevice(pointer, FALSE);
2900
2901         return BadAlloc;
2902     }
2903     pointer->name = dev_name;
2904
2905     pointer->public.processInputProc = ProcessOtherEvent;
2906     pointer->public.realInputProc = ProcessOtherEvent;
2907     XkbSetExtension(pointer, ProcessPointerEvent);
2908     pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
2909     pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
2910     pointer->coreEvents = TRUE;
2911     pointer->spriteInfo->spriteOwner = TRUE;
2912
2913     pointer->lastSlave = NULL;
2914     pointer->last.slave = NULL;
2915     pointer->type = (master) ? MASTER_POINTER : SLAVE;
2916
2917     keyboard = AddInputDevice(client, keybd_proc, TRUE);
2918     if (!keyboard) {
2919         RemoveDevice(pointer, FALSE);
2920
2921         return BadAlloc;
2922     }
2923
2924     if (asprintf(&dev_name, "%s keyboard", name) == -1) {
2925         RemoveDevice(keyboard, FALSE);
2926         RemoveDevice(pointer, FALSE);
2927
2928         return BadAlloc;
2929     }
2930     keyboard->name = dev_name;
2931
2932     keyboard->public.processInputProc = ProcessOtherEvent;
2933     keyboard->public.realInputProc = ProcessOtherEvent;
2934     XkbSetExtension(keyboard, ProcessKeyboardEvent);
2935     keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
2936     keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
2937     keyboard->coreEvents = TRUE;
2938     keyboard->spriteInfo->spriteOwner = FALSE;
2939
2940     keyboard->lastSlave = NULL;
2941     keyboard->last.slave = NULL;
2942     keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
2943
2944     /* The ClassesRec stores the device classes currently not used. */
2945     if (IsMaster(pointer)) {
2946         pointer->unused_classes = calloc(1, sizeof(ClassesRec));
2947         keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
2948     }
2949
2950     *ptr = pointer;
2951
2952     *keybd = keyboard;
2953
2954     return Success;
2955 }
2956
2957 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
2958 int
2959 AllocHWKeyTouchDevicePair(ClientPtr client, const char *name,
2960                 DeviceIntPtr *ptr,
2961                 DeviceIntPtr *keybd,
2962                 DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master)
2963 {
2964     DeviceIntPtr pointer;
2965     DeviceIntPtr keyboard;
2966     char *dev_name;
2967
2968     *ptr = *keybd = NULL;
2969
2970     XkbInitPrivates();
2971
2972     pointer = AddInputDevice(client, ptr_proc, TRUE);
2973
2974     if (!pointer)
2975         return BadAlloc;
2976
2977     if (asprintf(&dev_name, "%s touch", name) == -1) {
2978         RemoveDevice(pointer, FALSE);
2979
2980         return BadAlloc;
2981     }
2982     pointer->name = dev_name;
2983
2984     pointer->public.processInputProc = ProcessOtherEvent;
2985     pointer->public.realInputProc = ProcessOtherEvent;
2986     XkbSetExtension(pointer, ProcessPointerEvent);
2987     pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
2988     pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
2989     pointer->coreEvents = TRUE;
2990     pointer->spriteInfo->spriteOwner = TRUE;
2991
2992     pointer->lastSlave = NULL;
2993     pointer->last.slave = NULL;
2994     pointer->type = (master) ? MASTER_POINTER : SLAVE;
2995
2996     keyboard = AddInputDevice(client, keybd_proc, TRUE);
2997     if (!keyboard) {
2998         RemoveDevice(pointer, FALSE);
2999
3000         return BadAlloc;
3001     }
3002
3003     if (asprintf(&dev_name, "%s functionkeys", name) == -1) {
3004         RemoveDevice(keyboard, FALSE);
3005         RemoveDevice(pointer, FALSE);
3006
3007         return BadAlloc;
3008     }
3009     keyboard->name = dev_name;
3010
3011     keyboard->public.processInputProc = ProcessOtherEvent;
3012     keyboard->public.realInputProc = ProcessOtherEvent;
3013     XkbSetExtension(keyboard, ProcessKeyboardEvent);
3014     keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
3015     keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
3016     keyboard->coreEvents = TRUE;
3017     keyboard->spriteInfo->spriteOwner = FALSE;
3018
3019     keyboard->lastSlave = NULL;
3020     keyboard->last.slave = NULL;
3021     keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
3022
3023     /* The ClassesRec stores the device classes currently not used. */
3024     if (IsMaster(pointer)) {
3025         pointer->unused_classes = calloc(1, sizeof(ClassesRec));
3026         keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
3027     }
3028
3029     *ptr = pointer;
3030
3031     *keybd = keyboard;
3032
3033     return Success;
3034 }
3035 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
3036
3037 /**
3038  * Return Relative or Absolute for the device.
3039  */
3040 int
3041 valuator_get_mode(DeviceIntPtr dev, int axis)
3042 {
3043     return (dev->valuator->axes[axis].mode & DeviceMode);
3044 }
3045
3046 /**
3047  * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
3048  * set the mode for all axes.
3049  */
3050 void
3051 valuator_set_mode(DeviceIntPtr dev, int axis, int mode)
3052 {
3053     if (axis != VALUATOR_MODE_ALL_AXES)
3054         dev->valuator->axes[axis].mode = mode;
3055     else {
3056         int i;
3057
3058         for (i = 0; i < dev->valuator->numAxes; i++)
3059             dev->valuator->axes[i].mode = mode;
3060     }
3061 }