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
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.
25 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
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.
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
45 ********************************************************/
47 #ifdef HAVE_DIX_CONFIG_H
48 #include <dix-config.h>
54 #include <X11/Xproto.h>
55 #include <X11/Xatom.h>
56 #include "windowstr.h"
58 #include "scrnintstr.h"
59 #include "cursorstr.h"
60 #include "dixstruct.h"
70 #include "dixevents.h"
71 #include "mipointer.h"
75 #include <X11/extensions/XI.h>
76 #include <X11/extensions/XI2.h>
77 #include <X11/extensions/XIproto.h>
80 #include "exglobals.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 */
90 * This file handles input device-related stuff.
93 static void RecalculateMasterButtons(DeviceIntPtr slave);
96 DeviceSetTransform(DeviceIntPtr dev, float *transform)
98 struct pixman_f_transform scale;
103 * calculate combined transformation matrix:
105 * M = InvScale * Transform * Scale
107 * So we can later transform points using M * p
110 * Scale scales coordinates into 0..1 range
111 * Transform is the user supplied (affine) transform
112 * InvScale scales coordinates back up into their native range
114 sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value;
115 sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value;
118 pixman_f_transform_init_scale(&scale, sx, sy);
119 scale.m[0][2] = dev->valuator->axes[0].min_value;
120 scale.m[1][2] = dev->valuator->axes[1].min_value;
123 for (y = 0; y < 3; y++)
124 for (x = 0; x < 3; x++)
125 dev->transform.m[y][x] = *transform++;
127 pixman_f_transform_multiply(&dev->transform, &scale, &dev->transform);
130 pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
131 scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
132 scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
134 pixman_f_transform_multiply(&dev->transform, &dev->transform, &scale);
138 * DIX property handler.
141 DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
144 if (property == XIGetKnownProperty(XI_PROP_ENABLED)) {
145 if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
148 /* Don't allow disabling of VCP/VCK */
149 if ((dev == inputInfo.pointer ||dev ==
150 inputInfo.keyboard) &&!(*(CARD8 *) prop->data))
154 if ((*((CARD8 *) prop->data)) && !dev->enabled)
155 EnableDevice(dev, TRUE);
156 else if (!(*((CARD8 *) prop->data)) && dev->enabled)
157 DisableDevice(dev, TRUE);
160 else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) {
161 float *f = (float *) prop->data;
164 if (prop->format != 32 || prop->size != 9 ||
165 prop->type != XIGetKnownProperty(XATOM_FLOAT))
168 for (i = 0; i < 9; i++)
173 DeviceSetTransform(dev, f);
179 /* Pair the keyboard to the pointer device. Keyboard events will follow the
180 * pointer sprite. Only applicable for master devices.
183 PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd)
188 /* Don't allow pairing for slave devices */
189 if (!IsMaster(ptr) || !IsMaster(kbd))
192 if (ptr->spriteInfo->paired)
195 if (kbd->spriteInfo->spriteOwner) {
196 free(kbd->spriteInfo->sprite);
197 kbd->spriteInfo->sprite = NULL;
198 kbd->spriteInfo->spriteOwner = FALSE;
201 kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
202 kbd->spriteInfo->paired = ptr;
203 ptr->spriteInfo->paired = kbd;
208 * Find and return the next unpaired MD pointer device.
211 NextFreePointerDevice(void)
215 for (dev = inputInfo.devices; dev; dev = dev->next)
217 dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired)
223 * Create a new input device and init it to sane values. The device is added
224 * to the server's off_devices list.
226 * @param deviceProc Callback for device control function (switch dev on/off).
227 * @return The newly created device.
230 AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
232 DeviceIntPtr dev, *prev; /* not a typo */
235 char devind[MAXDEVICES];
239 /* Find next available id, 0 and 1 are reserved */
240 memset(devind, 0, sizeof(char) * MAXDEVICES);
241 for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
242 devind[devtmp->id]++;
243 for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
244 devind[devtmp->id]++;
245 for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++);
247 if (devid >= MAXDEVICES)
248 return (DeviceIntPtr) NULL;
250 sizeof(DeviceIntRec) +
251 sizeof(SpriteInfoRec));
253 return (DeviceIntPtr) NULL;
255 if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) {
261 return (DeviceIntPtr) NULL;
263 dev->last.scroll = NULL;
264 dev->last.touches = NULL;
266 dev->public.processInputProc = ProcessOtherEvent;
267 dev->public.realInputProc = ProcessOtherEvent;
268 dev->public.enqueueInputProc = EnqueueEvent;
269 dev->deviceProc = deviceProc;
270 dev->startup = autoStart;
272 /* device grab defaults */
273 dev->deviceGrab.grabTime = currentTime;
274 dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
275 dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
276 dev->deviceGrab.activeGrab = AllocGrab();
277 dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
279 XkbSetExtension(dev, ProcessKeyboardEvent);
281 dev->coreEvents = TRUE;
283 /* sprite defaults */
284 dev->spriteInfo = (SpriteInfoPtr) & dev[1];
286 /* security creation/labeling check
288 if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
289 dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
294 inputInfo.numDevices++;
296 for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next);
301 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
302 XA_INTEGER, 8, PropModeReplace, 1, &enabled, FALSE);
303 XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED),
307 memset(transform, 0, sizeof(transform));
308 transform[0] = transform[4] = transform[8] = 1.0f;
310 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
311 XIGetKnownProperty(XATOM_FLOAT), 32,
312 PropModeReplace, 9, transform, FALSE);
313 XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
316 XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
322 SendDevicePresenceEvent(int deviceid, int type)
324 DeviceIntRec dummyDev = { .id = XIAllDevices };
325 devicePresenceNotify ev = {
326 .type = DevicePresenceNotify,
327 .time = currentTime.milliseconds,
332 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
337 * Enable the device through the driver, add the device to the device list.
338 * Switch device ON through the driver and push it onto the global device
339 * list. Initialize the DIX sprite or pair the device. All clients are
340 * notified about the device being enabled.
342 * A master pointer device needs to be enabled before a master keyboard
345 * @param The device to be enabled.
346 * @param sendevent True if an XI2 event should be sent.
347 * @return TRUE on success or FALSE otherwise.
350 EnableDevice(DeviceIntPtr dev, BOOL sendevent)
356 int flags[MAXDEVICES] = { 0 };
358 for (prev = &inputInfo.off_devices;
359 *prev && (*prev != dev); prev = &(*prev)->next);
361 if (!dev->spriteInfo->sprite) {
363 /* Sprites appear on first root window, so we can hardcode it */
364 if (dev->spriteInfo->spriteOwner) {
365 InitializeSprite(dev, screenInfo.screens[0]->root);
366 /* mode doesn't matter */
367 EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
370 other = NextFreePointerDevice();
371 BUG_RETURN_VAL_MSG(other == NULL, FALSE,
372 "[dix] cannot find pointer to pair with.\n");
373 PairDevices(other, dev);
378 other = (IsPointerDevice(dev)) ? inputInfo.pointer :
381 other = NULL; /* auto-float non-core devices */
382 AttachDevice(NULL, dev, other);
386 if ((*prev != dev) || !dev->inited ||
387 ((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) {
388 ErrorF("[dix] couldn't enable device %d\n", dev->id);
394 for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next);
399 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
400 XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE);
402 SendDevicePresenceEvent(dev->id, DeviceEnabled);
404 flags[dev->id] |= XIDeviceEnabled;
405 XISendDeviceHierarchyEvent(flags);
408 RecalculateMasterButtons(dev);
410 /* initialise an idle timer for this device*/
411 dev->idle_counter = SyncInitDeviceIdleTime(dev);
418 * Switch a device off through the driver and push it onto the off_devices
419 * list. A device will not send events while disabled. All clients are
420 * notified about the device being disabled.
422 * Master keyboard devices have to be disabled before master pointer devices
423 * otherwise things turn bad.
425 * @param sendevent True if an XI2 event should be sent.
426 * @return TRUE on success or FALSE otherwise.
429 DisableDevice(DeviceIntPtr dev, BOOL sendevent)
431 DeviceIntPtr *prev, other;
433 int flags[MAXDEVICES] = { 0 };
438 for (prev = &inputInfo.devices;
439 *prev && (*prev != dev); prev = &(*prev)->next);
443 ReleaseButtonsAndKeys(dev);
444 SyncRemoveDeviceIdleTime(dev->idle_counter);
445 dev->idle_counter = NULL;
447 /* float attached devices */
449 for (other = inputInfo.devices; other; other = other->next) {
450 if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
451 AttachDevice(NULL, other, NULL);
452 flags[other->id] |= XISlaveDetached;
457 for (other = inputInfo.devices; other; other = other->next) {
458 if (IsMaster(other) && other->lastSlave == dev)
459 other->lastSlave = NULL;
463 if (IsMaster(dev) && dev->spriteInfo->sprite) {
464 for (other = inputInfo.devices; other; other = other->next)
465 if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner)
466 DisableDevice(other, sendevent);
469 if (dev->spriteInfo->paired)
470 dev->spriteInfo->paired = NULL;
472 (void) (*dev->deviceProc) (dev, DEVICE_OFF);
473 dev->enabled = FALSE;
477 /* now that the device is disabled, we can reset the signal handler's
480 for (other = inputInfo.devices; other; other = other->next) {
481 if (other->last.slave == dev)
482 other->last.slave = NULL;
490 dev->next = inputInfo.off_devices;
491 inputInfo.off_devices = dev;
494 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
495 XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE);
497 SendDevicePresenceEvent(dev->id, DeviceDisabled);
499 flags[dev->id] = XIDeviceDisabled;
500 XISendDeviceHierarchyEvent(flags);
503 RecalculateMasterButtons(dev);
509 DisableAllDevices(void)
511 DeviceIntPtr dev, tmp;
513 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
515 DisableDevice(dev, FALSE);
517 /* master keyboards need to be disabled first */
518 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
519 if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev))
520 DisableDevice(dev, FALSE);
522 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
524 DisableDevice(dev, FALSE);
529 * Initialise a new device through the driver and tell all clients about the
532 * Must be called before EnableDevice.
533 * The device will NOT send events until it is enabled!
535 * @param sendevent True if an XI2 event should be sent.
536 * @return Success or an error code on failure.
539 ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
542 ScreenPtr pScreen = screenInfo.screens[0];
544 if (!dev || !dev->deviceProc)
545 return BadImplementation;
547 ret = (*dev->deviceProc) (dev, DEVICE_INIT);
548 dev->inited = (ret == Success);
552 /* Initialize memory for sprites. */
553 if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
554 if (!pScreen->DeviceCursorInitialize(dev, pScreen))
557 SendDevicePresenceEvent(dev->id, DeviceAdded);
559 int flags[MAXDEVICES] = { 0 };
560 flags[dev->id] = XISlaveAdded;
561 XISendDeviceHierarchyEvent(flags);
568 * The actual task of ringing the bell is the job of the DDX.
571 CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
573 KeybdCtrl *ctrl = arg;
575 DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
579 CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
585 * Device control function for the Virtual Core Keyboard.
588 CoreKeyboardProc(DeviceIntPtr pDev, int what)
593 if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
595 ErrorF("Keyboard initialization failed. This could be a missing "
596 "or incorrect setup of xkeyboard-config.\n");
613 * Device control function for the Virtual Core Pointer.
616 CorePointerProc(DeviceIntPtr pDev, int what)
620 BYTE map[NBUTTONS + 1];
622 Atom btn_labels[NBUTTONS] = { 0 };
623 Atom axes_labels[NAXES] = { 0 };
624 ScreenPtr scr = screenInfo.screens[0];
628 for (i = 1; i <= NBUTTONS; i++)
631 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
632 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
633 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
634 btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
635 btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
636 btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
637 btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
638 /* don't know about the rest */
640 axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
641 axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
643 if (!InitPointerDeviceStruct
644 ((DevicePtr) pDev, map, NBUTTONS, btn_labels,
645 (PtrCtrlProcPtr) NoopDDA, GetMotionHistorySize(), NAXES,
647 ErrorF("Could not initialize device '%s'. Out of memory.\n",
649 return BadAlloc; /* IPDS only fails on allocs */
651 /* axisVal is per-screen, last.valuators is desktop-wide */
652 pDev->valuator->axisVal[0] = scr->width / 2;
653 pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x;
654 pDev->valuator->axisVal[1] = scr->height / 2;
655 pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y;
672 * Initialise the two core devices, VCP and VCK (see events.c).
673 * Both devices are not tied to physical devices, but guarantee that there is
674 * always a keyboard and a pointer present and keep the protocol semantics.
676 * Note that the server MUST have two core devices at all times, even if there
677 * is no physical device connected.
680 InitCoreDevices(void)
682 if (AllocDevicePair(serverClient, "Virtual core",
683 &inputInfo.pointer, &inputInfo.keyboard,
684 CorePointerProc, CoreKeyboardProc, TRUE) != Success)
685 FatalError("Failed to allocate core devices");
687 if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
688 ActivateDevice(inputInfo.keyboard, TRUE) != Success)
689 FatalError("Failed to activate core devices.");
690 if (!EnableDevice(inputInfo.pointer, TRUE) ||
691 !EnableDevice(inputInfo.keyboard, TRUE))
692 FatalError("Failed to enable core devices.");
698 * Activate all switched-off devices and then enable all those devices.
700 * Will return an error if no core keyboard or core pointer is present.
701 * In theory this should never happen if you call InitCoreDevices() first.
703 * InitAndStartDevices needs to be called AFTER the windows are initialized.
704 * Devices will start sending events after InitAndStartDevices() has
707 * @return Success or error code on failure.
710 InitAndStartDevices(void)
712 DeviceIntPtr dev, next;
714 for (dev = inputInfo.off_devices; dev; dev = dev->next) {
715 DebugF("(dix) initialising device %d\n", dev->id);
717 ActivateDevice(dev, TRUE);
720 /* enable real devices */
721 for (dev = inputInfo.off_devices; dev; dev = next) {
722 DebugF("(dix) enabling device %d\n", dev->id);
724 if (dev->inited && dev->startup)
725 EnableDevice(dev, TRUE);
732 * Free the given device class and reset the pointer to NULL.
735 FreeDeviceClass(int type, pointer *class)
743 KeyClassPtr *k = (KeyClassPtr *) class;
746 XkbFreeInfo((*k)->xkbInfo);
747 (*k)->xkbInfo = NULL;
754 ButtonClassPtr *b = (ButtonClassPtr *) class;
756 free((*b)->xkb_acts);
762 ValuatorClassPtr *v = (ValuatorClassPtr *) class;
770 TouchClassPtr *t = (TouchClassPtr *) class;
773 for (i = 0; i < (*t)->num_touches; i++) {
774 free((*t)->touches[i].sprite.spriteTrace);
775 free((*t)->touches[i].listeners);
776 free((*t)->touches[i].valuators);
784 FocusClassPtr *f = (FocusClassPtr *) class;
792 ProximityClassPtr *p = (ProximityClassPtr *) class;
802 FreeFeedbackClass(int type, pointer *class)
808 case KbdFeedbackClass:
810 KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr *) class;
811 KbdFeedbackPtr k, knext;
813 for (k = (*kbdfeed); k; k = knext) {
816 XkbFreeSrvLedInfo(k->xkb_sli);
821 case PtrFeedbackClass:
823 PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr *) class;
824 PtrFeedbackPtr p, pnext;
826 for (p = (*ptrfeed); p; p = pnext) {
832 case IntegerFeedbackClass:
834 IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr *) class;
835 IntegerFeedbackPtr i, inext;
837 for (i = (*intfeed); i; i = inext) {
843 case StringFeedbackClass:
845 StringFeedbackPtr *stringfeed = (StringFeedbackPtr *) class;
846 StringFeedbackPtr s, snext;
848 for (s = (*stringfeed); s; s = snext) {
850 free(s->ctrl.symbols_supported);
851 free(s->ctrl.symbols_displayed);
856 case BellFeedbackClass:
858 BellFeedbackPtr *bell = (BellFeedbackPtr *) class;
859 BellFeedbackPtr b, bnext;
861 for (b = (*bell); b; b = bnext) {
867 case LedFeedbackClass:
869 LedFeedbackPtr *leds = (LedFeedbackPtr *) class;
870 LedFeedbackPtr l, lnext;
872 for (l = (*leds); l; l = lnext) {
875 XkbFreeSrvLedInfo(l->xkb_sli);
885 FreeAllDeviceClasses(ClassesPtr classes)
890 FreeDeviceClass(KeyClass, (pointer) &classes->key);
891 FreeDeviceClass(ValuatorClass, (pointer) &classes->valuator);
892 FreeDeviceClass(XITouchClass, (pointer) &classes->touch);
893 FreeDeviceClass(ButtonClass, (pointer) &classes->button);
894 FreeDeviceClass(FocusClass, (pointer) &classes->focus);
895 FreeDeviceClass(ProximityClass, (pointer) &classes->proximity);
897 FreeFeedbackClass(KbdFeedbackClass, (pointer) &classes->kbdfeed);
898 FreeFeedbackClass(PtrFeedbackClass, (pointer) &classes->ptrfeed);
899 FreeFeedbackClass(IntegerFeedbackClass, (pointer) &classes->intfeed);
900 FreeFeedbackClass(StringFeedbackClass, (pointer) &classes->stringfeed);
901 FreeFeedbackClass(BellFeedbackClass, (pointer) &classes->bell);
902 FreeFeedbackClass(LedFeedbackClass, (pointer) &classes->leds);
907 * Close down a device and free all resources.
908 * Once closed down, the driver will probably not expect you that you'll ever
909 * enable it again and free associated structs. If you want the device to just
910 * be disabled, DisableDevice().
911 * Don't call this function directly, use RemoveDevice() instead.
914 CloseDevice(DeviceIntPtr dev)
916 ScreenPtr screen = screenInfo.screens[0];
923 XIDeleteAllDeviceProperties(dev);
926 (void) (*dev->deviceProc) (dev, DEVICE_CLOSE);
928 /* free sprite memory */
929 if (IsMaster(dev) && dev->spriteInfo->sprite)
930 screen->DeviceCursorCleanup(dev, screen);
932 /* free acceleration info */
933 if (dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
934 dev->valuator->accelScheme.AccelCleanupProc(dev);
936 while (dev->xkb_interest)
937 XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource);
941 classes = (ClassesPtr) & dev->key;
942 FreeAllDeviceClasses(classes);
945 classes = dev->unused_classes;
946 FreeAllDeviceClasses(classes);
952 /* a client may have the device set as client pointer */
953 for (j = 0; j < currentMaxClients; j++) {
954 if (clients[j] && clients[j]->clientPtr == dev) {
955 clients[j]->clientPtr = NULL;
956 clients[j]->clientPtr = PickPointer(clients[j]);
960 FreeGrab(dev->deviceGrab.activeGrab);
961 free(dev->deviceGrab.sync.event);
962 free(dev->config_info); /* Allocated in xf86ActivateDevice. */
963 free(dev->last.scroll);
964 for (j = 0; j < dev->last.num_touches; j++)
965 free(dev->last.touches[j].valuators);
966 free(dev->last.touches);
967 dev->config_info = NULL;
968 dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
973 * Shut down all devices of one list and free all resources.
977 CloseDeviceList(DeviceIntPtr *listHead)
979 /* Used to mark devices that we tried to free */
980 Bool freedIds[MAXDEVICES];
984 if (listHead == NULL)
987 for (i = 0; i < MAXDEVICES; i++)
991 while (dev != NULL) {
992 freedIds[dev->id] = TRUE;
993 DeleteInputDeviceRequest(dev);
996 while (dev != NULL && freedIds[dev->id])
1002 * Shut down all devices, free all resources, etc.
1003 * Only useful if you're shutting down the server!
1006 CloseDownDevices(void)
1012 /* Float all SDs before closing them. Note that at this point resources
1013 * (e.g. cursors) have been freed already, so we can't just call
1014 * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
1015 * to NULL and pretend nothing happened.
1017 for (dev = inputInfo.devices; dev; dev = dev->next) {
1018 if (!IsMaster(dev) && !IsFloating(dev))
1022 CloseDeviceList(&inputInfo.devices);
1023 CloseDeviceList(&inputInfo.off_devices);
1025 CloseDevice(inputInfo.pointer);
1027 CloseDevice(inputInfo.keyboard);
1029 inputInfo.devices = NULL;
1030 inputInfo.off_devices = NULL;
1031 inputInfo.keyboard = NULL;
1032 inputInfo.pointer = NULL;
1034 XkbDeleteRulesDflts();
1040 * Remove the cursor sprite for all devices. This needs to be done before any
1041 * resources are freed or any device is deleted.
1044 UndisplayDevices(void)
1047 ScreenPtr screen = screenInfo.screens[0];
1049 for (dev = inputInfo.devices; dev; dev = dev->next)
1050 screen->DisplayCursor(dev, screen, NullCursor);
1054 * Remove a device from the device list, closes it and thus frees all
1056 * Removes both enabled and disabled devices and notifies all devices about
1057 * the removal of the device.
1059 * No PresenceNotify is sent for device that the client never saw. This can
1060 * happen if a malloc fails during the addition of master devices. If
1061 * dev->init is FALSE it means the client never received a DeviceAdded event,
1062 * so let's not send a DeviceRemoved event either.
1064 * @param sendevent True if an XI2 event should be sent.
1067 RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
1069 DeviceIntPtr prev, tmp, next;
1071 ScreenPtr screen = screenInfo.screens[0];
1074 int flags[MAXDEVICES] = { 0 };
1076 DebugF("(dix) removing device %d\n", dev->id);
1078 if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
1079 return BadImplementation;
1081 initialized = dev->inited;
1085 if (DevHasCursor(dev))
1086 screen->DisplayCursor(dev, screen, NullCursor);
1088 DisableDevice(dev, sendevent);
1089 flags[dev->id] = XIDeviceDisabled;
1093 for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
1098 inputInfo.devices = next;
1102 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1109 for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
1112 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1116 inputInfo.off_devices = next;
1124 if (ret == Success && initialized) {
1125 inputInfo.numDevices--;
1126 SendDevicePresenceEvent(deviceid, DeviceRemoved);
1128 XISendDeviceHierarchyEvent(flags);
1135 NumMotionEvents(void)
1137 /* only called to fill data in initial connection reply.
1138 * VCP is ok here, it is the only fixed device we have. */
1139 return inputInfo.pointer->valuator->numMotionEvents;
1143 dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
1150 for (dev = inputInfo.devices; dev; dev = dev->next) {
1154 for (dev = inputInfo.off_devices; dev; dev = dev->next) {
1161 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
1168 QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
1170 if (inputInfo.keyboard) {
1171 *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
1172 *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
1176 /* Notably, this function does not expand the destination's keycode range, or
1177 * notify clients. */
1179 SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
1183 int rowDif = src->minKeyCode - dst->minKeyCode;
1185 /* if keysym map size changes, grow map first */
1186 if (src->mapWidth < dst->mapWidth) {
1187 for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
1188 #define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
1189 #define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
1190 for (j = 0; j < src->mapWidth; j++)
1191 dst->map[DI(i, j)] = src->map[SI(i, j)];
1192 for (j = src->mapWidth; j < dst->mapWidth; j++)
1193 dst->map[DI(i, j)] = NoSymbol;
1199 else if (src->mapWidth > dst->mapWidth) {
1200 i = sizeof(KeySym) * src->mapWidth *
1201 (dst->maxKeyCode - dst->minKeyCode + 1);
1202 tmp = calloc(sizeof(KeySym), i);
1207 for (i = 0; i <= dst->maxKeyCode - dst->minKeyCode; i++)
1208 memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
1209 dst->mapWidth * sizeof(KeySym));
1212 dst->mapWidth = src->mapWidth;
1215 else if (!dst->map) {
1216 i = sizeof(KeySym) * src->mapWidth *
1217 (dst->maxKeyCode - dst->minKeyCode + 1);
1218 tmp = calloc(sizeof(KeySym), i);
1223 dst->mapWidth = src->mapWidth;
1226 memmove(&dst->map[rowDif * dst->mapWidth], src->map,
1227 (src->maxKeyCode - src->minKeyCode + 1) *
1228 dst->mapWidth * sizeof(KeySym));
1234 InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels,
1237 ButtonClassPtr butc;
1240 butc = calloc(1, sizeof(ButtonClassRec));
1243 butc->numButtons = numButtons;
1244 butc->sourceid = dev->id;
1245 for (i = 1; i <= numButtons; i++)
1246 butc->map[i] = map[i];
1247 for (i = numButtons + 1; i < MAP_LENGTH; i++)
1249 memcpy(butc->labels, labels, numButtons * sizeof(Atom));
1255 * Allocate a valuator class and set up the pointers for the axis values
1258 * @param src If non-NULL, the memory is reallocated from src. If NULL, the
1259 * memory is calloc'd.
1260 * @parma numAxes Number of axes to allocate.
1261 * @return The allocated valuator struct.
1264 AllocValuatorClass(ValuatorClassPtr src, int numAxes)
1268 /* force alignment with double */
1270 ValuatorClassRec valc;
1276 sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo));
1277 align = (union align_u *) realloc(src, size);
1283 memset(align, 0, size);
1286 v->numAxes = numAxes;
1287 v->axisVal = (double *) (align + 1);
1288 v->axes = (AxisInfoPtr) (v->axisVal + numAxes);
1294 InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
1295 int numMotionEvents, int mode)
1298 ValuatorClassPtr valc;
1303 if (numAxes > MAX_VALUATORS) {
1304 LogMessage(X_WARNING,
1305 "Device '%s' has %d axes, only using first %d.\n",
1306 dev->name, numAxes, MAX_VALUATORS);
1307 numAxes = MAX_VALUATORS;
1310 valc = AllocValuatorClass(NULL, numAxes);
1314 dev->last.scroll = valuator_mask_new(numAxes);
1315 if (!dev->last.scroll) {
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,
1339 NO_AXIS_LIMITS, 0, 0, 0, mode);
1340 valc->axisVal[i] = 0;
1343 dev->last.numValuators = numAxes;
1345 if (IsMaster(dev) || /* do not accelerate master or xtest devices */
1346 IsXTestDevice(dev, NULL))
1347 InitPointerAccelerationScheme(dev, PtrAccelNoOp);
1349 InitPointerAccelerationScheme(dev, PtrAccelDefault);
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 */
1363 * install an acceleration scheme. returns TRUE on success, and should not
1364 * change anything if unsuccessful.
1367 InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme)
1370 ValuatorClassPtr val;
1372 val = dev->valuator;
1377 if (IsMaster(dev) && scheme != PtrAccelNoOp)
1380 for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
1381 if (pointerAccelerationScheme[x].number == scheme) {
1390 if (val->accelScheme.AccelCleanupProc)
1391 val->accelScheme.AccelCleanupProc(dev);
1393 if (pointerAccelerationScheme[i].AccelInitProc) {
1394 if (!pointerAccelerationScheme[i].AccelInitProc(dev,
1395 &pointerAccelerationScheme[i])) {
1400 val->accelScheme = pointerAccelerationScheme[i];
1406 InitFocusClassDeviceStruct(DeviceIntPtr dev)
1410 focc = malloc(sizeof(FocusClassRec));
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;
1425 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
1427 PtrFeedbackPtr feedc;
1429 feedc = malloc(sizeof(PtrFeedbackClassRec));
1432 feedc->CtrlProc = controlProc;
1433 feedc->ctrl = defaultPointerControl;
1435 if ((feedc->next = dev->ptrfeed))
1436 feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
1437 dev->ptrfeed = feedc;
1438 (*controlProc) (dev, &feedc->ctrl);
1442 static LedCtrl defaultLedControl = {
1443 DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0
1446 static BellCtrl defaultBellControl = {
1449 DEFAULT_BELL_DURATION,
1453 static IntegerCtrl defaultIntegerControl = {
1454 DEFAULT_INT_RESOLUTION,
1455 DEFAULT_INT_MIN_VALUE,
1456 DEFAULT_INT_MAX_VALUE,
1457 DEFAULT_INT_DISPLAYED,
1462 InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev,
1463 StringCtrlProcPtr controlProc,
1464 int max_symbols, int num_symbols_supported,
1468 StringFeedbackPtr feedc;
1470 feedc = malloc(sizeof(StringFeedbackClassRec));
1473 feedc->CtrlProc = controlProc;
1474 feedc->ctrl.num_symbols_supported = num_symbols_supported;
1475 feedc->ctrl.num_symbols_displayed = 0;
1476 feedc->ctrl.max_symbols = max_symbols;
1477 feedc->ctrl.symbols_supported =
1478 malloc(sizeof(KeySym) * num_symbols_supported);
1479 feedc->ctrl.symbols_displayed = malloc(sizeof(KeySym) * max_symbols);
1480 if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) {
1481 free(feedc->ctrl.symbols_supported);
1482 free(feedc->ctrl.symbols_displayed);
1486 for (i = 0; i < num_symbols_supported; i++)
1487 *(feedc->ctrl.symbols_supported + i) = *symbols++;
1488 for (i = 0; i < max_symbols; i++)
1489 *(feedc->ctrl.symbols_displayed + i) = (KeySym) 0;
1491 if ((feedc->next = dev->stringfeed))
1492 feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
1493 dev->stringfeed = feedc;
1494 (*controlProc) (dev, &feedc->ctrl);
1499 InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
1500 BellCtrlProcPtr controlProc)
1502 BellFeedbackPtr feedc;
1504 feedc = malloc(sizeof(BellFeedbackClassRec));
1507 feedc->CtrlProc = controlProc;
1508 feedc->BellProc = bellProc;
1509 feedc->ctrl = defaultBellControl;
1511 if ((feedc->next = dev->bell))
1512 feedc->ctrl.id = dev->bell->ctrl.id + 1;
1514 (*controlProc) (dev, &feedc->ctrl);
1519 InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev, LedCtrlProcPtr controlProc)
1521 LedFeedbackPtr feedc;
1523 feedc = malloc(sizeof(LedFeedbackClassRec));
1526 feedc->CtrlProc = controlProc;
1527 feedc->ctrl = defaultLedControl;
1529 if ((feedc->next = dev->leds))
1530 feedc->ctrl.id = dev->leds->ctrl.id + 1;
1531 feedc->xkb_sli = NULL;
1533 (*controlProc) (dev, &feedc->ctrl);
1538 InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev,
1539 IntegerCtrlProcPtr controlProc)
1541 IntegerFeedbackPtr feedc;
1543 feedc = malloc(sizeof(IntegerFeedbackClassRec));
1546 feedc->CtrlProc = controlProc;
1547 feedc->ctrl = defaultIntegerControl;
1549 if ((feedc->next = dev->intfeed))
1550 feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
1551 dev->intfeed = feedc;
1552 (*controlProc) (dev, &feedc->ctrl);
1557 InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
1558 Atom *btn_labels, PtrCtrlProcPtr controlProc,
1559 int numMotionEvents, int numAxes, Atom *axes_labels)
1561 DeviceIntPtr dev = (DeviceIntPtr) device;
1563 return (InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
1564 InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
1565 numMotionEvents, Relative) &&
1566 InitPtrFeedbackClassDeviceStruct(dev, controlProc));
1570 * Sets up multitouch capabilities on @device.
1572 * @max_touches The maximum number of simultaneous touches, or 0 for unlimited.
1573 * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch).
1574 * @num_axes The number of touch valuator axes.
1577 InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
1578 unsigned int mode, unsigned int num_axes)
1580 TouchClassPtr touch;
1583 if (device->touch || !device->valuator)
1586 /* Check the mode is valid, and at least X and Y axes. */
1587 if (mode != XIDirectTouch && mode != XIDependentTouch)
1592 if (num_axes > MAX_VALUATORS) {
1593 LogMessage(X_WARNING,
1594 "Device '%s' has %d touch axes, only using first %d.\n",
1595 device->name, num_axes, MAX_VALUATORS);
1596 num_axes = MAX_VALUATORS;
1599 touch = calloc(1, sizeof(*touch));
1603 touch->max_touches = max_touches;
1604 if (max_touches == 0)
1605 max_touches = 5; /* arbitrary number plucked out of the air */
1606 touch->touches = calloc(max_touches, sizeof(*touch->touches));
1607 if (!touch->touches)
1609 touch->num_touches = max_touches;
1610 for (i = 0; i < max_touches; i++)
1611 TouchInitTouchPoint(touch, device->valuator, i);
1614 touch->sourceid = device->id;
1616 device->touch = touch;
1617 device->last.touches = calloc(max_touches, sizeof(*device->last.touches));
1618 device->last.num_touches = touch->num_touches;
1619 for (i = 0; i < touch->num_touches; i++)
1620 TouchInitDDXTouchPoint(device, &device->last.touches[i]);
1625 for (i = 0; i < touch->num_touches; i++)
1626 TouchFreeTouchPoint(device, i);
1628 free(touch->touches);
1635 * Check if the given buffer contains elements between low (inclusive) and
1636 * high (inclusive) only.
1638 * @return TRUE if the device map is invalid, FALSE otherwise.
1641 BadDeviceMap(BYTE * buff, int length, unsigned low, unsigned high, XID *errval)
1645 for (i = 0; i < length; i++)
1646 if (buff[i]) { /* only check non-zero elements */
1647 if ((low > buff[i]) || (high < buff[i])) {
1656 ProcSetModifierMapping(ClientPtr client)
1658 xSetModifierMappingReply rep;
1661 REQUEST(xSetModifierMappingReq);
1662 REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
1664 if (client->req_len != ((stuff->numKeyPerModifier << 1) +
1665 bytes_to_int32(sizeof(xSetModifierMappingReq))))
1668 rep = (xSetModifierMappingReply) {
1670 .sequenceNumber = client->sequence,
1674 rc = change_modmap(client, PickKeyboard(client), (KeyCode *) &stuff[1],
1675 stuff->numKeyPerModifier);
1676 if (rc == MappingFailed || rc == -1)
1678 if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
1684 WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
1689 ProcGetModifierMapping(ClientPtr client)
1691 xGetModifierMappingReply rep;
1692 int max_keys_per_mod = 0;
1693 KeyCode *modkeymap = NULL;
1695 REQUEST_SIZE_MATCH(xReq);
1697 generate_modkeymap(client, PickKeyboard(client), &modkeymap,
1700 rep = (xGetModifierMappingReply) {
1702 .numKeyPerModifier = max_keys_per_mod,
1703 .sequenceNumber = client->sequence,
1704 /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1705 .length = max_keys_per_mod << 1
1708 WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
1709 WriteToClient(client, max_keys_per_mod * 8, modkeymap);
1717 ProcChangeKeyboardMapping(ClientPtr client)
1719 REQUEST(xChangeKeyboardMappingReq);
1722 DeviceIntPtr pDev, tmp;
1725 REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
1727 len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
1728 if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
1731 pDev = PickKeyboard(client);
1733 if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
1734 (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
1735 client->errorValue = stuff->firstKeyCode;
1739 if (((unsigned) (stuff->firstKeyCode + stuff->keyCodes - 1) >
1740 pDev->key->xkbInfo->desc->max_key_code) ||
1741 (stuff->keySymsPerKeyCode == 0)) {
1742 client->errorValue = stuff->keySymsPerKeyCode;
1746 keysyms.minKeyCode = stuff->firstKeyCode;
1747 keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
1748 keysyms.mapWidth = stuff->keySymsPerKeyCode;
1749 keysyms.map = (KeySym *) &stuff[1];
1751 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1755 XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
1756 stuff->keyCodes, NULL, client);
1758 for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
1759 if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev)
1764 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1768 XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
1769 stuff->keyCodes, NULL, client);
1776 ProcSetPointerMapping(ClientPtr client)
1781 DeviceIntPtr ptr = PickPointer(client);
1782 xSetPointerMappingReply rep;
1784 REQUEST(xSetPointerMappingReq);
1785 REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
1787 if (client->req_len !=
1788 bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
1791 rep = (xSetPointerMappingReply) {
1793 .success = MappingSuccess,
1794 .sequenceNumber = client->sequence,
1797 map = (BYTE *) &stuff[1];
1799 /* So we're bounded here by the number of core buttons. This check
1800 * probably wants disabling through XFixes. */
1801 /* MPX: With ClientPointer, we can return the right number of buttons.
1802 * Let's just hope nobody changed ClientPointer between GetPointerMapping
1803 * and SetPointerMapping
1805 if (stuff->nElts != ptr->button->numButtons) {
1806 client->errorValue = stuff->nElts;
1810 /* Core protocol specs don't allow for duplicate mappings; this check
1811 * almost certainly wants disabling through XFixes too. */
1812 for (i = 0; i < stuff->nElts; i++) {
1813 for (j = i + 1; j < stuff->nElts; j++) {
1814 if (map[i] && map[i] == map[j]) {
1815 client->errorValue = map[i];
1821 ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
1822 if (ret == MappingBusy)
1826 else if (ret != Success)
1829 WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
1834 ProcGetKeyboardMapping(ClientPtr client)
1836 xGetKeyboardMappingReply rep;
1837 DeviceIntPtr kbd = PickKeyboard(client);
1842 REQUEST(xGetKeyboardMappingReq);
1843 REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
1845 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
1849 xkb = kbd->key->xkbInfo->desc;
1851 if ((stuff->firstKeyCode < xkb->min_key_code) ||
1852 (stuff->firstKeyCode > xkb->max_key_code)) {
1853 client->errorValue = stuff->firstKeyCode;
1856 if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
1857 client->errorValue = stuff->count;
1861 syms = XkbGetCoreMap(kbd);
1865 rep = (xGetKeyboardMappingReply) {
1867 .keySymsPerKeyCode = syms->mapWidth,
1868 .sequenceNumber = client->sequence,
1869 /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
1870 .length = syms->mapWidth * stuff->count
1872 WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
1873 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
1874 WriteSwappedDataToClient(client,
1875 syms->mapWidth * stuff->count * sizeof(KeySym),
1876 &syms->map[syms->mapWidth * (stuff->firstKeyCode -
1877 syms->minKeyCode)]);
1885 ProcGetPointerMapping(ClientPtr client)
1887 xGetPointerMappingReply rep;
1889 /* Apps may get different values each time they call GetPointerMapping as
1890 * the ClientPointer could change. */
1891 DeviceIntPtr ptr = PickPointer(client);
1892 ButtonClassPtr butc = ptr->button;
1896 REQUEST_SIZE_MATCH(xReq);
1898 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
1902 nElts = (butc) ? butc->numButtons : 0;
1903 rep = (xGetPointerMappingReply) {
1906 .sequenceNumber = client->sequence,
1907 .length = ((unsigned) nElts + (4 - 1)) / 4
1909 WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
1911 WriteToClient(client, nElts, &butc->map[1]);
1916 NoteLedState(DeviceIntPtr keybd, int led, Bool on)
1918 KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
1921 ctrl->leds |= ((Leds) 1 << (led - 1));
1923 ctrl->leds &= ~((Leds) 1 << (led - 1));
1927 Ones(unsigned long mask)
1931 y = (mask >> 1) & 033333333333;
1932 y = mask - y - ((y >> 1) & 033333333333);
1933 return (((y + (y >> 3)) & 030707070707) % 077);
1937 DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist,
1946 int mask = vmask, i;
1947 XkbEventCauseRec cause;
1949 ctrl = keybd->kbdfeed->ctrl;
1951 index2 = (BITS32) lowbit(vmask);
1954 case KBKeyClickPercent:
1958 t = defaultKeyboardControl.click;
1960 else if (t < 0 || t > 100) {
1961 client->errorValue = t;
1970 t = defaultKeyboardControl.bell;
1972 else if (t < 0 || t > 100) {
1973 client->errorValue = t;
1982 t = defaultKeyboardControl.bell_pitch;
1985 client->errorValue = t;
1988 ctrl.bell_pitch = t;
1990 case KBBellDuration:
1994 t = defaultKeyboardControl.bell_duration;
1996 client->errorValue = t;
1999 ctrl.bell_duration = t;
2002 led = (CARD8) *vlist;
2004 if (led < 1 || led > 32) {
2005 client->errorValue = led;
2008 if (!(mask & KBLedMode))
2014 if (t == LedModeOff) {
2018 ctrl.leds &= ~(((Leds) (1)) << (led - 1));
2020 else if (t == LedModeOn) {
2024 ctrl.leds |= (((Leds) (1)) << (led - 1));
2027 client->errorValue = t;
2031 XkbSetCauseCoreReq(&cause, X_ChangeKeyboardControl, client);
2032 XkbSetIndicators(keybd, ((led == DO_ALL) ? ~0L : (1L << (led - 1))),
2034 ctrl.leds = keybd->kbdfeed->ctrl.leds;
2038 key = (KeyCode) *vlist;
2040 if ((KeyCode) key < keybd->key->xkbInfo->desc->min_key_code ||
2041 (KeyCode) key > keybd->key->xkbInfo->desc->max_key_code) {
2042 client->errorValue = key;
2045 if (!(mask & KBAutoRepeatMode))
2048 case KBAutoRepeatMode:
2050 mask = (1 << (key & 7));
2054 XkbDisableComputedAutoRepeats(keybd, key);
2055 if (t == AutoRepeatModeOff) {
2057 ctrl.autoRepeat = FALSE;
2059 ctrl.autoRepeats[i] &= ~mask;
2061 else if (t == AutoRepeatModeOn) {
2063 ctrl.autoRepeat = TRUE;
2065 ctrl.autoRepeats[i] |= mask;
2067 else if (t == AutoRepeatModeDefault) {
2069 ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
2071 ctrl.autoRepeats[i] =
2072 (ctrl.autoRepeats[i] & ~mask) |
2073 (defaultKeyboardControl.autoRepeats[i] & mask);
2076 client->errorValue = t;
2081 client->errorValue = mask;
2085 keybd->kbdfeed->ctrl = ctrl;
2087 /* The XKB RepeatKeys control and core protocol global autorepeat */
2088 /* value are linked */
2089 XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
2097 * Changes kbd control on the ClientPointer and all attached SDs.
2100 ProcChangeKeyboardControl(ClientPtr client)
2104 int ret = Success, error = Success;
2105 DeviceIntPtr pDev = NULL, keyboard;
2107 REQUEST(xChangeKeyboardControlReq);
2109 REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
2111 vmask = stuff->mask;
2112 vlist = (XID *) &stuff[1];
2114 if (client->req_len !=
2115 (sizeof(xChangeKeyboardControlReq) >> 2) + Ones(vmask))
2118 keyboard = PickKeyboard(client);
2120 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2121 if ((pDev == keyboard ||
2122 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2123 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2124 ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
2130 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2131 if ((pDev == keyboard ||
2132 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2133 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2134 ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
2144 ProcGetKeyboardControl(ClientPtr client)
2147 DeviceIntPtr kbd = PickKeyboard(client);
2148 KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
2149 xGetKeyboardControlReply rep;
2151 REQUEST_SIZE_MATCH(xReq);
2153 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
2157 rep = (xGetKeyboardControlReply) {
2159 .globalAutoRepeat = ctrl->autoRepeat,
2160 .sequenceNumber = client->sequence,
2162 .ledMask = ctrl->leds,
2163 .keyClickPercent = ctrl->click,
2164 .bellPercent = ctrl->bell,
2165 .bellPitch = ctrl->bell_pitch,
2166 .bellDuration = ctrl->bell_duration
2168 for (i = 0; i < 32; i++)
2169 rep.map[i] = ctrl->autoRepeats[i];
2170 WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
2175 ProcBell(ClientPtr client)
2177 DeviceIntPtr dev, keybd = PickKeyboard(client);
2178 int base = keybd->kbdfeed->ctrl.bell;
2183 REQUEST_SIZE_MATCH(xBellReq);
2185 if (stuff->percent < -100 || stuff->percent > 100) {
2186 client->errorValue = stuff->percent;
2190 newpercent = (base * stuff->percent) / 100;
2191 if (stuff->percent < 0)
2192 newpercent = base + newpercent;
2194 newpercent = base - newpercent + stuff->percent;
2196 for (dev = inputInfo.devices; dev; dev = dev->next) {
2197 if ((dev == keybd ||
2198 (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
2199 dev->kbdfeed && dev->kbdfeed->BellProc) {
2201 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
2204 XkbHandleBell(FALSE, FALSE, dev, newpercent,
2205 &dev->kbdfeed->ctrl, 0, None, NULL, client);
2213 ProcChangePointerControl(ClientPtr client)
2215 DeviceIntPtr dev, mouse = PickPointer(client);
2216 PtrCtrl ctrl; /* might get BadValue part way through */
2219 REQUEST(xChangePointerControlReq);
2220 REQUEST_SIZE_MATCH(xChangePointerControlReq);
2222 ctrl = mouse->ptrfeed->ctrl;
2223 if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
2224 client->errorValue = stuff->doAccel;
2227 if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
2228 client->errorValue = stuff->doThresh;
2231 if (stuff->doAccel) {
2232 if (stuff->accelNum == -1) {
2233 ctrl.num = defaultPointerControl.num;
2235 else if (stuff->accelNum < 0) {
2236 client->errorValue = stuff->accelNum;
2240 ctrl.num = stuff->accelNum;
2243 if (stuff->accelDenum == -1) {
2244 ctrl.den = defaultPointerControl.den;
2246 else if (stuff->accelDenum <= 0) {
2247 client->errorValue = stuff->accelDenum;
2251 ctrl.den = stuff->accelDenum;
2254 if (stuff->doThresh) {
2255 if (stuff->threshold == -1) {
2256 ctrl.threshold = defaultPointerControl.threshold;
2258 else if (stuff->threshold < 0) {
2259 client->errorValue = stuff->threshold;
2263 ctrl.threshold = stuff->threshold;
2267 for (dev = inputInfo.devices; dev; dev = dev->next) {
2268 if ((dev == mouse ||
2269 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2271 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
2277 for (dev = inputInfo.devices; dev; dev = dev->next) {
2278 if ((dev == mouse ||
2279 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2281 dev->ptrfeed->ctrl = ctrl;
2289 ProcGetPointerControl(ClientPtr client)
2291 DeviceIntPtr ptr = PickPointer(client);
2292 PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
2293 xGetPointerControlReply rep;
2296 REQUEST_SIZE_MATCH(xReq);
2298 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
2302 rep = (xGetPointerControlReply) {
2304 .sequenceNumber = client->sequence,
2306 .accelNumerator = ctrl->num,
2307 .accelDenominator = ctrl->den,
2308 .threshold = ctrl->threshold
2310 WriteReplyToClient(client, sizeof(xGenericReply), &rep);
2315 MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
2317 GrabPtr grab = dev->deviceGrab.grab;
2319 if ((grab && SameClient(grab, client) &&
2320 ((grab->eventMask & PointerMotionHintMask) ||
2321 (grab->ownerEvents &&
2322 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2323 PointerMotionHintMask)))) ||
2325 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2326 PointerMotionHintMask)))
2327 dev->valuator->motionHintWindow = NullWindow;
2331 ProcGetMotionEvents(ClientPtr client)
2334 xTimecoord *coords = (xTimecoord *) NULL;
2335 xGetMotionEventsReply rep;
2336 int i, count, xmin, xmax, ymin, ymax, rc;
2337 unsigned long nEvents;
2338 DeviceIntPtr mouse = PickPointer(client);
2339 TimeStamp start, stop;
2341 REQUEST(xGetMotionEventsReq);
2342 REQUEST_SIZE_MATCH(xGetMotionEventsReq);
2344 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2347 rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
2351 if (mouse->valuator->motionHintWindow)
2352 MaybeStopHint(mouse, client);
2353 rep = (xGetMotionEventsReply) {
2355 .sequenceNumber = client->sequence
2358 start = ClientTimeToServerTime(stuff->start);
2359 stop = ClientTimeToServerTime(stuff->stop);
2360 if ((CompareTimeStamps(start, stop) != LATER) &&
2361 (CompareTimeStamps(start, currentTime) != LATER) &&
2362 mouse->valuator->numMotionEvents) {
2363 if (CompareTimeStamps(stop, currentTime) == LATER)
2365 count = GetMotionHistory(mouse, &coords, start.milliseconds,
2366 stop.milliseconds, pWin->drawable.pScreen,
2368 xmin = pWin->drawable.x - wBorderWidth(pWin);
2369 xmax = pWin->drawable.x + (int) pWin->drawable.width +
2371 ymin = pWin->drawable.y - wBorderWidth(pWin);
2372 ymax = pWin->drawable.y + (int) pWin->drawable.height +
2374 for (i = 0; i < count; i++)
2375 if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
2376 (ymin <= coords[i].y) && (coords[i].y < ymax)) {
2377 coords[nEvents].time = coords[i].time;
2378 coords[nEvents].x = coords[i].x - pWin->drawable.x;
2379 coords[nEvents].y = coords[i].y - pWin->drawable.y;
2383 rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
2384 rep.nEvents = nEvents;
2385 WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
2387 client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
2388 WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
2396 ProcQueryKeymap(ClientPtr client)
2398 xQueryKeymapReply rep;
2400 DeviceIntPtr keybd = PickKeyboard(client);
2401 CARD8 *down = keybd->key->down;
2403 REQUEST_SIZE_MATCH(xReq);
2404 rep = (xQueryKeymapReply) {
2406 .sequenceNumber = client->sequence,
2410 rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
2411 /* If rc is Success, we're allowed to copy out the keymap.
2412 * If it's BadAccess, we leave it empty & lie to the client.
2414 if (rc == Success) {
2415 for (i = 0; i < 32; i++)
2416 rep.map[i] = down[i];
2418 else if (rc != BadAccess)
2421 WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
2427 * Recalculate the number of buttons for the master device. The number of
2428 * buttons on the master device is equal to the number of buttons on the
2429 * slave device with the highest number of buttons.
2432 RecalculateMasterButtons(DeviceIntPtr slave)
2434 DeviceIntPtr dev, master;
2437 if (!slave->button || IsMaster(slave))
2440 master = GetMaster(slave, MASTER_POINTER);
2444 for (dev = inputInfo.devices; dev; dev = dev->next) {
2445 if (IsMaster(dev) ||
2446 GetMaster(dev, MASTER_ATTACHED) != master || !dev->button)
2449 maxbuttons = max(maxbuttons, dev->button->numButtons);
2452 if (master->button && master->button->numButtons != maxbuttons) {
2454 DeviceChangedEvent event = {
2455 .header = ET_Internal,
2456 .type = ET_DeviceChanged,
2457 .time = GetTimeInMillis(),
2458 .deviceid = master->id,
2459 .flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE,
2460 .buttons.num_buttons = maxbuttons
2463 master->button->numButtons = maxbuttons;
2465 memcpy(&event.buttons.names, master->button->labels, maxbuttons *
2468 if (master->valuator) {
2469 event.num_valuators = master->valuator->numAxes;
2470 for (i = 0; i < event.num_valuators; i++) {
2471 event.valuators[i].min = master->valuator->axes[i].min_value;
2472 event.valuators[i].max = master->valuator->axes[i].max_value;
2473 event.valuators[i].resolution =
2474 master->valuator->axes[i].resolution;
2475 event.valuators[i].mode = master->valuator->axes[i].mode;
2476 event.valuators[i].name = master->valuator->axes[i].label;
2481 event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
2482 event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
2485 XISendDeviceChangedEvent(master, &event);
2490 * Generate release events for all keys/button currently down on this
2494 ReleaseButtonsAndKeys(DeviceIntPtr dev)
2496 InternalEvent *eventlist = InitEventList(GetMaximumEventsNum());
2497 ButtonClassPtr b = dev->button;
2498 KeyClassPtr k = dev->key;
2501 if (!eventlist) /* no release events for you */
2504 /* Release all buttons */
2505 for (i = 0; b && i < b->numButtons; i++) {
2506 if (BitIsOn(b->down, i)) {
2508 GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
2509 for (j = 0; j < nevents; j++)
2510 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2514 /* Release all keys */
2515 for (i = 0; k && i < MAP_LENGTH; i++) {
2516 if (BitIsOn(k->down, i)) {
2517 nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
2518 for (j = 0; j < nevents; j++)
2519 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2523 FreeEventList(eventlist, GetMaximumEventsNum());
2527 * Attach device 'dev' to device 'master'.
2528 * Client is set to the client that issued the request, or NULL if it comes
2529 * from some internal automatic pairing.
2531 * Master may be NULL to set the device floating.
2533 * We don't allow multi-layer hierarchies right now. You can't attach a slave
2537 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
2541 if (!dev || IsMaster(dev))
2544 if (master && !IsMaster(master)) /* can't attach to slaves */
2547 /* set from floating to floating? */
2548 if (IsFloating(dev) && !master && dev->enabled)
2551 /* free the existing sprite. */
2552 if (IsFloating(dev) && dev->spriteInfo->paired == dev) {
2553 screen = miPointerGetScreen(dev);
2554 screen->DeviceCursorCleanup(dev, screen);
2555 free(dev->spriteInfo->sprite);
2558 dev->master = master;
2560 /* If device is set to floating, we need to create a sprite for it,
2561 * otherwise things go bad. However, we don't want to render the cursor,
2562 * so we reset spriteOwner.
2563 * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
2564 * alloc new memory but overwrite the previous one.
2567 WindowPtr currentRoot;
2569 if (dev->spriteInfo->sprite)
2570 currentRoot = GetCurrentRootWindow(dev);
2571 else /* new device auto-set to floating */
2572 currentRoot = screenInfo.screens[0]->root;
2574 /* we need to init a fake sprite */
2575 screen = currentRoot->drawable.pScreen;
2576 screen->DeviceCursorInitialize(dev, screen);
2577 dev->spriteInfo->sprite = NULL;
2578 InitializeSprite(dev, currentRoot);
2579 dev->spriteInfo->spriteOwner = FALSE;
2580 dev->spriteInfo->paired = dev;
2583 dev->spriteInfo->sprite = master->spriteInfo->sprite;
2584 dev->spriteInfo->paired = master;
2585 dev->spriteInfo->spriteOwner = FALSE;
2587 RecalculateMasterButtons(master);
2590 /* XXX: in theory, the MD should change back to its old, original
2591 * classes when the last SD is detached. Thanks to the XTEST devices,
2592 * we'll always have an SD attached until the MD is removed.
2593 * So let's not worry about that.
2600 * Return the device paired with the given device or NULL.
2601 * Returns the device paired with the parent master if the given device is a
2605 GetPairedDevice(DeviceIntPtr dev)
2607 if (!IsMaster(dev) && !IsFloating(dev))
2608 dev = GetMaster(dev, MASTER_ATTACHED);
2610 return dev->spriteInfo->paired;
2614 * Returns the requested master for this device.
2615 * The return values are:
2616 * - MASTER_ATTACHED: the master for this device or NULL for a floating
2618 * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a
2620 * - MASTER_POINTER: the master keyboard for this device or NULL for a
2622 * - POINTER_OR_FLOAT: the master pointer for this device or the device for
2624 * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for
2627 * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED,
2628 * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT.
2629 * @return The requested master device
2632 GetMaster(DeviceIntPtr dev, int which)
2634 DeviceIntPtr master;
2639 master = dev->master;
2641 (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT))
2645 if (master && which != MASTER_ATTACHED) {
2646 if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) {
2647 if (master->type != MASTER_KEYBOARD)
2648 master = GetPairedDevice(master);
2651 if (master->type != MASTER_POINTER)
2652 master = GetPairedDevice(master);
2660 * Create a new device pair (== one pointer, one keyboard device).
2661 * Only allocates the devices, you will need to call ActivateDevice() and
2662 * EnableDevice() manually.
2663 * Either a master or a slave device can be created depending on
2664 * the value for master.
2667 AllocDevicePair(ClientPtr client, const char *name,
2669 DeviceIntPtr *keybd,
2670 DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master)
2672 DeviceIntPtr pointer;
2673 DeviceIntPtr keyboard;
2675 *ptr = *keybd = NULL;
2679 pointer = AddInputDevice(client, ptr_proc, TRUE);
2684 if (asprintf(&pointer->name, "%s pointer", name) == -1) {
2685 pointer->name = NULL;
2686 RemoveDevice(pointer, FALSE);
2691 pointer->public.processInputProc = ProcessOtherEvent;
2692 pointer->public.realInputProc = ProcessOtherEvent;
2693 XkbSetExtension(pointer, ProcessPointerEvent);
2694 pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
2695 pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
2696 pointer->coreEvents = TRUE;
2697 pointer->spriteInfo->spriteOwner = TRUE;
2699 pointer->lastSlave = NULL;
2700 pointer->last.slave = NULL;
2701 pointer->type = (master) ? MASTER_POINTER : SLAVE;
2703 keyboard = AddInputDevice(client, keybd_proc, TRUE);
2705 RemoveDevice(pointer, FALSE);
2710 if (asprintf(&keyboard->name, "%s keyboard", name) == -1) {
2711 keyboard->name = NULL;
2712 RemoveDevice(keyboard, FALSE);
2713 RemoveDevice(pointer, FALSE);
2718 keyboard->public.processInputProc = ProcessOtherEvent;
2719 keyboard->public.realInputProc = ProcessOtherEvent;
2720 XkbSetExtension(keyboard, ProcessKeyboardEvent);
2721 keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
2722 keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
2723 keyboard->coreEvents = TRUE;
2724 keyboard->spriteInfo->spriteOwner = FALSE;
2726 keyboard->lastSlave = NULL;
2727 keyboard->last.slave = NULL;
2728 keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
2730 /* The ClassesRec stores the device classes currently not used. */
2731 pointer->unused_classes = calloc(1, sizeof(ClassesRec));
2733 keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
2743 * Return Relative or Absolute for the device.
2746 valuator_get_mode(DeviceIntPtr dev, int axis)
2748 return (dev->valuator->axes[axis].mode & DeviceMode);
2752 * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
2753 * set the mode for all axes.
2756 valuator_set_mode(DeviceIntPtr dev, int axis, int mode)
2758 if (axis != VALUATOR_MODE_ALL_AXES)
2759 dev->valuator->axes[axis].mode = mode;
2763 for (i = 0; i < dev->valuator->numAxes; i++)
2764 dev->valuator->axes[i].mode = mode;