]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/xserver.git/blob - dix/devices.c
Imported Debian patch 1.11.4-0ubuntu3
[glsdk/xserver.git] / dix / devices.c
1 /************************************************************
3 Copyright 1987, 1998  The Open Group
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.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
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.
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.
26 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28                         All Rights Reserved
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
46 ********************************************************/
50 #ifdef HAVE_DIX_CONFIG_H
51 #include <dix-config.h>
52 #endif
54 #include <X11/X.h>
55 #include "misc.h"
56 #include "resource.h"
57 #include <X11/Xproto.h>
58 #include <X11/Xatom.h>
59 #include "windowstr.h"
60 #include "inputstr.h"
61 #include "scrnintstr.h"
62 #include "cursorstr.h"
63 #include "dixstruct.h"
64 #include "ptrveloc.h"
65 #include "site.h"
66 #include "xkbsrv.h"
67 #include "privates.h"
68 #include "xace.h"
69 #include "mi.h"
71 #include "dispatch.h"
72 #include "swaprep.h"
73 #include "dixevents.h"
74 #include "mipointer.h"
75 #include "eventstr.h"
76 #include "dixgrabs.h"
78 #include <X11/extensions/XI.h>
79 #include <X11/extensions/XI2.h>
80 #include <X11/extensions/XIproto.h>
81 #include <math.h>
82 #include <pixman.h>
83 #include "exglobals.h"
84 #include "exevents.h"
85 #include "xiquerydevice.h" /* for SizeDeviceClasses */
86 #include "xiproperty.h"
87 #include "enterleave.h" /* for EnterWindow() */
88 #include "xserver-properties.h"
89 #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */
91 /** @file
92  * This file handles input device-related stuff.
93  */
95 static void RecalculateMasterButtons(DeviceIntPtr slave);
97 static void
98 DeviceSetTransform(DeviceIntPtr dev, float *transform)
99 {
100     struct pixman_f_transform scale;
101     double sx, sy;
102     int x, y;
104     /**
105      * calculate combined transformation matrix:
106      *
107      * M = InvScale * Transform * Scale
108      *
109      * So we can later transform points using M * p
110      *
111      * Where:
112      *  Scale scales coordinates into 0..1 range
113      *  Transform is the user supplied (affine) transform
114      *  InvScale scales coordinates back up into their native range
115      */
116     sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
117     sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
119     /* invscale */
120     pixman_f_transform_init_scale(&scale, sx, sy);
121     scale.m[0][2] = dev->valuator->axes[0].min_value;
122     scale.m[1][2] = dev->valuator->axes[1].min_value;
124     /* transform */
125     for (y=0; y<3; y++)
126         for (x=0; x<3; x++)
127             dev->transform.m[y][x] = *transform++;
129     pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
131     /* scale */
132     pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
133     scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
134     scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
136     pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
139 /**
140  * DIX property handler.
141  */
142 static int
143 DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
144                   BOOL checkonly)
146     if (property == XIGetKnownProperty(XI_PROP_ENABLED))
147     {
148         if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
149             return BadValue;
151         /* Don't allow disabling of VCP/VCK */
152         if ((dev == inputInfo.pointer || dev == inputInfo.keyboard) &&
153             !(*(CARD8*)prop->data))
154             return BadAccess;
156         if (!checkonly)
157         {
158             if ((*((CARD8*)prop->data)) && !dev->enabled)
159                 EnableDevice(dev, TRUE);
160             else if (!(*((CARD8*)prop->data)) && dev->enabled)
161                 DisableDevice(dev, TRUE);
162         }
163     } else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM))
164     {
165         float *f = (float*)prop->data;
166         int i;
168         if (prop->format != 32 || prop->size != 9 ||
169             prop->type != XIGetKnownProperty(XATOM_FLOAT))
170             return BadValue;
172         for (i=0; i<9; i++)
173             if (!isfinite(f[i]))
174                 return BadValue;
176         if (!checkonly)
177             DeviceSetTransform(dev, f);
178     }
180     return Success;
183 /* Pair the keyboard to the pointer device. Keyboard events will follow the
184  * pointer sprite. Only applicable for master devices.
185  * If the client is set, the request to pair comes from some client. In this
186  * case, we need to check for access. If the client is NULL, it's from an
187  * internal automatic pairing, we must always permit this.
188  */
189 static int
190 PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd)
192     if (!ptr)
193         return BadDevice;
195     /* Don't allow pairing for slave devices */
196     if (!IsMaster(ptr) || !IsMaster(kbd))
197         return BadDevice;
199     if (ptr->spriteInfo->paired)
200         return BadDevice;
202     if (kbd->spriteInfo->spriteOwner)
203     {
204         free(kbd->spriteInfo->sprite);
205         kbd->spriteInfo->sprite = NULL;
206         kbd->spriteInfo->spriteOwner = FALSE;
207     }
209     kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
210     kbd->spriteInfo->paired = ptr;
211     ptr->spriteInfo->paired = kbd;
212     return Success;
216 /**
217  * Find and return the next unpaired MD pointer device.
218  */
219 static DeviceIntPtr
220 NextFreePointerDevice(void)
222     DeviceIntPtr dev;
223     for (dev = inputInfo.devices; dev; dev = dev->next)
224         if (IsMaster(dev) &&
225                 dev->spriteInfo->spriteOwner &&
226                 !dev->spriteInfo->paired)
227             return dev;
228     return NULL;
231 /**
232  * Create a new input device and init it to sane values. The device is added
233  * to the server's off_devices list.
234  *
235  * @param deviceProc Callback for device control function (switch dev on/off).
236  * @return The newly created device.
237  */
238 DeviceIntPtr
239 AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
241     DeviceIntPtr dev, *prev; /* not a typo */
242     DeviceIntPtr devtmp;
243     int devid;
244     char devind[MAXDEVICES];
245     BOOL enabled;
246     float transform[9];
248     /* Find next available id, 0 and 1 are reserved */
249     memset(devind, 0, sizeof(char)*MAXDEVICES);
250     for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
251         devind[devtmp->id]++;
252     for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
253         devind[devtmp->id]++;
254     for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++)
255         ;
257     if (devid >= MAXDEVICES)
258         return (DeviceIntPtr)NULL;
259     dev =  _dixAllocateObjectWithPrivates(sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
260                                           sizeof(DeviceIntRec) + sizeof(SpriteInfoRec),
261                                           offsetof(DeviceIntRec, devPrivates), PRIVATE_DEVICE);
262     if (!dev)
263         return (DeviceIntPtr)NULL;
265     dev->last.scroll = NULL;
266     dev->last.touches = NULL;
267     dev->id = devid;
268     dev->public.processInputProc = ProcessOtherEvent;
269     dev->public.realInputProc = ProcessOtherEvent;
270     dev->public.enqueueInputProc = EnqueueEvent;
271     dev->deviceProc = deviceProc;
272     dev->startup = autoStart;
274     /* device grab defaults */
275     dev->deviceGrab.grabTime = currentTime;
276     dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
277     dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
278     dev->deviceGrab.activeGrab = AllocGrab();
279     dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
281     XkbSetExtension(dev, ProcessKeyboardEvent);
283     dev->coreEvents = TRUE;
285     /* sprite defaults */
286     dev->spriteInfo = (SpriteInfoPtr)&dev[1];
288     /*  security creation/labeling check
289      */
290     if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
291         free(dev);
292         return NULL;
293     }
295     inputInfo.numDevices++;
297     for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
298         ;
299     *prev = dev;
300     dev->next = NULL;
302     enabled = FALSE;
303     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
304                            XA_INTEGER, 8, PropModeReplace, 1, &enabled,
305                            FALSE);
306     XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED), FALSE);
308     /* unity matrix */
309     memset(transform, 0, sizeof(transform));
310     transform[0] = transform[4] = transform[8] = 1.0f;
312     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
313                            XIGetKnownProperty(XATOM_FLOAT), 32,
314                            PropModeReplace, 9, transform, FALSE);
315     XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
316                                  FALSE);
318     XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
320     return dev;
323 void
324 SendDevicePresenceEvent(int deviceid, int type)
326     DeviceIntRec dummyDev;
327     devicePresenceNotify ev;
329     memset(&dummyDev, 0, sizeof(DeviceIntRec));
330     ev.type = DevicePresenceNotify;
331     ev.time = currentTime.milliseconds;
332     ev.devchange = type;
333     ev.deviceid = deviceid;
334     dummyDev.id = XIAllDevices;
335     SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
336                           (xEvent*)&ev, 1);
339 /**
340  * Enable the device through the driver, add the device to the device list.
341  * Switch device ON through the driver and push it onto the global device
342  * list. Initialize the DIX sprite or pair the device. All clients are
343  * notified about the device being enabled.
344  *
345  * A master pointer device needs to be enabled before a master keyboard
346  * device.
347  *
348  * @param The device to be enabled.
349  * @param sendevent True if an XI2 event should be sent.
350  * @return TRUE on success or FALSE otherwise.
351  */
352 Bool
353 EnableDevice(DeviceIntPtr dev, BOOL sendevent)
355     DeviceIntPtr *prev;
356     int ret;
357     DeviceIntPtr other;
358     BOOL enabled;
359     int flags[MAXDEVICES] = {0};
361     for (prev = &inputInfo.off_devices;
362          *prev && (*prev != dev);
363          prev = &(*prev)->next)
364         ;
366     if (!dev->spriteInfo->sprite)
367     {
368         if (IsMaster(dev))
369         {
370             /* Sprites appear on first root window, so we can hardcode it */
371             if (dev->spriteInfo->spriteOwner)
372             {
373                 InitializeSprite(dev, screenInfo.screens[0]->root);
374                                                  /* mode doesn't matter */
375                 EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
376             }
377             else if ((other = NextFreePointerDevice()) == NULL)
378             {
379                 ErrorF("[dix] cannot find pointer to pair with. "
380                        "This is a bug.\n");
381                 return FALSE;
382             } else
383                 PairDevices(NULL, other, dev);
384         } else
385         {
386             if (dev->coreEvents)
387                 other = (IsPointerDevice(dev)) ? inputInfo.pointer :
388                     inputInfo.keyboard;
389             else
390                 other = NULL; /* auto-float non-core devices */
391             AttachDevice(NULL, dev, other);
392         }
393     }
395     if ((*prev != dev) || !dev->inited ||
396         ((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
397         ErrorF("[dix] couldn't enable device %d\n", dev->id);
398         return FALSE;
399     }
400     dev->enabled = TRUE;
401     *prev = dev->next;
403     for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
404         ;
405     *prev = dev;
406     dev->next = NULL;
408     enabled = TRUE;
409     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
410                            XA_INTEGER, 8, PropModeReplace, 1, &enabled,
411                            TRUE);
413     SendDevicePresenceEvent(dev->id, DeviceEnabled);
414     if (sendevent)
415     {
416         flags[dev->id] |= XIDeviceEnabled;
417         XISendDeviceHierarchyEvent(flags);
418     }
420     RecalculateMasterButtons(dev);
422     return TRUE;
425 /**
426  * Switch a device off through the driver and push it onto the off_devices
427  * list. A device will not send events while disabled. All clients are
428  * notified about the device being disabled.
429  *
430  * Master keyboard devices have to be disabled before master pointer devices
431  * otherwise things turn bad.
432  *
433  * @param sendevent True if an XI2 event should be sent.
434  * @return TRUE on success or FALSE otherwise.
435  */
436 Bool
437 DisableDevice(DeviceIntPtr dev, BOOL sendevent)
439     DeviceIntPtr *prev, other;
440     BOOL enabled;
441     int flags[MAXDEVICES] = {0};
443     for (prev = &inputInfo.devices;
444          *prev && (*prev != dev);
445          prev = &(*prev)->next)
446         ;
447     if (*prev != dev)
448         return FALSE;
450     /* float attached devices */
451     if (IsMaster(dev))
452     {
453         for (other = inputInfo.devices; other; other = other->next)
454         {
455             if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev)
456             {
457                 AttachDevice(NULL, other, NULL);
458                 flags[other->id] |= XISlaveDetached;
459             }
460         }
461     }
462     else
463     {
464         for (other = inputInfo.devices; other; other = other->next)
465         {
466             if (IsMaster(other) && other->lastSlave == dev)
467                 other->lastSlave = NULL;
468         }
469     }
471     if (IsMaster(dev) && dev->spriteInfo->sprite)
472     {
473         for (other = inputInfo.devices; other; other = other->next)
474         {
475             if (other->spriteInfo->paired == dev)
476             {
477                 ErrorF("[dix] cannot disable device, still paired. "
478                         "This is a bug. \n");
479                 return FALSE;
480             }
481         }
482     }
484     (void)(*dev->deviceProc)(dev, DEVICE_OFF);
485     dev->enabled = FALSE;
487     /* now that the device is disabled, we can reset the signal handler's
488      * last.slave */
489     OsBlockSignals();
490     for (other = inputInfo.devices; other; other = other->next)
491     {
492         if (other->last.slave == dev)
493             other->last.slave = NULL;
494     }
495     OsReleaseSignals();
497     LeaveWindow(dev);
498     SetFocusOut(dev);
500     *prev = dev->next;
501     dev->next = inputInfo.off_devices;
502     inputInfo.off_devices = dev;
504     enabled = FALSE;
505     XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
506                            XA_INTEGER, 8, PropModeReplace, 1, &enabled,
507                            TRUE);
509     SendDevicePresenceEvent(dev->id, DeviceDisabled);
510     if (sendevent)
511     {
512         flags[dev->id] = XIDeviceDisabled;
513         XISendDeviceHierarchyEvent(flags);
514     }
516     RecalculateMasterButtons(dev);
518     return TRUE;
521 /**
522  * Initialise a new device through the driver and tell all clients about the
523  * new device.
524  *
525  * Must be called before EnableDevice.
526  * The device will NOT send events until it is enabled!
527  *
528  * @param sendevent True if an XI2 event should be sent.
529  * @return Success or an error code on failure.
530  */
531 int
532 ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
534     int ret = Success;
535     ScreenPtr pScreen = screenInfo.screens[0];
537     if (!dev || !dev->deviceProc)
538         return BadImplementation;
540     ret = (*dev->deviceProc) (dev, DEVICE_INIT);
541     dev->inited = (ret == Success);
542     if (!dev->inited)
543         return ret;
545     /* Initialize memory for sprites. */
546     if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
547         if (!pScreen->DeviceCursorInitialize(dev, pScreen))
548             ret = BadAlloc;
550     SendDevicePresenceEvent(dev->id, DeviceAdded);
551     if (sendevent)
552     {
553         int flags[MAXDEVICES] = {0};
554         flags[dev->id] = XISlaveAdded;
555         XISendDeviceHierarchyEvent(flags);
556     }
557     return ret;
560 /**
561  * Ring the bell.
562  * The actual task of ringing the bell is the job of the DDX.
563  */
564 static void
565 CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
567     KeybdCtrl *ctrl = arg;
569     DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
572 static void
573 CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
575     return;
578 /**
579  * Device control function for the Virtual Core Keyboard.
580  */
581 int
582 CoreKeyboardProc(DeviceIntPtr pDev, int what)
585     switch (what) {
586     case DEVICE_INIT:
587         if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
588                                       CoreKeyboardCtl))
589         {
590             ErrorF("Keyboard initialization failed. This could be a missing "
591                    "or incorrect setup of xkeyboard-config.\n");
592             return BadValue;
593         }
594         return Success;
596     case DEVICE_ON:
597     case DEVICE_OFF:
598         return Success;
600     case DEVICE_CLOSE:
601         return Success;
602     }
604     return BadMatch;
607 /**
608  * Device control function for the Virtual Core Pointer.
609  */
610 int
611 CorePointerProc(DeviceIntPtr pDev, int what)
613 #define NBUTTONS 10
614 #define NAXES 2
615     BYTE map[NBUTTONS + 1];
616     int i = 0;
617     Atom btn_labels[NBUTTONS] = {0};
618     Atom axes_labels[NAXES] = {0};
619     ScreenPtr scr = screenInfo.screens[0];
621     switch (what) {
622     case DEVICE_INIT:
623         for (i = 1; i <= NBUTTONS; i++)
624             map[i] = i;
626         btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
627         btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
628         btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
629         btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
630         btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
631         btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
632         btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
633         /* don't know about the rest */
635         axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
636         axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
638         if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels,
639                                 (PtrCtrlProcPtr)NoopDDA,
640                                 GetMotionHistorySize(), NAXES, axes_labels))
641         {
642             ErrorF("Could not initialize device '%s'. Out of memory.\n",
643                    pDev->name);
644             return BadAlloc; /* IPDS only fails on allocs */
645         }
646         /* axisVal is per-screen, last.valuators is desktop-wide */
647         pDev->valuator->axisVal[0] = scr->width / 2;
648         pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x;
649         pDev->valuator->axisVal[1] = scr->height / 2;
650         pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y;
651         break;
653     case DEVICE_CLOSE:
654         break;
656     default:
657         break;
658     }
660     return Success;
662 #undef NBUTTONS
663 #undef NAXES
666 /**
667  * Initialise the two core devices, VCP and VCK (see events.c).
668  * Both devices are not tied to physical devices, but guarantee that there is
669  * always a keyboard and a pointer present and keep the protocol semantics.
670  *
671  * Note that the server MUST have two core devices at all times, even if there
672  * is no physical device connected.
673  */
674 void
675 InitCoreDevices(void)
677     if (AllocDevicePair(serverClient, "Virtual core",
678                         &inputInfo.pointer, &inputInfo.keyboard,
679                         CorePointerProc, CoreKeyboardProc,
680                         TRUE) != Success)
681         FatalError("Failed to allocate core devices");
683     if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
684         ActivateDevice(inputInfo.keyboard, TRUE) != Success)
685         FatalError("Failed to activate core devices.");
686     if (!EnableDevice(inputInfo.pointer, TRUE) ||
687         !EnableDevice(inputInfo.keyboard, TRUE))
688         FatalError("Failed to enable core devices.");
690     InitXTestDevices();
693 /**
694  * Activate all switched-off devices and then enable all those devices.
695  *
696  * Will return an error if no core keyboard or core pointer is present.
697  * In theory this should never happen if you call InitCoreDevices() first.
698  *
699  * InitAndStartDevices needs to be called AFTER the windows are initialized.
700  * Devices will start sending events after InitAndStartDevices() has
701  * completed.
702  *
703  * @return Success or error code on failure.
704  */
705 int
706 InitAndStartDevices(void)
708     DeviceIntPtr dev, next;
710     for (dev = inputInfo.off_devices; dev; dev = dev->next) {
711         DebugF("(dix) initialising device %d\n", dev->id);
712         if (!dev->inited)
713             ActivateDevice(dev, TRUE);
714     }
716     /* enable real devices */
717     for (dev = inputInfo.off_devices; dev; dev = next)
718     {
719         DebugF("(dix) enabling device %d\n", dev->id);
720         next = dev->next;
721         if (dev->inited && dev->startup)
722             EnableDevice(dev, TRUE);
723     }
725     return Success;
728 /**
729  * Free the given device class and reset the pointer to NULL.
730  */
731 static void
732 FreeDeviceClass(int type, pointer *class)
734     if (!(*class))
735         return;
737     switch(type)
738     {
739         case KeyClass:
740             {
741                 KeyClassPtr* k = (KeyClassPtr*)class;
742                 if ((*k)->xkbInfo)
743                 {
744                     XkbFreeInfo((*k)->xkbInfo);
745                     (*k)->xkbInfo = NULL;
746                 }
747                 free((*k));
748                 break;
749             }
750         case ButtonClass:
751             {
752                 ButtonClassPtr *b = (ButtonClassPtr*)class;
753                 free((*b)->xkb_acts);
754                 free((*b));
755                 break;
756             }
757         case ValuatorClass:
758             {
759                 ValuatorClassPtr *v = (ValuatorClassPtr*)class;
761                 free((*v)->motion);
762                 free((*v));
763                 break;
764             }
765         case XITouchClass:
766             {
767                 TouchClassPtr *t = (TouchClassPtr*)class;
768                 int i;
770                 for (i = 0; i < (*t)->num_touches; i++)
771                 {
772                     free((*t)->touches[i].sprite.spriteTrace);
773                     free((*t)->touches[i].listeners);
774                     free((*t)->touches[i].valuators);
775                 }
777                 free((*t));
778                 break;
779             }
780         case FocusClass:
781             {
782                 FocusClassPtr *f = (FocusClassPtr*)class;
783                 free((*f)->trace);
784                 free((*f));
785                 break;
786             }
787         case ProximityClass:
788             {
789                 ProximityClassPtr *p = (ProximityClassPtr*)class;
790                 free((*p));
791                 break;
792             }
793     }
794     *class = NULL;
797 static void
798 FreeFeedbackClass(int type, pointer *class)
800     if (!(*class))
801         return;
803     switch(type)
804     {
805         case KbdFeedbackClass:
806             {
807                 KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr*)class;
808                 KbdFeedbackPtr k, knext;
809                 for (k = (*kbdfeed); k; k = knext) {
810                     knext = k->next;
811                     if (k->xkb_sli)
812                         XkbFreeSrvLedInfo(k->xkb_sli);
813                     free(k);
814                 }
815                 break;
816             }
817         case PtrFeedbackClass:
818             {
819                 PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr*)class;
820                 PtrFeedbackPtr p, pnext;
822                 for (p = (*ptrfeed); p; p = pnext) {
823                     pnext = p->next;
824                     free(p);
825                 }
826                 break;
827             }
828         case IntegerFeedbackClass:
829             {
830                 IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr*)class;
831                 IntegerFeedbackPtr i, inext;
833                 for (i = (*intfeed); i; i = inext) {
834                     inext = i->next;
835                     free(i);
836                 }
837                 break;
838             }
839         case StringFeedbackClass:
840             {
841                 StringFeedbackPtr *stringfeed = (StringFeedbackPtr*)class;
842                 StringFeedbackPtr s, snext;
844                 for (s = (*stringfeed); s; s = snext) {
845                     snext = s->next;
846                     free(s->ctrl.symbols_supported);
847                     free(s->ctrl.symbols_displayed);
848                     free(s);
849                 }
850                 break;
851             }
852         case BellFeedbackClass:
853             {
854                 BellFeedbackPtr *bell = (BellFeedbackPtr*)class;
855                 BellFeedbackPtr b, bnext;
857                 for (b = (*bell); b; b = bnext) {
858                     bnext = b->next;
859                     free(b);
860                 }
861                 break;
862             }
863         case LedFeedbackClass:
864             {
865                 LedFeedbackPtr *leds = (LedFeedbackPtr*)class;
866                 LedFeedbackPtr l, lnext;
868                 for (l = (*leds); l; l = lnext) {
869                     lnext = l->next;
870                     if (l->xkb_sli)
871                         XkbFreeSrvLedInfo(l->xkb_sli);
872                     free(l);
873                 }
874                 break;
875             }
876     }
877     *class = NULL;
880 static void
881 FreeAllDeviceClasses(ClassesPtr classes)
883     if (!classes)
884         return;
886     FreeDeviceClass(KeyClass, (pointer)&classes->key);
887     FreeDeviceClass(ValuatorClass, (pointer)&classes->valuator);
888     FreeDeviceClass(XITouchClass, (pointer)&classes->touch);
889     FreeDeviceClass(ButtonClass, (pointer)&classes->button);
890     FreeDeviceClass(FocusClass, (pointer)&classes->focus);
891     FreeDeviceClass(ProximityClass, (pointer)&classes->proximity);
893     FreeFeedbackClass(KbdFeedbackClass, (pointer)&classes->kbdfeed);
894     FreeFeedbackClass(PtrFeedbackClass, (pointer)&classes->ptrfeed);
895     FreeFeedbackClass(IntegerFeedbackClass, (pointer)&classes->intfeed);
896     FreeFeedbackClass(StringFeedbackClass, (pointer)&classes->stringfeed);
897     FreeFeedbackClass(BellFeedbackClass, (pointer)&classes->bell);
898     FreeFeedbackClass(LedFeedbackClass, (pointer)&classes->leds);
902 /**
903  * Close down a device and free all resources.
904  * Once closed down, the driver will probably not expect you that you'll ever
905  * enable it again and free associated structs. If you want the device to just
906  * be disabled, DisableDevice().
907  * Don't call this function directly, use RemoveDevice() instead.
908  */
909 static void
910 CloseDevice(DeviceIntPtr dev)
912     ScreenPtr screen = screenInfo.screens[0];
913     ClassesPtr classes;
914     int j;
916     if (!dev)
917         return;
919     XIDeleteAllDeviceProperties(dev);
921     if (dev->inited)
922         (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
924     /* free sprite memory */
925     if (IsMaster(dev) && dev->spriteInfo->sprite)
926         screen->DeviceCursorCleanup(dev, screen);
928     /* free acceleration info */
929     if(dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
930         dev->valuator->accelScheme.AccelCleanupProc(dev);
932     while (dev->xkb_interest)
933         XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
935     free(dev->name);
937     classes = (ClassesPtr)&dev->key;
938     FreeAllDeviceClasses(classes);
940     if (IsMaster(dev))
941     {
942         classes = dev->unused_classes;
943         FreeAllDeviceClasses(classes);
944         free(classes);
945     }
947     if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
948         if (dev->spriteInfo->sprite->current)
949             FreeCursor(dev->spriteInfo->sprite->current, None);
950         free(dev->spriteInfo->sprite->spriteTrace);
951         free(dev->spriteInfo->sprite);
952     }
954     /* a client may have the device set as client pointer */
955     for (j = 0; j < currentMaxClients; j++)
956     {
957         if (clients[j] && clients[j]->clientPtr == dev)
958         {
959             clients[j]->clientPtr = NULL;
960             clients[j]->clientPtr = PickPointer(clients[j]);
961         }
962     }
964     FreeGrab(dev->deviceGrab.activeGrab);
965     free(dev->deviceGrab.sync.event);
966     free(dev->config_info);     /* Allocated in xf86ActivateDevice. */
967     free(dev->last.scroll);
968     for (j = 0; j < dev->last.num_touches; j++)
969         free(dev->last.touches[j].valuators);
970     free(dev->last.touches);
971     dev->config_info = NULL;
972     dixFreeObjectWithPrivates(dev, PRIVATE_DEVICE);
975 /**
976  * Shut down all devices of one list and free all resources.
977  */
978 static
979 void
980 CloseDeviceList(DeviceIntPtr *listHead)
982     /* Used to mark devices that we tried to free */
983     Bool freedIds[MAXDEVICES];
984     DeviceIntPtr dev;
985     int i;
987     if (listHead == NULL)
988         return;
990     for (i = 0; i < MAXDEVICES; i++)
991         freedIds[i] = FALSE;
993     dev = *listHead;
994     while (dev != NULL)
995     {
996         freedIds[dev->id] = TRUE;
997         DeleteInputDeviceRequest(dev);
999         dev = *listHead;
1000         while (dev != NULL && freedIds[dev->id])
1001             dev = dev->next;
1002     }
1005 /**
1006  * Shut down all devices, free all resources, etc.
1007  * Only useful if you're shutting down the server!
1008  */
1009 void
1010 CloseDownDevices(void)
1012     DeviceIntPtr dev;
1014     OsBlockSignals();
1016     /* Float all SDs before closing them. Note that at this point resources
1017      * (e.g. cursors) have been freed already, so we can't just call
1018      * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
1019      * to NULL and pretend nothing happened.
1020      */
1021     for (dev = inputInfo.devices; dev; dev = dev->next)
1022     {
1023         if (!IsMaster(dev) && !IsFloating(dev))
1024             dev->master = NULL;
1025     }
1027     CloseDeviceList(&inputInfo.devices);
1028     CloseDeviceList(&inputInfo.off_devices);
1030     CloseDevice(inputInfo.pointer);
1031     CloseDevice(inputInfo.keyboard);
1033     inputInfo.devices = NULL;
1034     inputInfo.off_devices = NULL;
1035     inputInfo.keyboard = NULL;
1036     inputInfo.pointer = NULL;
1037     XkbDeleteRulesDflts();
1039     OsReleaseSignals();
1042 /**
1043  * Remove the cursor sprite for all devices. This needs to be done before any
1044  * resources are freed or any device is deleted.
1045  */
1046 void
1047 UndisplayDevices(void)
1049     DeviceIntPtr dev;
1050     ScreenPtr screen = screenInfo.screens[0];
1052     for (dev = inputInfo.devices; dev; dev = dev->next)
1053         screen->DisplayCursor(dev, screen, NullCursor);
1056 /**
1057  * Remove a device from the device list, closes it and thus frees all
1058  * resources.
1059  * Removes both enabled and disabled devices and notifies all devices about
1060  * the removal of the device.
1061  *
1062  * No PresenceNotify is sent for device that the client never saw. This can
1063  * happen if a malloc fails during the addition of master devices. If
1064  * dev->init is FALSE it means the client never received a DeviceAdded event,
1065  * so let's not send a DeviceRemoved event either.
1066  *
1067  * @param sendevent True if an XI2 event should be sent.
1068  */
1069 int
1070 RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
1072     DeviceIntPtr prev,tmp,next;
1073     int ret = BadMatch;
1074     ScreenPtr screen = screenInfo.screens[0];
1075     int deviceid;
1076     int initialized;
1077     int flags[MAXDEVICES] = {0};
1079     DebugF("(dix) removing device %d\n", dev->id);
1081     if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
1082         return BadImplementation;
1084     initialized = dev->inited;
1085     deviceid = dev->id;
1087     if (initialized)
1088     {
1089         if (DevHasCursor(dev))
1090             screen->DisplayCursor(dev, screen, NullCursor);
1092         DisableDevice(dev, sendevent);
1093         flags[dev->id] = XIDeviceDisabled;
1094     }
1096     prev = NULL;
1097     for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
1098         next = tmp->next;
1099         if (tmp == dev) {
1101             if (prev==NULL)
1102                 inputInfo.devices = next;
1103             else
1104                 prev->next = next;
1106             flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1107             CloseDevice(tmp);
1108             ret = Success;
1109         }
1110     }
1112     prev = NULL;
1113     for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
1114         next = tmp->next;
1115         if (tmp == dev) {
1116             flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1117             CloseDevice(tmp);
1119             if (prev == NULL)
1120                 inputInfo.off_devices = next;
1121             else
1122                 prev->next = next;
1124             ret = Success;
1125         }
1126     }
1128     if (ret == Success && initialized) {
1129         inputInfo.numDevices--;
1130         SendDevicePresenceEvent(deviceid, DeviceRemoved);
1131         if (sendevent)
1132             XISendDeviceHierarchyEvent(flags);
1133     }
1135     return ret;
1138 int
1139 NumMotionEvents(void)
1141     /* only called to fill data in initial connection reply.
1142      * VCP is ok here, it is the only fixed device we have. */
1143     return inputInfo.pointer->valuator->numMotionEvents;
1146 int
1147 dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
1149     DeviceIntPtr dev;
1150     int rc;
1151     *pDev = NULL;
1153     for (dev=inputInfo.devices; dev; dev=dev->next) {
1154         if (dev->id == id)
1155             goto found;
1156     }
1157     for (dev=inputInfo.off_devices; dev; dev=dev->next) {
1158         if (dev->id == id)
1159             goto found;
1160     }
1161     return BadDevice;
1163 found:
1164     rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
1165     if (rc == Success)
1166         *pDev = dev;
1167     return rc;
1170 void
1171 QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
1173     if (inputInfo.keyboard) {
1174         *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
1175         *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
1176     }
1179 /* Notably, this function does not expand the destination's keycode range, or
1180  * notify clients. */
1181 Bool
1182 SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
1184     int i, j;
1185     KeySym *tmp;
1186     int rowDif = src->minKeyCode - dst->minKeyCode;
1188     /* if keysym map size changes, grow map first */
1189     if (src->mapWidth < dst->mapWidth) {
1190         for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
1191 #define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
1192 #define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
1193             for (j = 0; j < src->mapWidth; j++)
1194                 dst->map[DI(i, j)] = src->map[SI(i, j)];
1195             for (j = src->mapWidth; j < dst->mapWidth; j++)
1196                 dst->map[DI(i, j)] = NoSymbol;
1197 #undef SI
1198 #undef DI
1199         }
1200         return TRUE;
1201     }
1202     else if (src->mapWidth > dst->mapWidth) {
1203         i = sizeof(KeySym) * src->mapWidth *
1204              (dst->maxKeyCode - dst->minKeyCode + 1);
1205         tmp = calloc(sizeof(KeySym), i);
1206         if (!tmp)
1207             return FALSE;
1209         if (dst->map) {
1210             for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
1211                 memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
1212                         dst->mapWidth * sizeof(KeySym));
1213             free(dst->map);
1214         }
1215         dst->mapWidth = src->mapWidth;
1216         dst->map = tmp;
1217     }
1218     else if (!dst->map) {
1219         i = sizeof(KeySym) * src->mapWidth *
1220              (dst->maxKeyCode - dst->minKeyCode + 1);
1221         tmp = calloc(sizeof(KeySym), i);
1222         if (!tmp)
1223             return FALSE;
1225         dst->map = tmp;
1226         dst->mapWidth = src->mapWidth;
1227     }
1229     memmove(&dst->map[rowDif * dst->mapWidth], src->map,
1230             (src->maxKeyCode - src->minKeyCode + 1) *
1231             dst->mapWidth * sizeof(KeySym));
1233     return TRUE;
1236 Bool
1237 InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels,
1238                             CARD8 *map)
1240     ButtonClassPtr butc;
1241     int i;
1243     butc = calloc(1, sizeof(ButtonClassRec));
1244     if (!butc)
1245         return FALSE;
1246     butc->numButtons = numButtons;
1247     butc->sourceid = dev->id;
1248     for (i = 1; i <= numButtons; i++)
1249         butc->map[i] = map[i];
1250     for (i = numButtons + 1; i < MAP_LENGTH; i++)
1251         butc->map[i] = i;
1252     memcpy(butc->labels, labels, numButtons * sizeof(Atom));
1253     dev->button = butc;
1254     return TRUE;
1257 /**
1258  * Allocate a valuator class and set up the pointers for the axis values
1259  * appropriately.
1260  *
1261  * @param src If non-NULL, the memory is reallocated from src. If NULL, the
1262  * memory is calloc'd.
1263  * @parma numAxes Number of axes to allocate.
1264  * @return The allocated valuator struct.
1265  */
1266 ValuatorClassPtr
1267 AllocValuatorClass(ValuatorClassPtr src, int numAxes)
1269     ValuatorClassPtr v;
1270     /* force alignment with double */
1271     union align_u { ValuatorClassRec valc; double d; } *align;
1272     int size;
1274     size = sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo));
1275     align = (union align_u *) realloc(src, size);
1277     if (!align)
1278         return NULL;
1280     if (!src)
1281         memset(align, 0, size);
1283     v = &align->valc;
1284     v->numAxes = numAxes;
1285     v->axisVal = (double*)(align + 1);
1286     v->axes = (AxisInfoPtr)(v->axisVal + numAxes);
1288     return v;
1291 Bool
1292 InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
1293                               int numMotionEvents, int mode)
1295     int i;
1296     ValuatorClassPtr valc;
1298     if (!dev)
1299         return FALSE;
1301     if (numAxes > MAX_VALUATORS)
1302     {
1303         LogMessage(X_WARNING,
1304                    "Device '%s' has %d axes, only using first %d.\n",
1305                    dev->name, numAxes, MAX_VALUATORS);
1306         numAxes = MAX_VALUATORS;
1307     }
1309     valc = AllocValuatorClass(NULL, numAxes);
1310     if (!valc)
1311         return FALSE;
1313     dev->last.scroll = valuator_mask_new(numAxes);
1314     if (!dev->last.scroll)
1315     {
1316         free(valc);
1317         return FALSE;
1318     }
1320     valc->sourceid = dev->id;
1321     valc->motion = NULL;
1322     valc->first_motion = 0;
1323     valc->last_motion = 0;
1324     valc->h_scroll_axis = -1;
1325     valc->v_scroll_axis = -1;
1327     valc->numMotionEvents = numMotionEvents;
1328     valc->motionHintWindow = NullWindow;
1330     if (mode & OutOfProximity)
1331         InitProximityClassDeviceStruct(dev);
1333     dev->valuator = valc;
1335     AllocateMotionHistory(dev);
1337     for (i=0; i<numAxes; i++) {
1338         InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS,
1339                                0, 0, 0, mode);
1340         valc->axisVal[i]=0;
1341     }
1343     dev->last.numValuators = numAxes;
1345     if (IsMaster(dev) || /* do not accelerate master or xtest devices */
1346         IsXTestDevice(dev, NULL))
1347         InitPointerAccelerationScheme(dev, PtrAccelNoOp);
1348     else
1349         InitPointerAccelerationScheme(dev, PtrAccelDefault);
1350     return TRUE;
1353 /* global list of acceleration schemes */
1354 ValuatorAccelerationRec pointerAccelerationScheme[] = {
1355     {PtrAccelNoOp, NULL, NULL, NULL, NULL},
1356     {PtrAccelPredictable, acceleratePointerPredictable, NULL,
1357         InitPredictableAccelerationScheme, AccelerationDefaultCleanup},
1358     {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL},
1359     {-1, NULL, NULL, NULL, NULL} /* terminator */
1360 };
1362 /**
1363  * install an acceleration scheme. returns TRUE on success, and should not
1364  * change anything if unsuccessful.
1365  */
1366 Bool
1367 InitPointerAccelerationScheme(DeviceIntPtr dev,
1368                               int scheme)
1370     int x, i = -1;
1371     ValuatorClassPtr val;
1373     val = dev->valuator;
1375     if (!val)
1376         return FALSE;
1378     if (IsMaster(dev) && scheme != PtrAccelNoOp)
1379         return FALSE;
1381     for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
1382         if(pointerAccelerationScheme[x].number == scheme){
1383             i = x;
1384             break;
1385         }
1386     }
1388     if (-1 == i)
1389         return FALSE;
1391     if (val->accelScheme.AccelCleanupProc)
1392         val->accelScheme.AccelCleanupProc(dev);
1394     if (pointerAccelerationScheme[i].AccelInitProc) {
1395         if (!pointerAccelerationScheme[i].AccelInitProc(dev,
1396                                             &pointerAccelerationScheme[i])) {
1397             return FALSE;
1398         }
1399     } else {
1400         val->accelScheme = pointerAccelerationScheme[i];
1401     }
1402     return TRUE;
1405 Bool
1406 InitFocusClassDeviceStruct(DeviceIntPtr dev)
1408     FocusClassPtr focc;
1410     focc = malloc(sizeof(FocusClassRec));
1411     if (!focc)
1412         return FALSE;
1413     focc->win = PointerRootWin;
1414     focc->revert = None;
1415     focc->time = currentTime;
1416     focc->trace = (WindowPtr *)NULL;
1417     focc->traceSize = 0;
1418     focc->traceGood = 0;
1419     focc->sourceid = dev->id;
1420     dev->focus = focc;
1421     return TRUE;
1424 Bool
1425 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
1427     PtrFeedbackPtr feedc;
1429     feedc = malloc(sizeof(PtrFeedbackClassRec));
1430     if (!feedc)
1431         return FALSE;
1432     feedc->CtrlProc = controlProc;
1433     feedc->ctrl = defaultPointerControl;
1434     feedc->ctrl.id = 0;
1435     if ( (feedc->next = dev->ptrfeed) )
1436         feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
1437     dev->ptrfeed = feedc;
1438     (*controlProc)(dev, &feedc->ctrl);
1439     return TRUE;
1442 static LedCtrl defaultLedControl = {
1443         DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
1445 static BellCtrl defaultBellControl = {
1446         DEFAULT_BELL,
1447         DEFAULT_BELL_PITCH,
1448         DEFAULT_BELL_DURATION,
1449         0};
1451 static IntegerCtrl defaultIntegerControl = {
1452         DEFAULT_INT_RESOLUTION,
1453         DEFAULT_INT_MIN_VALUE,
1454         DEFAULT_INT_MAX_VALUE,
1455         DEFAULT_INT_DISPLAYED,
1456         0};
1458 Bool
1459 InitStringFeedbackClassDeviceStruct (
1460       DeviceIntPtr dev, StringCtrlProcPtr controlProc,
1461       int max_symbols, int num_symbols_supported, KeySym *symbols)
1463     int i;
1464     StringFeedbackPtr feedc;
1466     feedc = malloc(sizeof(StringFeedbackClassRec));
1467     if (!feedc)
1468         return FALSE;
1469     feedc->CtrlProc = controlProc;
1470     feedc->ctrl.num_symbols_supported = num_symbols_supported;
1471     feedc->ctrl.num_symbols_displayed = 0;
1472     feedc->ctrl.max_symbols = max_symbols;
1473     feedc->ctrl.symbols_supported = malloc(sizeof (KeySym) * num_symbols_supported);
1474     feedc->ctrl.symbols_displayed = malloc(sizeof (KeySym) * max_symbols);
1475     if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
1476     {
1477         free(feedc->ctrl.symbols_supported);
1478         free(feedc->ctrl.symbols_displayed);
1479         free(feedc);
1480         return FALSE;
1481     }
1482     for (i=0; i<num_symbols_supported; i++)
1483         *(feedc->ctrl.symbols_supported+i) = *symbols++;
1484     for (i=0; i<max_symbols; i++)
1485         *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0;
1486     feedc->ctrl.id = 0;
1487     if ( (feedc->next = dev->stringfeed) )
1488         feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
1489     dev->stringfeed = feedc;
1490     (*controlProc)(dev, &feedc->ctrl);
1491     return TRUE;
1494 Bool
1495 InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
1496                                    BellCtrlProcPtr controlProc)
1498     BellFeedbackPtr feedc;
1500     feedc = malloc(sizeof(BellFeedbackClassRec));
1501     if (!feedc)
1502         return FALSE;
1503     feedc->CtrlProc = controlProc;
1504     feedc->BellProc = bellProc;
1505     feedc->ctrl = defaultBellControl;
1506     feedc->ctrl.id = 0;
1507     if ( (feedc->next = dev->bell) )
1508         feedc->ctrl.id = dev->bell->ctrl.id + 1;
1509     dev->bell = feedc;
1510     (*controlProc)(dev, &feedc->ctrl);
1511     return TRUE;
1514 Bool
1515 InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
1517     LedFeedbackPtr feedc;
1519     feedc = malloc(sizeof(LedFeedbackClassRec));
1520     if (!feedc)
1521         return FALSE;
1522     feedc->CtrlProc = controlProc;
1523     feedc->ctrl = defaultLedControl;
1524     feedc->ctrl.id = 0;
1525     if ( (feedc->next = dev->leds) )
1526         feedc->ctrl.id = dev->leds->ctrl.id + 1;
1527     feedc->xkb_sli= NULL;
1528     dev->leds = feedc;
1529     (*controlProc)(dev, &feedc->ctrl);
1530     return TRUE;
1533 Bool
1534 InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
1536     IntegerFeedbackPtr feedc;
1538     feedc = malloc(sizeof(IntegerFeedbackClassRec));
1539     if (!feedc)
1540         return FALSE;
1541     feedc->CtrlProc = controlProc;
1542     feedc->ctrl = defaultIntegerControl;
1543     feedc->ctrl.id = 0;
1544     if ( (feedc->next = dev->intfeed) )
1545         feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
1546     dev->intfeed = feedc;
1547     (*controlProc)(dev, &feedc->ctrl);
1548     return TRUE;
1551 Bool
1552 InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels,
1553                         PtrCtrlProcPtr controlProc, int numMotionEvents,
1554                         int numAxes, Atom *axes_labels)
1556     DeviceIntPtr dev = (DeviceIntPtr)device;
1558     return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
1559            InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
1560                                          numMotionEvents, Relative) &&
1561            InitPtrFeedbackClassDeviceStruct(dev, controlProc));
1564 /**
1565  * Sets up multitouch capabilities on @device.
1566  *
1567  * @max_touches The maximum number of simultaneous touches, or 0 for unlimited.
1568  * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch).
1569  * @num_axes The number of touch valuator axes.
1570  */
1571 Bool
1572 InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
1573                            unsigned int mode, unsigned int num_axes)
1575     TouchClassPtr touch;
1576     int i;
1578     if (device->touch || !device->valuator)
1579         return FALSE;
1581     /* Check the mode is valid, and at least X and Y axes. */
1582     if (mode != XIDirectTouch && mode != XIDependentTouch)
1583         return FALSE;
1584     if (num_axes < 2)
1585         return FALSE;
1587     if (num_axes > MAX_VALUATORS)
1588     {
1589         LogMessage(X_WARNING,
1590                    "Device '%s' has %d touch axes, only using first %d.\n",
1591                    device->name, num_axes, MAX_VALUATORS);
1592         num_axes = MAX_VALUATORS;
1593     }
1595     touch = calloc(1, sizeof(*touch));
1596     if (!touch)
1597         return FALSE;
1599     touch->max_touches = max_touches;
1600     if (max_touches == 0)
1601         max_touches = 5; /* arbitrary number plucked out of the air */
1602     touch->touches = calloc(max_touches, sizeof(*touch->touches));
1603     if (!touch->touches)
1604         goto err;
1605     touch->num_touches = max_touches;
1606     for (i = 0; i < max_touches; i++)
1607         TouchInitTouchPoint(touch, device->valuator, i);
1609     touch->mode = mode;
1610     touch->sourceid = device->id;
1612     device->touch = touch;
1613     device->last.touches = calloc(max_touches, sizeof(*device->last.touches));
1614     device->last.num_touches = touch->num_touches;
1615     for (i = 0; i < touch->num_touches; i++)
1616         TouchInitDDXTouchPoint(device, &device->last.touches[i]);
1618     return TRUE;
1620 err:
1621     for (i = 0; i < touch->num_touches; i++)
1622         TouchFreeTouchPoint(device, i);
1624     free(touch->touches);
1625     free(touch);
1627     return FALSE;
1630 /*
1631  * Check if the given buffer contains elements between low (inclusive) and
1632  * high (inclusive) only.
1633  *
1634  * @return TRUE if the device map is invalid, FALSE otherwise.
1635  */
1636 Bool
1637 BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
1639     int i;
1641     for (i = 0; i < length; i++)
1642         if (buff[i])                   /* only check non-zero elements */
1643         {
1644             if ((low > buff[i]) || (high < buff[i]))
1645             {
1646                 *errval = buff[i];
1647                 return TRUE;
1648             }
1649         }
1650     return FALSE;
1653 int
1654 ProcSetModifierMapping(ClientPtr client)
1656     xSetModifierMappingReply rep;
1657     int rc;
1658     REQUEST(xSetModifierMappingReq);
1659     REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
1661     if (client->req_len != ((stuff->numKeyPerModifier << 1) +
1662                 bytes_to_int32(sizeof(xSetModifierMappingReq))))
1663         return BadLength;
1665     rep.type = X_Reply;
1666     rep.length = 0;
1667     rep.sequenceNumber = client->sequence;
1669     rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1],
1670                        stuff->numKeyPerModifier);
1671     if (rc == MappingFailed || rc == -1)
1672         return BadValue;
1673     if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
1674         rc != MappingBusy)
1675         return rc;
1677     rep.success = rc;
1679     WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
1680     return Success;
1683 int
1684 ProcGetModifierMapping(ClientPtr client)
1686     xGetModifierMappingReply rep;
1687     int max_keys_per_mod = 0;
1688     KeyCode *modkeymap = NULL;
1689     REQUEST_SIZE_MATCH(xReq);
1691     generate_modkeymap(client, PickKeyboard(client), &modkeymap,
1692                        &max_keys_per_mod);
1694     memset(&rep, 0, sizeof(xGetModifierMappingReply));
1695     rep.type = X_Reply;
1696     rep.numKeyPerModifier = max_keys_per_mod;
1697     rep.sequenceNumber = client->sequence;
1698     /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1699     rep.length = max_keys_per_mod << 1;
1701     WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
1702     (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap);
1704     free(modkeymap);
1706     return Success;
1709 int
1710 ProcChangeKeyboardMapping(ClientPtr client)
1712     REQUEST(xChangeKeyboardMappingReq);
1713     unsigned len;
1714     KeySymsRec keysyms;
1715     DeviceIntPtr pDev, tmp;
1716     int rc;
1717     REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
1719     len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
1720     if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
1721             return BadLength;
1723     pDev = PickKeyboard(client);
1725     if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
1726         (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
1727             client->errorValue = stuff->firstKeyCode;
1728             return BadValue;
1730     }
1731     if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
1732           pDev->key->xkbInfo->desc->max_key_code) ||
1733         (stuff->keySymsPerKeyCode == 0)) {
1734             client->errorValue = stuff->keySymsPerKeyCode;
1735             return BadValue;
1736     }
1738     keysyms.minKeyCode = stuff->firstKeyCode;
1739     keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
1740     keysyms.mapWidth = stuff->keySymsPerKeyCode;
1741     keysyms.map = (KeySym *) &stuff[1];
1743     rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1744     if (rc != Success)
1745         return rc;
1747     XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
1748                           stuff->keyCodes, NULL, client);
1750     for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
1751         if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev)
1752             continue;
1753         if (!tmp->key)
1754             continue;
1756         rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1757         if (rc != Success)
1758             continue;
1760         XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
1761                               stuff->keyCodes, NULL, client);
1762     }
1764     return Success;
1767 int
1768 ProcSetPointerMapping(ClientPtr client)
1770     BYTE *map;
1771     int ret;
1772     int i, j;
1773     DeviceIntPtr ptr = PickPointer(client);
1774     xSetPointerMappingReply rep;
1775     REQUEST(xSetPointerMappingReq);
1776     REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
1778     if (client->req_len !=
1779             bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
1780         return BadLength;
1781     rep.type = X_Reply;
1782     rep.length = 0;
1783     rep.sequenceNumber = client->sequence;
1784     rep.success = MappingSuccess;
1785     map = (BYTE *)&stuff[1];
1787     /* So we're bounded here by the number of core buttons.  This check
1788      * probably wants disabling through XFixes. */
1789     /* MPX: With ClientPointer, we can return the right number of buttons.
1790      * Let's just hope nobody changed ClientPointer between GetPointerMapping
1791      * and SetPointerMapping
1792      */
1793     if (stuff->nElts != ptr->button->numButtons) {
1794         client->errorValue = stuff->nElts;
1795         return BadValue;
1796     }
1798     /* Core protocol specs don't allow for duplicate mappings; this check
1799      * almost certainly wants disabling through XFixes too. */
1800     for (i = 0; i < stuff->nElts; i++) {
1801         for (j = i + 1; j < stuff->nElts; j++) {
1802             if (map[i] && map[i] == map[j]) {
1803                 client->errorValue = map[i];
1804                 return BadValue;
1805             }
1806         }
1807     }
1809     ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
1810     if (ret == MappingBusy)
1811         rep.success = ret;
1812     else if (ret == -1)
1813         return BadValue;
1814     else if (ret != Success)
1815         return ret;
1817     WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
1818     return Success;
1821 int
1822 ProcGetKeyboardMapping(ClientPtr client)
1824     xGetKeyboardMappingReply rep;
1825     DeviceIntPtr kbd = PickKeyboard(client);
1826     XkbDescPtr xkb;
1827     KeySymsPtr syms;
1828     int rc;
1829     REQUEST(xGetKeyboardMappingReq);
1830     REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
1832     rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
1833     if (rc != Success)
1834         return rc;
1836     xkb = kbd->key->xkbInfo->desc;
1838     if ((stuff->firstKeyCode < xkb->min_key_code) ||
1839         (stuff->firstKeyCode > xkb->max_key_code)) {
1840         client->errorValue = stuff->firstKeyCode;
1841         return BadValue;
1842     }
1843     if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
1844         client->errorValue = stuff->count;
1845         return BadValue;
1846     }
1848     syms = XkbGetCoreMap(kbd);
1849     if (!syms)
1850         return BadAlloc;
1852     memset(&rep, 0, sizeof(xGetKeyboardMappingReply));
1853     rep.type = X_Reply;
1854     rep.sequenceNumber = client->sequence;
1855     rep.keySymsPerKeyCode = syms->mapWidth;
1856     /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
1857     rep.length = syms->mapWidth * stuff->count;
1858     WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
1859     client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
1860     WriteSwappedDataToClient(client,
1861                              syms->mapWidth * stuff->count * sizeof(KeySym),
1862                              &syms->map[syms->mapWidth * (stuff->firstKeyCode -
1863                                                           syms->minKeyCode)]);
1864     free(syms->map);
1865     free(syms);
1867     return Success;
1870 int
1871 ProcGetPointerMapping(ClientPtr client)
1873     xGetPointerMappingReply rep;
1874     /* Apps may get different values each time they call GetPointerMapping as
1875      * the ClientPointer could change. */
1876     DeviceIntPtr ptr = PickPointer(client);
1877     ButtonClassPtr butc = ptr->button;
1878     int rc;
1879     REQUEST_SIZE_MATCH(xReq);
1881     rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
1882     if (rc != Success)
1883         return rc;
1885     rep.type = X_Reply;
1886     rep.sequenceNumber = client->sequence;
1887     rep.nElts = (butc) ? butc->numButtons : 0;
1888     rep.length = ((unsigned)rep.nElts + (4-1))/4;
1889     WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
1890     if (butc)
1891         WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
1892     return Success;
1895 void
1896 NoteLedState(DeviceIntPtr keybd, int led, Bool on)
1898     KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
1899     if (on)
1900         ctrl->leds |= ((Leds)1 << (led - 1));
1901     else
1902         ctrl->leds &= ~((Leds)1 << (led - 1));
1905 int
1906 Ones(unsigned long mask)             /* HACKMEM 169 */
1908     unsigned long y;
1910     y = (mask >> 1) &033333333333;
1911     y = mask - y - ((y >>1) & 033333333333);
1912     return (((y + (y >> 3)) & 030707070707) % 077);
1915 static int
1916 DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
1917                          BITS32 vmask)
1919 #define DO_ALL    (-1)
1920     KeybdCtrl ctrl;
1921     int t;
1922     int led = DO_ALL;
1923     int key = DO_ALL;
1924     BITS32 index2;
1925     int mask = vmask, i;
1926     XkbEventCauseRec cause;
1928     ctrl = keybd->kbdfeed->ctrl;
1929     while (vmask) {
1930         index2 = (BITS32) lowbit (vmask);
1931         vmask &= ~index2;
1932         switch (index2) {
1933         case KBKeyClickPercent:
1934             t = (INT8)*vlist;
1935             vlist++;
1936             if (t == -1) {
1937                 t = defaultKeyboardControl.click;
1938             }
1939             else if (t < 0 || t > 100) {
1940                 client->errorValue = t;
1941                 return BadValue;
1942             }
1943             ctrl.click = t;
1944             break;
1945         case KBBellPercent:
1946             t = (INT8)*vlist;
1947             vlist++;
1948             if (t == -1) {
1949                 t = defaultKeyboardControl.bell;
1950             }
1951             else if (t < 0 || t > 100) {
1952                 client->errorValue = t;
1953                 return BadValue;
1954             }
1955             ctrl.bell = t;
1956             break;
1957         case KBBellPitch:
1958             t = (INT16)*vlist;
1959             vlist++;
1960             if (t == -1) {
1961                 t = defaultKeyboardControl.bell_pitch;
1962             }
1963             else if (t < 0) {
1964                 client->errorValue = t;
1965                 return BadValue;
1966             }
1967             ctrl.bell_pitch = t;
1968             break;
1969         case KBBellDuration:
1970             t = (INT16)*vlist;
1971             vlist++;
1972             if (t == -1)
1973                 t = defaultKeyboardControl.bell_duration;
1974             else if (t < 0) {
1975                 client->errorValue = t;
1976                 return BadValue;
1977             }
1978             ctrl.bell_duration = t;
1979             break;
1980         case KBLed:
1981             led = (CARD8)*vlist;
1982             vlist++;
1983             if (led < 1 || led > 32) {
1984                 client->errorValue = led;
1985                 return BadValue;
1986             }
1987             if (!(mask & KBLedMode))
1988                 return BadMatch;
1989             break;
1990         case KBLedMode:
1991             t = (CARD8)*vlist;
1992             vlist++;
1993             if (t == LedModeOff) {
1994                 if (led == DO_ALL)
1995                     ctrl.leds = 0x0;
1996                 else
1997                     ctrl.leds &= ~(((Leds)(1)) << (led - 1));
1998             }
1999             else if (t == LedModeOn) {
2000                 if (led == DO_ALL)
2001                     ctrl.leds = ~0L;
2002                 else
2003                     ctrl.leds |= (((Leds)(1)) << (led - 1));
2004             }
2005             else {
2006                 client->errorValue = t;
2007                 return BadValue;
2008             }
2010             XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
2011             XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
2012                              ctrl.leds, &cause);
2013             ctrl.leds = keybd->kbdfeed->ctrl.leds;
2015             break;
2016         case KBKey:
2017             key = (KeyCode)*vlist;
2018             vlist++;
2019             if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code ||
2020                 (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) {
2021                 client->errorValue = key;
2022                 return BadValue;
2023             }
2024             if (!(mask & KBAutoRepeatMode))
2025                 return BadMatch;
2026             break;
2027         case KBAutoRepeatMode:
2028             i = (key >> 3);
2029             mask = (1 << (key & 7));
2030             t = (CARD8)*vlist;
2031             vlist++;
2032             if (key != DO_ALL)
2033                 XkbDisableComputedAutoRepeats(keybd,key);
2034             if (t == AutoRepeatModeOff) {
2035                 if (key == DO_ALL)
2036                     ctrl.autoRepeat = FALSE;
2037                 else
2038                     ctrl.autoRepeats[i] &= ~mask;
2039             }
2040             else if (t == AutoRepeatModeOn) {
2041                 if (key == DO_ALL)
2042                     ctrl.autoRepeat = TRUE;
2043                 else
2044                     ctrl.autoRepeats[i] |= mask;
2045             }
2046             else if (t == AutoRepeatModeDefault) {
2047                 if (key == DO_ALL)
2048                     ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
2049                 else
2050                     ctrl.autoRepeats[i] =
2051                             (ctrl.autoRepeats[i] & ~mask) |
2052                             (defaultKeyboardControl.autoRepeats[i] & mask);
2053             }
2054             else {
2055                 client->errorValue = t;
2056                 return BadValue;
2057             }
2058             break;
2059         default:
2060             client->errorValue = mask;
2061             return BadValue;
2062         }
2063     }
2064     keybd->kbdfeed->ctrl = ctrl;
2066     /* The XKB RepeatKeys control and core protocol global autorepeat */
2067     /* value are linked */
2068     XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
2070     return Success;
2072 #undef DO_ALL
2075 /**
2076  * Changes kbd control on the ClientPointer and all attached SDs.
2077  */
2078 int
2079 ProcChangeKeyboardControl (ClientPtr client)
2081     XID *vlist;
2082     BITS32 vmask;
2083     int ret = Success, error = Success;
2084     DeviceIntPtr pDev = NULL, keyboard;
2085     REQUEST(xChangeKeyboardControlReq);
2087     REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
2089     vmask = stuff->mask;
2090     vlist = (XID *)&stuff[1];
2092     if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
2093         return BadLength;
2095     keyboard = PickKeyboard(client);
2097     for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2098         if ((pDev == keyboard ||
2099              (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2100             && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2101             ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
2102             if (ret != Success)
2103                 return ret;
2104         }
2105     }
2107     for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2108         if ((pDev == keyboard ||
2109              (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2110             && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2111             ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
2112             if (ret != Success)
2113                 error = ret;
2114         }
2115     }
2117     return error;
2120 int
2121 ProcGetKeyboardControl (ClientPtr client)
2123     int rc, i;
2124     DeviceIntPtr kbd = PickKeyboard(client);
2125     KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
2126     xGetKeyboardControlReply rep;
2127     REQUEST_SIZE_MATCH(xReq);
2129     rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
2130     if (rc != Success)
2131         return rc;
2133     rep.type = X_Reply;
2134     rep.length = 5;
2135     rep.sequenceNumber = client->sequence;
2136     rep.globalAutoRepeat = ctrl->autoRepeat;
2137     rep.keyClickPercent = ctrl->click;
2138     rep.bellPercent = ctrl->bell;
2139     rep.bellPitch = ctrl->bell_pitch;
2140     rep.bellDuration = ctrl->bell_duration;
2141     rep.ledMask = ctrl->leds;
2142     for (i = 0; i < 32; i++)
2143         rep.map[i] = ctrl->autoRepeats[i];
2144     WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
2145     return Success;
2148 int
2149 ProcBell(ClientPtr client)
2151     DeviceIntPtr dev, keybd = PickKeyboard(client);
2152     int base = keybd->kbdfeed->ctrl.bell;
2153     int newpercent;
2154     int rc;
2155     REQUEST(xBellReq);
2156     REQUEST_SIZE_MATCH(xBellReq);
2158     if (stuff->percent < -100 || stuff->percent > 100) {
2159         client->errorValue = stuff->percent;
2160         return BadValue;
2161     }
2163     newpercent = (base * stuff->percent) / 100;
2164     if (stuff->percent < 0)
2165         newpercent = base + newpercent;
2166     else
2167         newpercent = base - newpercent + stuff->percent;
2169     for (dev = inputInfo.devices; dev; dev = dev->next) {
2170         if ((dev == keybd ||
2171              (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
2172             dev->kbdfeed && dev->kbdfeed->BellProc) {
2174             rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
2175             if (rc != Success)
2176                 return rc;
2177             XkbHandleBell(FALSE, FALSE, dev, newpercent,
2178                           &dev->kbdfeed->ctrl, 0, None, NULL, client);
2179         }
2180     }
2182     return Success;
2185 int
2186 ProcChangePointerControl(ClientPtr client)
2188     DeviceIntPtr dev, mouse = PickPointer(client);
2189     PtrCtrl ctrl;               /* might get BadValue part way through */
2190     int rc;
2191     REQUEST(xChangePointerControlReq);
2192     REQUEST_SIZE_MATCH(xChangePointerControlReq);
2194     ctrl = mouse->ptrfeed->ctrl;
2195     if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
2196         client->errorValue = stuff->doAccel;
2197         return BadValue;
2198     }
2199     if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
2200         client->errorValue = stuff->doThresh;
2201         return BadValue;
2202     }
2203     if (stuff->doAccel) {
2204         if (stuff->accelNum == -1) {
2205             ctrl.num = defaultPointerControl.num;
2206         }
2207         else if (stuff->accelNum < 0) {
2208             client->errorValue = stuff->accelNum;
2209             return BadValue;
2210         }
2211         else {
2212             ctrl.num = stuff->accelNum;
2213         }
2215         if (stuff->accelDenum == -1) {
2216             ctrl.den = defaultPointerControl.den;
2217         }
2218         else if (stuff->accelDenum <= 0) {
2219             client->errorValue = stuff->accelDenum;
2220             return BadValue;
2221         }
2222         else {
2223             ctrl.den = stuff->accelDenum;
2224         }
2225     }
2226     if (stuff->doThresh) {
2227         if (stuff->threshold == -1) {
2228             ctrl.threshold = defaultPointerControl.threshold;
2229         }
2230         else if (stuff->threshold < 0) {
2231             client->errorValue = stuff->threshold;
2232             return BadValue;
2233         }
2234         else {
2235             ctrl.threshold = stuff->threshold;
2236         }
2237     }
2239     for (dev = inputInfo.devices; dev; dev = dev->next) {
2240         if ((dev == mouse ||
2241              (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2242             dev->ptrfeed) {
2243             rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
2244             if (rc != Success)
2245                 return rc;
2246         }
2247     }
2249     for (dev = inputInfo.devices; dev; dev = dev->next) {
2250         if ((dev == mouse ||
2251              (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2252             dev->ptrfeed) {
2253             dev->ptrfeed->ctrl = ctrl;
2254         }
2255     }
2257     return Success;
2260 int
2261 ProcGetPointerControl(ClientPtr client)
2263     DeviceIntPtr ptr = PickPointer(client);
2264     PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
2265     xGetPointerControlReply rep;
2266     int rc;
2267     REQUEST_SIZE_MATCH(xReq);
2269     rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
2270     if (rc != Success)
2271         return rc;
2273     rep.type = X_Reply;
2274     rep.length = 0;
2275     rep.sequenceNumber = client->sequence;
2276     rep.threshold = ctrl->threshold;
2277     rep.accelNumerator = ctrl->num;
2278     rep.accelDenominator = ctrl->den;
2279     WriteReplyToClient(client, sizeof(xGenericReply), &rep);
2280     return Success;
2283 void
2284 MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
2286     GrabPtr grab = dev->deviceGrab.grab;
2288     if ((grab && SameClient(grab, client) &&
2289          ((grab->eventMask & PointerMotionHintMask) ||
2290           (grab->ownerEvents &&
2291            (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2292             PointerMotionHintMask)))) ||
2293         (!grab &&
2294          (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2295           PointerMotionHintMask)))
2296         dev->valuator->motionHintWindow = NullWindow;
2299 int
2300 ProcGetMotionEvents(ClientPtr client)
2302     WindowPtr pWin;
2303     xTimecoord * coords = (xTimecoord *) NULL;
2304     xGetMotionEventsReply rep;
2305     int i, count, xmin, xmax, ymin, ymax, rc;
2306     unsigned long nEvents;
2307     DeviceIntPtr mouse = PickPointer(client);
2308     TimeStamp start, stop;
2309     REQUEST(xGetMotionEventsReq);
2310     REQUEST_SIZE_MATCH(xGetMotionEventsReq);
2312     rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2313     if (rc != Success)
2314         return rc;
2315     rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
2316     if (rc != Success)
2317         return rc;
2319     if (mouse->valuator->motionHintWindow)
2320         MaybeStopHint(mouse, client);
2321     rep.type = X_Reply;
2322     rep.sequenceNumber = client->sequence;
2323     nEvents = 0;
2324     start = ClientTimeToServerTime(stuff->start);
2325     stop = ClientTimeToServerTime(stuff->stop);
2326     if ((CompareTimeStamps(start, stop) != LATER) &&
2327         (CompareTimeStamps(start, currentTime) != LATER) &&
2328         mouse->valuator->numMotionEvents)
2329     {
2330         if (CompareTimeStamps(stop, currentTime) == LATER)
2331             stop = currentTime;
2332         count = GetMotionHistory(mouse, &coords, start.milliseconds,
2333                                  stop.milliseconds, pWin->drawable.pScreen,
2334                                  TRUE);
2335         xmin = pWin->drawable.x - wBorderWidth (pWin);
2336         xmax = pWin->drawable.x + (int)pWin->drawable.width +
2337                 wBorderWidth (pWin);
2338         ymin = pWin->drawable.y - wBorderWidth (pWin);
2339         ymax = pWin->drawable.y + (int)pWin->drawable.height +
2340                 wBorderWidth (pWin);
2341         for (i = 0; i < count; i++)
2342             if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
2343                     (ymin <= coords[i].y) && (coords[i].y < ymax))
2344             {
2345                 coords[nEvents].time = coords[i].time;
2346                 coords[nEvents].x = coords[i].x - pWin->drawable.x;
2347                 coords[nEvents].y = coords[i].y - pWin->drawable.y;
2348                 nEvents++;
2349             }
2350     }
2351     rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
2352     rep.nEvents = nEvents;
2353     WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
2354     if (nEvents)
2355     {
2356         client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
2357         WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
2358                                  (char *)coords);
2359     }
2360     free(coords);
2361     return Success;
2364 int
2365 ProcQueryKeymap(ClientPtr client)
2367     xQueryKeymapReply rep;
2368     int rc, i;
2369     DeviceIntPtr keybd = PickKeyboard(client);
2370     CARD8 *down = keybd->key->down;
2372     REQUEST_SIZE_MATCH(xReq);
2373     rep.type = X_Reply;
2374     rep.sequenceNumber = client->sequence;
2375     rep.length = 2;
2377     rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
2378     if (rc != Success && rc != BadAccess)
2379         return rc;
2381     for (i = 0; i<32; i++)
2382         rep.map[i] = down[i];
2384     if (rc == BadAccess)
2385         memset(rep.map, 0, 32);
2387     WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
2389    return Success;
2393 /**
2394  * Recalculate the number of buttons for the master device. The number of
2395  * buttons on the master device is equal to the number of buttons on the
2396  * slave device with the highest number of buttons.
2397  */
2398 static void
2399 RecalculateMasterButtons(DeviceIntPtr slave)
2401     DeviceIntPtr dev, master;
2402     int maxbuttons = 0;
2404     if (!slave->button || IsMaster(slave))
2405         return;
2407     master = GetMaster(slave, MASTER_POINTER);
2408     if (!master)
2409         return;
2411     for (dev = inputInfo.devices; dev; dev = dev->next)
2412     {
2413         if (IsMaster(dev) ||
2414             GetMaster(dev, MASTER_ATTACHED) != master ||
2415             !dev->button)
2416             continue;
2418         maxbuttons = max(maxbuttons, dev->button->numButtons);
2419     }
2421     if (master->button && master->button->numButtons != maxbuttons)
2422     {
2423         int i;
2424         DeviceChangedEvent event;
2426         memset(&event, 0, sizeof(event));
2428         master->button->numButtons = maxbuttons;
2430         event.header = ET_Internal;
2431         event.type = ET_DeviceChanged;
2432         event.time = GetTimeInMillis();
2433         event.deviceid = master->id;
2434         event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE;
2435         event.buttons.num_buttons = maxbuttons;
2436         memcpy(&event.buttons.names, master->button->labels, maxbuttons *
2437                 sizeof(Atom));
2439         if (master->valuator)
2440         {
2441             event.num_valuators = master->valuator->numAxes;
2442             for (i = 0; i < event.num_valuators; i++)
2443             {
2444                 event.valuators[i].min = master->valuator->axes[i].min_value;
2445                 event.valuators[i].max = master->valuator->axes[i].max_value;
2446                 event.valuators[i].resolution = master->valuator->axes[i].resolution;
2447                 event.valuators[i].mode = master->valuator->axes[i].mode;
2448                 event.valuators[i].name = master->valuator->axes[i].label;
2449             }
2450         }
2452         if (master->key)
2453         {
2454             event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
2455             event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
2456         }
2458         XISendDeviceChangedEvent(master, &event);
2459     }
2462 /**
2463  * Generate release events for all keys/button currently down on this
2464  * device.
2465  */
2466 void
2467 ReleaseButtonsAndKeys(DeviceIntPtr dev)
2469     InternalEvent*      eventlist = InitEventList(GetMaximumEventsNum());
2470     ButtonClassPtr      b = dev->button;
2471     KeyClassPtr         k = dev->key;
2472     int                 i, j, nevents;
2474     if (!eventlist) /* no release events for you */
2475         return;
2477     /* Release all buttons */
2478     for (i = 0; b && i < b->numButtons; i++)
2479     {
2480         if (BitIsOn(b->down, i))
2481         {
2482             nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
2483             for (j = 0; j < nevents; j++)
2484                 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2485         }
2486     }
2488     /* Release all keys */
2489     for (i = 0; k && i < MAP_LENGTH; i++)
2490     {
2491         if (BitIsOn(k->down, i))
2492         {
2493             nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
2494             for (j = 0; j < nevents; j++)
2495                 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2496         }
2497     }
2499     FreeEventList(eventlist, GetMaximumEventsNum());
2502 /**
2503  * Attach device 'dev' to device 'master'.
2504  * Client is set to the client that issued the request, or NULL if it comes
2505  * from some internal automatic pairing.
2506  *
2507  * Master may be NULL to set the device floating.
2508  *
2509  * We don't allow multi-layer hierarchies right now. You can't attach a slave
2510  * to another slave.
2511  */
2512 int
2513 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
2515     ScreenPtr screen;
2516     if (!dev || IsMaster(dev))
2517         return BadDevice;
2519     if (master && !IsMaster(master)) /* can't attach to slaves */
2520         return BadDevice;
2522     /* set from floating to floating? */
2523     if (IsFloating(dev) && !master && dev->enabled)
2524         return Success;
2526     /* free the existing sprite. */
2527     if (IsFloating(dev) && dev->spriteInfo->paired == dev)
2528     {
2529         screen = miPointerGetScreen(dev);
2530         screen->DeviceCursorCleanup(dev, screen);
2531         free(dev->spriteInfo->sprite);
2532     }
2534     dev->master = master;
2536     /* If device is set to floating, we need to create a sprite for it,
2537      * otherwise things go bad. However, we don't want to render the cursor,
2538      * so we reset spriteOwner.
2539      * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
2540      * alloc new memory but overwrite the previous one.
2541      */
2542     if (!master)
2543     {
2544         WindowPtr currentRoot;
2546         if (dev->spriteInfo->sprite)
2547             currentRoot = GetCurrentRootWindow(dev);
2548         else /* new device auto-set to floating */
2549             currentRoot = screenInfo.screens[0]->root;
2551         /* we need to init a fake sprite */
2552         screen = currentRoot->drawable.pScreen;
2553         screen->DeviceCursorInitialize(dev, screen);
2554         dev->spriteInfo->sprite = NULL;
2555         InitializeSprite(dev, currentRoot);
2556         dev->spriteInfo->spriteOwner = FALSE;
2557         dev->spriteInfo->paired = dev;
2558     } else
2559     {
2560         dev->spriteInfo->sprite = master->spriteInfo->sprite;
2561         dev->spriteInfo->paired = master;
2562         dev->spriteInfo->spriteOwner = FALSE;
2564         RecalculateMasterButtons(master);
2565     }
2567     /* XXX: in theory, the MD should change back to its old, original
2568      * classes when the last SD is detached. Thanks to the XTEST devices,
2569      * we'll always have an SD attached until the MD is removed.
2570      * So let's not worry about that.
2571      */
2573     return Success;
2576 /**
2577  * Return the device paired with the given device or NULL.
2578  * Returns the device paired with the parent master if the given device is a
2579  * slave device.
2580  */
2581 DeviceIntPtr
2582 GetPairedDevice(DeviceIntPtr dev)
2584     if (!IsMaster(dev) && !IsFloating(dev))
2585         dev = GetMaster(dev, MASTER_ATTACHED);
2587     return dev->spriteInfo->paired;
2591 /**
2592  * Returns the requested master for this device.
2593  * The return values are:
2594  * - MASTER_ATTACHED: the master for this device or NULL for a floating
2595  *   slave.
2596  * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a
2597  *   floating slave
2598  * - MASTER_POINTER: the master keyboard for this device or NULL for a
2599  *   floating slave
2600  * - POINTER_OR_FLOAT: the master pointer for this device or the device for
2601  *   a floating slave
2602  * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for
2603  *   a floating slave
2604  *
2605  * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED,
2606  * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT.
2607  * @return The requested master device
2608  */
2609 DeviceIntPtr
2610 GetMaster(DeviceIntPtr dev, int which)
2612     DeviceIntPtr master;
2614     if (IsMaster(dev))
2615         master = dev;
2616     else {
2617         master = dev->master;
2618         if (!master && (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT))
2619             return dev;
2620     }
2622     if (master && which != MASTER_ATTACHED)
2623     {
2624         if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT)
2625         {
2626             if (master->type != MASTER_KEYBOARD)
2627                 master = GetPairedDevice(master);
2628         } else
2629         {
2630             if (master->type != MASTER_POINTER)
2631                 master = GetPairedDevice(master);
2632         }
2633     }
2635     return master;
2638 /**
2639  * Create a new device pair (== one pointer, one keyboard device).
2640  * Only allocates the devices, you will need to call ActivateDevice() and
2641  * EnableDevice() manually.
2642  * Either a master or a slave device can be created depending on
2643  * the value for master.
2644  */
2645 int
2646 AllocDevicePair (ClientPtr client, char* name,
2647                  DeviceIntPtr* ptr,
2648                  DeviceIntPtr* keybd,
2649                  DeviceProc ptr_proc,
2650                  DeviceProc keybd_proc,
2651                  Bool master)
2653     DeviceIntPtr pointer;
2654     DeviceIntPtr keyboard;
2655     *ptr = *keybd = NULL;
2657     pointer = AddInputDevice(client, ptr_proc, TRUE);
2658     if (!pointer)
2659         return BadAlloc;
2661     if (asprintf(&pointer->name, "%s pointer", name) == -1) {
2662         pointer->name = NULL;
2663         RemoveDevice(pointer, FALSE);
2664         return BadAlloc;
2665     }
2667     pointer->public.processInputProc = ProcessOtherEvent;
2668     pointer->public.realInputProc = ProcessOtherEvent;
2669     XkbSetExtension(pointer, ProcessPointerEvent);
2670     pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
2671     pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
2672     pointer->coreEvents = TRUE;
2673     pointer->spriteInfo->spriteOwner = TRUE;
2675     pointer->lastSlave = NULL;
2676     pointer->last.slave = NULL;
2677     pointer->type = (master) ? MASTER_POINTER : SLAVE;
2679     keyboard = AddInputDevice(client, keybd_proc, TRUE);
2680     if (!keyboard)
2681     {
2682         RemoveDevice(pointer, FALSE);
2683         return BadAlloc;
2684     }
2686     if (asprintf(&keyboard->name, "%s keyboard", name) == -1) {
2687         keyboard->name = NULL;
2688         RemoveDevice(keyboard, FALSE);
2689         RemoveDevice(pointer, FALSE);
2690         return BadAlloc;
2691     }
2693     keyboard->public.processInputProc = ProcessOtherEvent;
2694     keyboard->public.realInputProc = ProcessOtherEvent;
2695     XkbSetExtension(keyboard, ProcessKeyboardEvent);
2696     keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
2697     keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
2698     keyboard->coreEvents = TRUE;
2699     keyboard->spriteInfo->spriteOwner = FALSE;
2701     keyboard->lastSlave = NULL;
2702     keyboard->last.slave = NULL;
2703     keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
2705     /* The ClassesRec stores the device classes currently not used. */
2706     pointer->unused_classes = calloc(1, sizeof(ClassesRec));
2707     keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
2709     *ptr = pointer;
2710     *keybd = keyboard;
2712     return Success;
2715 /**
2716  * Return Relative or Absolute for the device.
2717  */
2718 int valuator_get_mode(DeviceIntPtr dev, int axis)
2720     return (dev->valuator->axes[axis].mode & DeviceMode);
2723 /**
2724  * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
2725  * set the mode for all axes.
2726  */
2727 void valuator_set_mode(DeviceIntPtr dev, int axis, int mode)
2729     if (axis != VALUATOR_MODE_ALL_AXES)
2730         dev->valuator->axes[axis].mode = mode;
2731     else {
2732         int i;
2733         for (i = 0; i < dev->valuator->numAxes; i++)
2734             dev->valuator->axes[i].mode = mode;
2735     }