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_data)
98 struct pixman_f_transform scale;
99 struct pixman_f_transform transform;
104 * calculate combined transformation matrix:
106 * M = InvScale * Transform * Scale
108 * So we can later transform points using M * p
111 * Scale scales coordinates into 0..1 range
112 * Transform is the user supplied (affine) transform
113 * InvScale scales coordinates back up into their native range
115 sx = dev->valuator->axes[0].max_value - dev->valuator->axes[0].min_value + 1;
116 sy = dev->valuator->axes[1].max_value - dev->valuator->axes[1].min_value + 1;
119 pixman_f_transform_init_scale(&scale, sx, sy);
120 scale.m[0][2] = dev->valuator->axes[0].min_value;
121 scale.m[1][2] = dev->valuator->axes[1].min_value;
124 for (y = 0; y < 3; y++)
125 for (x = 0; x < 3; x++)
126 transform.m[y][x] = *transform_data++;
128 pixman_f_transform_multiply(&dev->scale_and_transform, &scale, &transform);
131 pixman_f_transform_init_scale(&scale, 1.0 / sx, 1.0 / sy);
132 scale.m[0][2] = -dev->valuator->axes[0].min_value / sx;
133 scale.m[1][2] = -dev->valuator->axes[1].min_value / sy;
135 pixman_f_transform_multiply(&dev->scale_and_transform, &dev->scale_and_transform, &scale);
137 /* remove translation component for relative movements */
138 dev->relative_transform = transform;
139 dev->relative_transform.m[0][2] = 0;
140 dev->relative_transform.m[1][2] = 0;
144 * DIX property handler.
147 DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
150 if (property == XIGetKnownProperty(XI_PROP_ENABLED)) {
151 if (prop->format != 8 || prop->type != XA_INTEGER || prop->size != 1)
154 /* Don't allow disabling of VCP/VCK or XTest devices */
155 if ((dev == inputInfo.pointer ||
156 dev == inputInfo.keyboard ||
157 IsXTestDevice(dev, NULL))
158 &&!(*(CARD8 *) prop->data))
162 if ((*((CARD8 *) prop->data)) && !dev->enabled)
163 EnableDevice(dev, TRUE);
164 else if (!(*((CARD8 *) prop->data)) && dev->enabled)
165 DisableDevice(dev, TRUE);
168 else if (property == XIGetKnownProperty(XI_PROP_TRANSFORM)) {
169 float *f = (float *) prop->data;
172 if (prop->format != 32 || prop->size != 9 ||
173 prop->type != XIGetKnownProperty(XATOM_FLOAT))
176 for (i = 0; i < 9; i++)
181 DeviceSetTransform(dev, f);
187 /* Pair the keyboard to the pointer device. Keyboard events will follow the
188 * pointer sprite. Only applicable for master devices.
191 PairDevices(DeviceIntPtr ptr, DeviceIntPtr kbd)
196 /* Don't allow pairing for slave devices */
197 if (!IsMaster(ptr) || !IsMaster(kbd))
200 if (ptr->spriteInfo->paired)
203 if (kbd->spriteInfo->spriteOwner) {
204 free(kbd->spriteInfo->sprite);
205 kbd->spriteInfo->sprite = NULL;
206 kbd->spriteInfo->spriteOwner = FALSE;
209 kbd->spriteInfo->sprite = ptr->spriteInfo->sprite;
210 kbd->spriteInfo->paired = ptr;
211 ptr->spriteInfo->paired = kbd;
216 * Find and return the next unpaired MD pointer device.
219 NextFreePointerDevice(void)
223 for (dev = inputInfo.devices; dev; dev = dev->next)
225 dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired)
231 * Create a new input device and init it to sane values. The device is added
232 * to the server's off_devices list.
234 * @param deviceProc Callback for device control function (switch dev on/off).
235 * @return The newly created device.
238 AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
240 DeviceIntPtr dev, *prev; /* not a typo */
243 char devind[MAXDEVICES];
247 /* Find next available id, 0 and 1 are reserved */
248 memset(devind, 0, sizeof(char) * MAXDEVICES);
249 for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
250 devind[devtmp->id]++;
251 for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
252 devind[devtmp->id]++;
253 for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++);
255 if (devid >= MAXDEVICES)
256 return (DeviceIntPtr) NULL;
258 sizeof(DeviceIntRec) +
259 sizeof(SpriteInfoRec));
261 return (DeviceIntPtr) NULL;
263 if (!dixAllocatePrivates(&dev->devPrivates, PRIVATE_DEVICE)) {
269 return (DeviceIntPtr) NULL;
271 dev->last.scroll = NULL;
272 dev->last.touches = NULL;
274 dev->public.processInputProc = ProcessOtherEvent;
275 dev->public.realInputProc = ProcessOtherEvent;
276 dev->public.enqueueInputProc = EnqueueEvent;
277 dev->deviceProc = deviceProc;
278 dev->startup = autoStart;
280 /* device grab defaults */
281 dev->deviceGrab.grabTime = currentTime;
282 dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
283 dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
284 dev->deviceGrab.sync.event = calloc(1, sizeof(DeviceEvent));
286 XkbSetExtension(dev, ProcessKeyboardEvent);
288 dev->coreEvents = TRUE;
290 /* sprite defaults */
291 dev->spriteInfo = (SpriteInfoPtr) &dev[1];
293 /* security creation/labeling check
295 if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixCreateAccess)) {
296 dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
301 inputInfo.numDevices++;
303 for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next);
308 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
309 XA_INTEGER, 8, PropModeReplace, 1, &enabled, FALSE);
310 XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_ENABLED),
314 memset(transform, 0, sizeof(transform));
315 transform[0] = transform[4] = transform[8] = 1.0f;
316 dev->relative_transform.m[0][0] = 1.0;
317 dev->relative_transform.m[1][1] = 1.0;
318 dev->relative_transform.m[2][2] = 1.0;
319 dev->scale_and_transform = dev->relative_transform;
321 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
322 XIGetKnownProperty(XATOM_FLOAT), 32,
323 PropModeReplace, 9, transform, FALSE);
324 XISetDevicePropertyDeletable(dev, XIGetKnownProperty(XI_PROP_TRANSFORM),
327 XIRegisterPropertyHandler(dev, DeviceSetProperty, NULL, NULL);
333 SendDevicePresenceEvent(int deviceid, int type)
335 DeviceIntRec dummyDev = { .id = XIAllDevices };
336 devicePresenceNotify ev = {
337 .type = DevicePresenceNotify,
338 .time = currentTime.milliseconds,
343 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
348 * Enable the device through the driver, add the device to the device list.
349 * Switch device ON through the driver and push it onto the global device
350 * list. Initialize the DIX sprite or pair the device. All clients are
351 * notified about the device being enabled.
353 * A master pointer device needs to be enabled before a master keyboard
356 * @param The device to be enabled.
357 * @param sendevent True if an XI2 event should be sent.
358 * @return TRUE on success or FALSE otherwise.
361 EnableDevice(DeviceIntPtr dev, BOOL sendevent)
367 int flags[MAXDEVICES] = { 0 };
369 for (prev = &inputInfo.off_devices;
370 *prev && (*prev != dev); prev = &(*prev)->next);
372 if (!dev->spriteInfo->sprite) {
374 /* Sprites appear on first root window, so we can hardcode it */
375 if (dev->spriteInfo->spriteOwner) {
376 InitializeSprite(dev, screenInfo.screens[0]->root);
377 /* mode doesn't matter */
378 EnterWindow(dev, screenInfo.screens[0]->root, NotifyAncestor);
381 other = NextFreePointerDevice();
382 BUG_RETURN_VAL_MSG(other == NULL, FALSE,
383 "[dix] cannot find pointer to pair with.\n");
384 PairDevices(other, dev);
389 other = (IsPointerDevice(dev)) ? inputInfo.pointer:
392 other = NULL; /* auto-float non-core devices */
393 AttachDevice(NULL, dev, other);
397 if ((*prev != dev) || !dev->inited ||
398 ((ret = (*dev->deviceProc) (dev, DEVICE_ON)) != Success)) {
399 ErrorF("[dix] couldn't enable device %d\n", dev->id);
405 for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next);
410 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
411 XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE);
413 SendDevicePresenceEvent(dev->id, DeviceEnabled);
415 flags[dev->id] |= XIDeviceEnabled;
416 XISendDeviceHierarchyEvent(flags);
419 // IsFloating condition was brought from latest version at freedesktop xserver
420 if (!IsMaster(dev) && !IsFloating(dev))
421 XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
423 RecalculateMasterButtons(dev);
425 /* initialise an idle timer for this device*/
426 dev->idle_counter = SyncInitDeviceIdleTime(dev);
433 * Switch a device off through the driver and push it onto the off_devices
434 * list. A device will not send events while disabled. All clients are
435 * notified about the device being disabled.
437 * Master keyboard devices have to be disabled before master pointer devices
438 * otherwise things turn bad.
440 * @param sendevent True if an XI2 event should be sent.
441 * @return TRUE on success or FALSE otherwise.
444 DisableDevice(DeviceIntPtr dev, BOOL sendevent)
446 DeviceIntPtr *prev, other;
448 int flags[MAXDEVICES] = { 0 };
453 for (prev = &inputInfo.devices;
454 *prev && (*prev != dev); prev = &(*prev)->next);
458 TouchEndPhysicallyActiveTouches(dev);
459 ReleaseButtonsAndKeys(dev);
460 SyncRemoveDeviceIdleTime(dev->idle_counter);
461 dev->idle_counter = NULL;
463 /* float attached devices */
465 for (other = inputInfo.devices; other; other = other->next) {
466 if (!IsMaster(other) && GetMaster(other, MASTER_ATTACHED) == dev) {
467 AttachDevice(NULL, other, NULL);
468 flags[other->id] |= XISlaveDetached;
473 for (other = inputInfo.devices; other; other = other->next) {
474 if (IsMaster(other) && other->lastSlave == dev)
475 other->lastSlave = NULL;
479 if (IsMaster(dev) && dev->spriteInfo->sprite) {
480 for (other = inputInfo.devices; other; other = other->next)
481 if (other->spriteInfo->paired == dev && !other->spriteInfo->spriteOwner)
482 DisableDevice(other, sendevent);
485 if (dev->spriteInfo->paired)
486 dev->spriteInfo->paired = NULL;
488 (void) (*dev->deviceProc) (dev, DEVICE_OFF);
489 dev->enabled = FALSE;
493 /* now that the device is disabled, we can reset the signal handler's
496 for (other = inputInfo.devices; other; other = other->next) {
497 if (other->last.slave == dev)
498 other->last.slave = NULL;
506 dev->next = inputInfo.off_devices;
507 inputInfo.off_devices = dev;
510 XIChangeDeviceProperty(dev, XIGetKnownProperty(XI_PROP_ENABLED),
511 XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE);
513 SendDevicePresenceEvent(dev->id, DeviceDisabled);
515 flags[dev->id] = XIDeviceDisabled;
516 XISendDeviceHierarchyEvent(flags);
519 RecalculateMasterButtons(dev);
525 DisableAllDevices(void)
527 DeviceIntPtr dev, tmp;
529 /* Disable slave devices first, excluding XTest devices */
530 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
531 if (!IsXTestDevice(dev, NULL) && !IsMaster(dev))
532 DisableDevice(dev, FALSE);
534 /* Disable XTest devices */
535 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
537 DisableDevice(dev, FALSE);
539 /* master keyboards need to be disabled first */
540 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
541 if (dev->enabled && IsMaster(dev) && IsKeyboardDevice(dev))
542 DisableDevice(dev, FALSE);
544 nt_list_for_each_entry_safe(dev, tmp, inputInfo.devices, next) {
546 DisableDevice(dev, FALSE);
551 * Initialise a new device through the driver and tell all clients about the
554 * Must be called before EnableDevice.
555 * The device will NOT send events until it is enabled!
557 * @param sendevent True if an XI2 event should be sent.
558 * @return Success or an error code on failure.
561 ActivateDevice(DeviceIntPtr dev, BOOL sendevent)
564 ScreenPtr pScreen = screenInfo.screens[0];
566 if (!dev || !dev->deviceProc)
567 return BadImplementation;
569 ret = (*dev->deviceProc) (dev, DEVICE_INIT);
570 dev->inited = (ret == Success);
574 /* Initialize memory for sprites. */
575 if (IsMaster(dev) && dev->spriteInfo->spriteOwner)
576 if (!pScreen->DeviceCursorInitialize(dev, pScreen))
579 SendDevicePresenceEvent(dev->id, DeviceAdded);
581 int flags[MAXDEVICES] = { 0 };
582 flags[dev->id] = XISlaveAdded;
583 XISendDeviceHierarchyEvent(flags);
590 * The actual task of ringing the bell is the job of the DDX.
593 CoreKeyboardBell(int volume, DeviceIntPtr pDev, void *arg, int something)
595 KeybdCtrl *ctrl = arg;
597 DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
601 CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl * ctrl)
607 * Device control function for the Virtual Core Keyboard.
610 CoreKeyboardProc(DeviceIntPtr pDev, int what)
615 if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell,
617 ErrorF("Keyboard initialization failed. This could be a missing "
618 "or incorrect setup of xkeyboard-config.\n");
635 * Device control function for the Virtual Core Pointer.
638 CorePointerProc(DeviceIntPtr pDev, int what)
642 BYTE map[NBUTTONS + 1];
644 Atom btn_labels[NBUTTONS] = { 0 };
645 Atom axes_labels[NAXES] = { 0 };
646 ScreenPtr scr = screenInfo.screens[0];
650 for (i = 1; i <= NBUTTONS; i++)
653 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
654 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
655 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
656 btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
657 btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
658 btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
659 btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
660 /* don't know about the rest */
662 axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
663 axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
665 if (!InitPointerDeviceStruct
666 ((DevicePtr) pDev, map, NBUTTONS, btn_labels,
667 (PtrCtrlProcPtr) NoopDDA, GetMotionHistorySize(), NAXES,
669 ErrorF("Could not initialize device '%s'. Out of memory.\n",
671 return BadAlloc; /* IPDS only fails on allocs */
673 /* axisVal is per-screen, last.valuators is desktop-wide */
674 pDev->valuator->axisVal[0] = scr->width / 2;
675 pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x;
676 pDev->valuator->axisVal[1] = scr->height / 2;
677 pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y;
693 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
695 CoreTouchProc(DeviceIntPtr pDev, int what)
699 #define NAXES MAX_VALUATORS
701 Atom axes_labels[NAXES] = { 0 };
703 Atom btn_labels[NBUTTONS] = { 0 };
704 BYTE map[NBUTTONS + 1] = { 0 };
705 ScreenPtr scr = screenInfo.screens[0];
706 static char* abs_labels[] = {
707 AXIS_LABEL_PROP_ABS_X, /* 0x00 */
708 AXIS_LABEL_PROP_ABS_Y, /* 0x01 */
709 AXIS_LABEL_PROP_ABS_Z, /* 0x02 */
710 AXIS_LABEL_PROP_ABS_RX, /* 0x03 */
711 AXIS_LABEL_PROP_ABS_RY, /* 0x04 */
712 AXIS_LABEL_PROP_ABS_RZ, /* 0x05 */
713 AXIS_LABEL_PROP_ABS_THROTTLE, /* 0x06 */
714 AXIS_LABEL_PROP_ABS_RUDDER, /* 0x07 */
715 AXIS_LABEL_PROP_ABS_WHEEL, /* 0x08 */
716 AXIS_LABEL_PROP_ABS_GAS, /* 0x09 */
717 AXIS_LABEL_PROP_ABS_BRAKE, /* 0x0a */
718 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
719 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
720 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
721 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
722 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
723 AXIS_LABEL_PROP_ABS_HAT0X, /* 0x10 */
724 AXIS_LABEL_PROP_ABS_HAT0Y, /* 0x11 */
725 AXIS_LABEL_PROP_ABS_HAT1X, /* 0x12 */
726 AXIS_LABEL_PROP_ABS_HAT1Y, /* 0x13 */
727 AXIS_LABEL_PROP_ABS_HAT2X, /* 0x14 */
728 AXIS_LABEL_PROP_ABS_HAT2Y, /* 0x15 */
729 AXIS_LABEL_PROP_ABS_HAT3X, /* 0x16 */
730 AXIS_LABEL_PROP_ABS_HAT3Y, /* 0x17 */
731 AXIS_LABEL_PROP_ABS_PRESSURE, /* 0x18 */
732 AXIS_LABEL_PROP_ABS_DISTANCE, /* 0x19 */
733 AXIS_LABEL_PROP_ABS_TILT_X, /* 0x1a */
734 AXIS_LABEL_PROP_ABS_TILT_Y, /* 0x1b */
735 AXIS_LABEL_PROP_ABS_TOOL_WIDTH, /* 0x1c */
736 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
737 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
738 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
739 AXIS_LABEL_PROP_ABS_VOLUME /* 0x20 */
740 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
741 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
742 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
743 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
744 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
745 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
746 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
747 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
748 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
749 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
750 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
751 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
752 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
753 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
754 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
755 AXIS_LABEL_PROP_ABS_MISC, /* undefined */
756 AXIS_LABEL_PROP_ABS_MT_TOUCH_MAJOR, /* 0x30 */
757 AXIS_LABEL_PROP_ABS_MT_TOUCH_MINOR, /* 0x31 */
758 AXIS_LABEL_PROP_ABS_MT_WIDTH_MAJOR, /* 0x32 */
759 AXIS_LABEL_PROP_ABS_MT_WIDTH_MINOR, /* 0x33 */
760 AXIS_LABEL_PROP_ABS_MT_ORIENTATION, /* 0x34 */
761 AXIS_LABEL_PROP_ABS_MT_POSITION_X, /* 0x35 */
762 AXIS_LABEL_PROP_ABS_MT_POSITION_Y, /* 0x36 */
763 AXIS_LABEL_PROP_ABS_MT_TOOL_TYPE, /* 0x37 */
764 AXIS_LABEL_PROP_ABS_MT_BLOB_ID, /* 0x38 */
765 AXIS_LABEL_PROP_ABS_MT_TRACKING_ID, /* 0x39 */
766 AXIS_LABEL_PROP_ABS_MT_PRESSURE, /* 0x3a */
771 for (i = 1; i <= NBUTTONS; i++)
774 btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
775 btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
776 btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
777 btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
778 btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
779 btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
780 btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
782 for (i = 0; i < NAXES; i++) {
783 atom = XIGetKnownProperty(abs_labels[i]);
784 if (!atom) { /* Should not happen */
787 axes_labels[i] = atom;
790 if (!InitTouchDeviceStruct(pDev, MAX_VALUATORS, axes_labels,
791 GetMotionHistorySize(), Absolute, NTOUCHES, XIDirectTouch,
792 NBUTTONS, btn_labels, map)) {
793 ErrorF("[CoreTouchProc] Could not initialize touch device '%s'. Out of memory.\n",
798 /* axisVal is per-screen, last.valuators is desktop-wide */
799 pDev->valuator->axisVal[0] = scr->width / 2;
800 pDev->last.valuators[0] = pDev->valuator->axisVal[0] + scr->x;
801 pDev->valuator->axisVal[1] = scr->height / 2;
802 pDev->last.valuators[1] = pDev->valuator->axisVal[1] + scr->y;
818 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
821 * Initialise the two core devices, VCP and VCK (see events.c).
822 * Both devices are not tied to physical devices, but guarantee that there is
823 * always a keyboard and a pointer present and keep the protocol semantics.
825 * Note that the server MUST have two core devices at all times, even if there
826 * is no physical device connected.
829 InitCoreDevices(void)
831 if (AllocDevicePair(serverClient, "Virtual core",
832 &inputInfo.pointer, &inputInfo.keyboard,
833 CorePointerProc, CoreKeyboardProc, TRUE) != Success)
834 FatalError("Failed to allocate core devices");
836 if (ActivateDevice(inputInfo.pointer, TRUE) != Success ||
837 ActivateDevice(inputInfo.keyboard, TRUE) != Success)
838 FatalError("Failed to activate core devices.");
839 if (!EnableDevice(inputInfo.pointer, TRUE) ||
840 !EnableDevice(inputInfo.keyboard, TRUE))
841 FatalError("Failed to enable core devices.");
844 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
845 InitXTestHWKeyTouchDevices();
846 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
850 * Activate all switched-off devices and then enable all those devices.
852 * Will return an error if no core keyboard or core pointer is present.
853 * In theory this should never happen if you call InitCoreDevices() first.
855 * InitAndStartDevices needs to be called AFTER the windows are initialized.
856 * Devices will start sending events after InitAndStartDevices() has
859 * @return Success or error code on failure.
862 InitAndStartDevices(void)
864 DeviceIntPtr dev, next;
866 for (dev = inputInfo.off_devices; dev; dev = dev->next) {
867 DebugF("(dix) initialising device %d\n", dev->id);
869 ActivateDevice(dev, TRUE);
872 /* enable real devices */
873 for (dev = inputInfo.off_devices; dev; dev = next) {
874 DebugF("(dix) enabling device %d\n", dev->id);
876 if (dev->inited && dev->startup)
877 EnableDevice(dev, TRUE);
884 * Free the given device class and reset the pointer to NULL.
887 FreeDeviceClass(int type, void **class)
895 KeyClassPtr *k = (KeyClassPtr *) class;
898 XkbFreeInfo((*k)->xkbInfo);
899 (*k)->xkbInfo = NULL;
906 ButtonClassPtr *b = (ButtonClassPtr *) class;
908 free((*b)->xkb_acts);
914 ValuatorClassPtr *v = (ValuatorClassPtr *) class;
922 TouchClassPtr *t = (TouchClassPtr *) class;
925 for (i = 0; i < (*t)->num_touches; i++) {
926 free((*t)->touches[i].sprite.spriteTrace);
927 free((*t)->touches[i].listeners);
928 free((*t)->touches[i].valuators);
937 FocusClassPtr *f = (FocusClassPtr *) class;
945 ProximityClassPtr *p = (ProximityClassPtr *) class;
955 FreeFeedbackClass(int type, void **class)
961 case KbdFeedbackClass:
963 KbdFeedbackPtr *kbdfeed = (KbdFeedbackPtr *) class;
964 KbdFeedbackPtr k, knext;
966 for (k = (*kbdfeed); k; k = knext) {
969 XkbFreeSrvLedInfo(k->xkb_sli);
974 case PtrFeedbackClass:
976 PtrFeedbackPtr *ptrfeed = (PtrFeedbackPtr *) class;
977 PtrFeedbackPtr p, pnext;
979 for (p = (*ptrfeed); p; p = pnext) {
985 case IntegerFeedbackClass:
987 IntegerFeedbackPtr *intfeed = (IntegerFeedbackPtr *) class;
988 IntegerFeedbackPtr i, inext;
990 for (i = (*intfeed); i; i = inext) {
996 case StringFeedbackClass:
998 StringFeedbackPtr *stringfeed = (StringFeedbackPtr *) class;
999 StringFeedbackPtr s, snext;
1001 for (s = (*stringfeed); s; s = snext) {
1003 free(s->ctrl.symbols_supported);
1004 free(s->ctrl.symbols_displayed);
1009 case BellFeedbackClass:
1011 BellFeedbackPtr *bell = (BellFeedbackPtr *) class;
1012 BellFeedbackPtr b, bnext;
1014 for (b = (*bell); b; b = bnext) {
1020 case LedFeedbackClass:
1022 LedFeedbackPtr *leds = (LedFeedbackPtr *) class;
1023 LedFeedbackPtr l, lnext;
1025 for (l = (*leds); l; l = lnext) {
1028 XkbFreeSrvLedInfo(l->xkb_sli);
1038 FreeAllDeviceClasses(ClassesPtr classes)
1043 FreeDeviceClass(KeyClass, (void *) &classes->key);
1044 FreeDeviceClass(ValuatorClass, (void *) &classes->valuator);
1045 FreeDeviceClass(XITouchClass, (void *) &classes->touch);
1046 FreeDeviceClass(ButtonClass, (void *) &classes->button);
1047 FreeDeviceClass(FocusClass, (void *) &classes->focus);
1048 FreeDeviceClass(ProximityClass, (void *) &classes->proximity);
1050 FreeFeedbackClass(KbdFeedbackClass, (void *) &classes->kbdfeed);
1051 FreeFeedbackClass(PtrFeedbackClass, (void *) &classes->ptrfeed);
1052 FreeFeedbackClass(IntegerFeedbackClass, (void *) &classes->intfeed);
1053 FreeFeedbackClass(StringFeedbackClass, (void *) &classes->stringfeed);
1054 FreeFeedbackClass(BellFeedbackClass, (void *) &classes->bell);
1055 FreeFeedbackClass(LedFeedbackClass, (void *) &classes->leds);
1060 * Close down a device and free all resources.
1061 * Once closed down, the driver will probably not expect you that you'll ever
1062 * enable it again and free associated structs. If you want the device to just
1063 * be disabled, DisableDevice().
1064 * Don't call this function directly, use RemoveDevice() instead.
1067 CloseDevice(DeviceIntPtr dev)
1069 ScreenPtr screen = screenInfo.screens[0];
1076 XIDeleteAllDeviceProperties(dev);
1079 (void) (*dev->deviceProc) (dev, DEVICE_CLOSE);
1084 screen->DeviceCursorCleanup(dev, screen);
1086 /* free acceleration info */
1087 if (dev->valuator && dev->valuator->accelScheme.AccelCleanupProc)
1088 dev->valuator->accelScheme.AccelCleanupProc(dev);
1090 while (dev->xkb_interest)
1091 XkbRemoveResourceClient((DevicePtr) dev, dev->xkb_interest->resource);
1095 classes = (ClassesPtr) &dev->key;
1096 FreeAllDeviceClasses(classes);
1098 if (IsMaster(dev)) {
1099 classes = dev->unused_classes;
1100 FreeAllDeviceClasses(classes);
1104 /* a client may have the device set as client pointer */
1105 for (j = 0; j < currentMaxClients; j++) {
1106 if (clients[j] && clients[j]->clientPtr == dev) {
1107 clients[j]->clientPtr = NULL;
1108 clients[j]->clientPtr = PickPointer(clients[j]);
1112 if (dev->deviceGrab.grab)
1113 FreeGrab(dev->deviceGrab.grab);
1114 free(dev->deviceGrab.sync.event);
1115 free(dev->config_info); /* Allocated in xf86ActivateDevice. */
1116 free(dev->last.scroll);
1117 for (j = 0; j < dev->last.num_touches; j++)
1118 free(dev->last.touches[j].valuators);
1119 free(dev->last.touches);
1120 dev->config_info = NULL;
1121 dixFreePrivates(dev->devPrivates, PRIVATE_DEVICE);
1126 * Shut down all devices of one list and free all resources.
1130 CloseDeviceList(DeviceIntPtr *listHead)
1132 /* Used to mark devices that we tried to free */
1133 Bool freedIds[MAXDEVICES];
1137 if (listHead == NULL)
1140 for (i = 0; i < MAXDEVICES; i++)
1141 freedIds[i] = FALSE;
1144 while (dev != NULL) {
1145 freedIds[dev->id] = TRUE;
1146 DeleteInputDeviceRequest(dev);
1149 while (dev != NULL && freedIds[dev->id])
1155 * Shut down all devices, free all resources, etc.
1156 * Only useful if you're shutting down the server!
1159 CloseDownDevices(void)
1165 /* Float all SDs before closing them. Note that at this point resources
1166 * (e.g. cursors) have been freed already, so we can't just call
1167 * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
1168 * to NULL and pretend nothing happened.
1170 for (dev = inputInfo.devices; dev; dev = dev->next) {
1171 if (!IsMaster(dev) && !IsFloating(dev))
1175 CloseDeviceList(&inputInfo.devices);
1176 CloseDeviceList(&inputInfo.off_devices);
1178 CloseDevice(inputInfo.pointer);
1180 CloseDevice(inputInfo.keyboard);
1182 inputInfo.devices = NULL;
1183 inputInfo.off_devices = NULL;
1184 inputInfo.keyboard = NULL;
1185 inputInfo.pointer = NULL;
1187 XkbDeleteRulesDflts();
1188 XkbDeleteRulesUsed();
1194 * Signal all devices that we're in the process of aborting.
1195 * This function is called from a signal handler.
1201 nt_list_for_each_entry(dev, inputInfo.devices, next) {
1203 (*dev->deviceProc) (dev, DEVICE_ABORT);
1206 nt_list_for_each_entry(dev, inputInfo.off_devices, next) {
1208 (*dev->deviceProc) (dev, DEVICE_ABORT);
1213 * Remove the cursor sprite for all devices. This needs to be done before any
1214 * resources are freed or any device is deleted.
1217 UndisplayDevices(void)
1220 ScreenPtr screen = screenInfo.screens[0];
1222 for (dev = inputInfo.devices; dev; dev = dev->next)
1223 screen->DisplayCursor(dev, screen, NullCursor);
1227 * Remove a device from the device list, closes it and thus frees all
1229 * Removes both enabled and disabled devices and notifies all devices about
1230 * the removal of the device.
1232 * No PresenceNotify is sent for device that the client never saw. This can
1233 * happen if a malloc fails during the addition of master devices. If
1234 * dev->init is FALSE it means the client never received a DeviceAdded event,
1235 * so let's not send a DeviceRemoved event either.
1237 * @param sendevent True if an XI2 event should be sent.
1240 RemoveDevice(DeviceIntPtr dev, BOOL sendevent)
1242 DeviceIntPtr prev, tmp, next;
1244 ScreenPtr screen = screenInfo.screens[0];
1247 int flags[MAXDEVICES] = { 0 };
1249 DebugF("(dix) removing device %d\n", dev->id);
1251 if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
1252 return BadImplementation;
1254 initialized = dev->inited;
1258 if (DevHasCursor(dev))
1259 screen->DisplayCursor(dev, screen, NullCursor);
1261 DisableDevice(dev, sendevent);
1262 flags[dev->id] = XIDeviceDisabled;
1266 for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
1271 inputInfo.devices = next;
1275 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1282 for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
1285 flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved;
1289 inputInfo.off_devices = next;
1297 if (ret == Success && initialized) {
1298 inputInfo.numDevices--;
1299 SendDevicePresenceEvent(deviceid, DeviceRemoved);
1301 XISendDeviceHierarchyEvent(flags);
1308 NumMotionEvents(void)
1310 /* only called to fill data in initial connection reply.
1311 * VCP is ok here, it is the only fixed device we have. */
1312 return inputInfo.pointer->valuator->numMotionEvents;
1316 dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode)
1323 for (dev = inputInfo.devices; dev; dev = dev->next) {
1327 for (dev = inputInfo.off_devices; dev; dev = dev->next) {
1334 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
1341 QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
1343 if (inputInfo.keyboard) {
1344 *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code;
1345 *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code;
1349 /* Notably, this function does not expand the destination's keycode range, or
1350 * notify clients. */
1352 SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
1356 int rowDif = src->minKeyCode - dst->minKeyCode;
1358 /* if keysym map size changes, grow map first */
1359 if (src->mapWidth < dst->mapWidth) {
1360 for (i = src->minKeyCode; i <= src->maxKeyCode; i++) {
1361 #define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
1362 #define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
1363 for (j = 0; j < src->mapWidth; j++)
1364 dst->map[DI(i, j)] = src->map[SI(i, j)];
1365 for (j = src->mapWidth; j < dst->mapWidth; j++)
1366 dst->map[DI(i, j)] = NoSymbol;
1372 else if (src->mapWidth > dst->mapWidth) {
1373 i = sizeof(KeySym) * src->mapWidth *
1374 (dst->maxKeyCode - dst->minKeyCode + 1);
1375 tmp = calloc(sizeof(KeySym), i);
1380 for (i = 0; i <= dst->maxKeyCode - dst->minKeyCode; i++)
1381 memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth],
1382 dst->mapWidth * sizeof(KeySym));
1385 dst->mapWidth = src->mapWidth;
1388 else if (!dst->map) {
1389 i = sizeof(KeySym) * src->mapWidth *
1390 (dst->maxKeyCode - dst->minKeyCode + 1);
1391 tmp = calloc(sizeof(KeySym), i);
1396 dst->mapWidth = src->mapWidth;
1399 memmove(&dst->map[rowDif * dst->mapWidth], src->map,
1400 (src->maxKeyCode - src->minKeyCode + 1) *
1401 dst->mapWidth * sizeof(KeySym));
1407 InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom *labels,
1410 ButtonClassPtr butc;
1413 BUG_RETURN_VAL(dev == NULL, FALSE);
1414 BUG_RETURN_VAL(dev->button != NULL, FALSE);
1415 BUG_RETURN_VAL(numButtons >= MAX_BUTTONS, FALSE);
1417 butc = calloc(1, sizeof(ButtonClassRec));
1420 butc->numButtons = numButtons;
1421 butc->sourceid = dev->id;
1422 for (i = 1; i <= numButtons; i++)
1423 butc->map[i] = map[i];
1424 for (i = numButtons + 1; i < MAP_LENGTH; i++)
1426 memcpy(butc->labels, labels, numButtons * sizeof(Atom));
1432 * Allocate a valuator class and set up the pointers for the axis values
1435 * @param src If non-NULL, the memory is reallocated from src. If NULL, the
1436 * memory is calloc'd.
1437 * @parma numAxes Number of axes to allocate.
1438 * @return The allocated valuator struct.
1441 AllocValuatorClass(ValuatorClassPtr src, int numAxes)
1445 /* force alignment with double */
1447 ValuatorClassRec valc;
1453 sizeof(union align_u) + numAxes * (sizeof(double) + sizeof(AxisInfo));
1454 align = (union align_u *) realloc(src, size);
1460 memset(align, 0, size);
1463 v->numAxes = numAxes;
1464 v->axisVal = (double *) (align + 1);
1465 v->axes = (AxisInfoPtr) (v->axisVal + numAxes);
1471 InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels,
1472 int numMotionEvents, int mode)
1475 ValuatorClassPtr valc;
1477 BUG_RETURN_VAL(dev == NULL, FALSE);
1479 if (numAxes > MAX_VALUATORS) {
1480 LogMessage(X_WARNING,
1481 "Device '%s' has %d axes, only using first %d.\n",
1482 dev->name, numAxes, MAX_VALUATORS);
1483 numAxes = MAX_VALUATORS;
1486 valc = AllocValuatorClass(NULL, numAxes);
1490 dev->last.scroll = valuator_mask_new(numAxes);
1491 if (!dev->last.scroll) {
1496 valc->sourceid = dev->id;
1497 valc->motion = NULL;
1498 valc->first_motion = 0;
1499 valc->last_motion = 0;
1500 valc->h_scroll_axis = -1;
1501 valc->v_scroll_axis = -1;
1503 valc->numMotionEvents = numMotionEvents;
1504 valc->motionHintWindow = NullWindow;
1506 if ((mode & OutOfProximity) && !dev->proximity)
1507 InitProximityClassDeviceStruct(dev);
1509 dev->valuator = valc;
1511 AllocateMotionHistory(dev);
1513 for (i = 0; i < numAxes; i++) {
1514 InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS,
1515 NO_AXIS_LIMITS, 0, 0, 0, mode);
1516 valc->axisVal[i] = 0;
1519 dev->last.numValuators = numAxes;
1521 if (IsMaster(dev) || /* do not accelerate master or xtest devices */
1522 IsXTestDevice(dev, NULL))
1523 InitPointerAccelerationScheme(dev, PtrAccelNoOp);
1525 InitPointerAccelerationScheme(dev, PtrAccelDefault);
1529 /* global list of acceleration schemes */
1530 ValuatorAccelerationRec pointerAccelerationScheme[] = {
1531 {PtrAccelNoOp, NULL, NULL, NULL, NULL},
1532 {PtrAccelPredictable, acceleratePointerPredictable, NULL,
1533 InitPredictableAccelerationScheme, AccelerationDefaultCleanup},
1534 {PtrAccelLightweight, acceleratePointerLightweight, NULL, NULL, NULL},
1535 {-1, NULL, NULL, NULL, NULL} /* terminator */
1539 * install an acceleration scheme. returns TRUE on success, and should not
1540 * change anything if unsuccessful.
1543 InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme)
1546 ValuatorClassPtr val;
1548 val = dev->valuator;
1553 if (IsMaster(dev) && scheme != PtrAccelNoOp)
1556 for (x = 0; pointerAccelerationScheme[x].number >= 0; x++) {
1557 if (pointerAccelerationScheme[x].number == scheme) {
1566 if (val->accelScheme.AccelCleanupProc)
1567 val->accelScheme.AccelCleanupProc(dev);
1569 if (pointerAccelerationScheme[i].AccelInitProc) {
1570 if (!pointerAccelerationScheme[i].AccelInitProc(dev,
1571 &pointerAccelerationScheme[i])) {
1576 val->accelScheme = pointerAccelerationScheme[i];
1582 InitFocusClassDeviceStruct(DeviceIntPtr dev)
1586 BUG_RETURN_VAL(dev == NULL, FALSE);
1587 BUG_RETURN_VAL(dev->focus != NULL, FALSE);
1589 focc = malloc(sizeof(FocusClassRec));
1592 focc->win = PointerRootWin;
1593 focc->revert = None;
1594 focc->time = currentTime;
1595 focc->trace = (WindowPtr *) NULL;
1596 focc->traceSize = 0;
1597 focc->traceGood = 0;
1598 focc->sourceid = dev->id;
1604 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
1606 PtrFeedbackPtr feedc;
1608 BUG_RETURN_VAL(dev == NULL, FALSE);
1610 feedc = malloc(sizeof(PtrFeedbackClassRec));
1613 feedc->CtrlProc = controlProc;
1614 feedc->ctrl = defaultPointerControl;
1616 if ((feedc->next = dev->ptrfeed))
1617 feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
1618 dev->ptrfeed = feedc;
1619 (*controlProc) (dev, &feedc->ctrl);
1623 static LedCtrl defaultLedControl = {
1624 DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0
1627 static BellCtrl defaultBellControl = {
1630 DEFAULT_BELL_DURATION,
1634 static IntegerCtrl defaultIntegerControl = {
1635 DEFAULT_INT_RESOLUTION,
1636 DEFAULT_INT_MIN_VALUE,
1637 DEFAULT_INT_MAX_VALUE,
1638 DEFAULT_INT_DISPLAYED,
1643 InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev,
1644 StringCtrlProcPtr controlProc,
1645 int max_symbols, int num_symbols_supported,
1649 StringFeedbackPtr feedc;
1651 BUG_RETURN_VAL(dev == NULL, FALSE);
1653 feedc = malloc(sizeof(StringFeedbackClassRec));
1656 feedc->CtrlProc = controlProc;
1657 feedc->ctrl.num_symbols_supported = num_symbols_supported;
1658 feedc->ctrl.num_symbols_displayed = 0;
1659 feedc->ctrl.max_symbols = max_symbols;
1660 feedc->ctrl.symbols_supported =
1661 malloc(sizeof(KeySym) * num_symbols_supported);
1662 feedc->ctrl.symbols_displayed = malloc(sizeof(KeySym) * max_symbols);
1663 if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) {
1664 free(feedc->ctrl.symbols_supported);
1665 free(feedc->ctrl.symbols_displayed);
1669 for (i = 0; i < num_symbols_supported; i++)
1670 *(feedc->ctrl.symbols_supported + i) = *symbols++;
1671 for (i = 0; i < max_symbols; i++)
1672 *(feedc->ctrl.symbols_displayed + i) = (KeySym) 0;
1674 if ((feedc->next = dev->stringfeed))
1675 feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
1676 dev->stringfeed = feedc;
1677 (*controlProc) (dev, &feedc->ctrl);
1682 InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
1683 BellCtrlProcPtr controlProc)
1685 BellFeedbackPtr feedc;
1687 BUG_RETURN_VAL(dev == NULL, FALSE);
1689 feedc = malloc(sizeof(BellFeedbackClassRec));
1692 feedc->CtrlProc = controlProc;
1693 feedc->BellProc = bellProc;
1694 feedc->ctrl = defaultBellControl;
1696 if ((feedc->next = dev->bell))
1697 feedc->ctrl.id = dev->bell->ctrl.id + 1;
1699 (*controlProc) (dev, &feedc->ctrl);
1704 InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev, LedCtrlProcPtr controlProc)
1706 LedFeedbackPtr feedc;
1708 BUG_RETURN_VAL(dev == NULL, FALSE);
1710 feedc = malloc(sizeof(LedFeedbackClassRec));
1713 feedc->CtrlProc = controlProc;
1714 feedc->ctrl = defaultLedControl;
1716 if ((feedc->next = dev->leds))
1717 feedc->ctrl.id = dev->leds->ctrl.id + 1;
1718 feedc->xkb_sli = NULL;
1720 (*controlProc) (dev, &feedc->ctrl);
1725 InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev,
1726 IntegerCtrlProcPtr controlProc)
1728 IntegerFeedbackPtr feedc;
1730 BUG_RETURN_VAL(dev == NULL, FALSE);
1732 feedc = malloc(sizeof(IntegerFeedbackClassRec));
1735 feedc->CtrlProc = controlProc;
1736 feedc->ctrl = defaultIntegerControl;
1738 if ((feedc->next = dev->intfeed))
1739 feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
1740 dev->intfeed = feedc;
1741 (*controlProc) (dev, &feedc->ctrl);
1746 InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
1747 Atom *btn_labels, PtrCtrlProcPtr controlProc,
1748 int numMotionEvents, int numAxes, Atom *axes_labels)
1750 DeviceIntPtr dev = (DeviceIntPtr) device;
1752 BUG_RETURN_VAL(dev == NULL, FALSE);
1753 BUG_RETURN_VAL(dev->button != NULL, FALSE);
1754 BUG_RETURN_VAL(dev->valuator != NULL, FALSE);
1755 BUG_RETURN_VAL(dev->ptrfeed != NULL, FALSE);
1757 return (InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) &&
1758 InitValuatorClassDeviceStruct(dev, numAxes, axes_labels,
1759 numMotionEvents, Relative) &&
1760 InitPtrFeedbackClassDeviceStruct(dev, controlProc));
1763 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
1765 InitTouchDeviceStruct(DeviceIntPtr device, int numAxes,
1766 Atom *axes_labels, int numMotionEvents, int valuatormode, int numTouches,
1767 unsigned int touchMode, int numButtons, Atom *btn_labels, CARD8 *map)
1769 BUG_RETURN_VAL(device == NULL, FALSE);
1770 BUG_RETURN_VAL(device->button != NULL, FALSE);
1771 BUG_RETURN_VAL(device->valuator != NULL, FALSE);
1772 BUG_RETURN_VAL(device->ptrfeed != NULL, FALSE);
1774 return (InitValuatorClassDeviceStruct(device, numAxes, axes_labels,
1775 numMotionEvents, valuatormode) &&
1776 InitTouchClassDeviceStruct(device, numTouches, touchMode, numAxes) &&
1777 InitButtonClassDeviceStruct(device, numButtons, btn_labels, map));
1779 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
1783 * Sets up multitouch capabilities on @device.
1785 * @max_touches The maximum number of simultaneous touches, or 0 for unlimited.
1786 * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch).
1787 * @num_axes The number of touch valuator axes.
1790 InitTouchClassDeviceStruct(DeviceIntPtr device, unsigned int max_touches,
1791 unsigned int mode, unsigned int num_axes)
1793 TouchClassPtr touch;
1796 BUG_RETURN_VAL(device == NULL, FALSE);
1797 BUG_RETURN_VAL(device->touch != NULL, FALSE);
1798 BUG_RETURN_VAL(device->valuator == NULL, FALSE);
1800 /* Check the mode is valid, and at least X and Y axes. */
1801 BUG_RETURN_VAL(mode != XIDirectTouch && mode != XIDependentTouch, FALSE);
1802 BUG_RETURN_VAL(num_axes < 2, FALSE);
1804 if (num_axes > MAX_VALUATORS) {
1805 LogMessage(X_WARNING,
1806 "Device '%s' has %d touch axes, only using first %d.\n",
1807 device->name, num_axes, MAX_VALUATORS);
1808 num_axes = MAX_VALUATORS;
1811 touch = calloc(1, sizeof(*touch));
1815 touch->max_touches = max_touches;
1816 if (max_touches == 0)
1817 max_touches = 5; /* arbitrary number plucked out of the air */
1818 touch->touches = calloc(max_touches, sizeof(*touch->touches));
1819 if (!touch->touches)
1821 touch->num_touches = max_touches;
1822 for (i = 0; i < max_touches; i++)
1823 TouchInitTouchPoint(touch, device->valuator, i);
1826 touch->sourceid = device->id;
1828 device->touch = touch;
1829 device->last.touches = calloc(max_touches, sizeof(*device->last.touches));
1830 device->last.num_touches = touch->num_touches;
1831 for (i = 0; i < touch->num_touches; i++)
1832 TouchInitDDXTouchPoint(device, &device->last.touches[i]);
1837 for (i = 0; i < touch->num_touches; i++)
1838 TouchFreeTouchPoint(device, i);
1840 free(touch->touches);
1847 * Check if the given buffer contains elements between low (inclusive) and
1848 * high (inclusive) only.
1850 * @return TRUE if the device map is invalid, FALSE otherwise.
1853 BadDeviceMap(BYTE * buff, int length, unsigned low, unsigned high, XID *errval)
1857 for (i = 0; i < length; i++)
1858 if (buff[i]) { /* only check non-zero elements */
1859 if ((low > buff[i]) || (high < buff[i])) {
1868 ProcSetModifierMapping(ClientPtr client)
1870 xSetModifierMappingReply rep;
1873 REQUEST(xSetModifierMappingReq);
1874 REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
1876 if (client->req_len != ((stuff->numKeyPerModifier << 1) +
1877 bytes_to_int32(sizeof(xSetModifierMappingReq))))
1880 rep = (xSetModifierMappingReply) {
1882 .sequenceNumber = client->sequence,
1886 rc = change_modmap(client, PickKeyboard(client), (KeyCode *) &stuff[1],
1887 stuff->numKeyPerModifier);
1888 if (rc == MappingFailed || rc == -1)
1890 if (rc != Success && rc != MappingSuccess && rc != MappingFailed &&
1896 WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
1901 ProcGetModifierMapping(ClientPtr client)
1903 xGetModifierMappingReply rep;
1904 int max_keys_per_mod = 0;
1905 KeyCode *modkeymap = NULL;
1907 REQUEST_SIZE_MATCH(xReq);
1909 generate_modkeymap(client, PickKeyboard(client), &modkeymap,
1912 rep = (xGetModifierMappingReply) {
1914 .numKeyPerModifier = max_keys_per_mod,
1915 .sequenceNumber = client->sequence,
1916 /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1917 .length = max_keys_per_mod << 1
1920 WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
1921 WriteToClient(client, max_keys_per_mod * 8, modkeymap);
1929 ProcChangeKeyboardMapping(ClientPtr client)
1931 REQUEST(xChangeKeyboardMappingReq);
1934 DeviceIntPtr pDev, tmp;
1937 REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
1939 len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq));
1940 if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
1943 pDev = PickKeyboard(client);
1945 if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) ||
1946 (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) {
1947 client->errorValue = stuff->firstKeyCode;
1951 if (((unsigned) (stuff->firstKeyCode + stuff->keyCodes - 1) >
1952 pDev->key->xkbInfo->desc->max_key_code) ||
1953 (stuff->keySymsPerKeyCode == 0)) {
1954 client->errorValue = stuff->keySymsPerKeyCode;
1958 keysyms.minKeyCode = stuff->firstKeyCode;
1959 keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
1960 keysyms.mapWidth = stuff->keySymsPerKeyCode;
1961 keysyms.map = (KeySym *) &stuff[1];
1963 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1967 XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode,
1968 stuff->keyCodes, NULL, client);
1970 for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
1971 if (IsMaster(tmp) || GetMaster(tmp, MASTER_KEYBOARD) != pDev)
1976 rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
1980 XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode,
1981 stuff->keyCodes, NULL, client);
1988 ProcSetPointerMapping(ClientPtr client)
1993 DeviceIntPtr ptr = PickPointer(client);
1994 xSetPointerMappingReply rep;
1996 REQUEST(xSetPointerMappingReq);
1997 REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
1999 if (client->req_len !=
2000 bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts))
2003 rep = (xSetPointerMappingReply) {
2005 .success = MappingSuccess,
2006 .sequenceNumber = client->sequence,
2009 map = (BYTE *) &stuff[1];
2011 /* So we're bounded here by the number of core buttons. This check
2012 * probably wants disabling through XFixes. */
2013 /* MPX: With ClientPointer, we can return the right number of buttons.
2014 * Let's just hope nobody changed ClientPointer between GetPointerMapping
2015 * and SetPointerMapping
2017 if (stuff->nElts != ptr->button->numButtons) {
2018 client->errorValue = stuff->nElts;
2022 /* Core protocol specs don't allow for duplicate mappings; this check
2023 * almost certainly wants disabling through XFixes too. */
2024 for (i = 0; i < stuff->nElts; i++) {
2025 for (j = i + 1; j < stuff->nElts; j++) {
2026 if (map[i] && map[i] == map[j]) {
2027 client->errorValue = map[i];
2033 ret = ApplyPointerMapping(ptr, map, stuff->nElts, client);
2034 if (ret == MappingBusy)
2038 else if (ret != Success)
2041 WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
2046 ProcGetKeyboardMapping(ClientPtr client)
2048 xGetKeyboardMappingReply rep;
2049 DeviceIntPtr kbd = PickKeyboard(client);
2054 REQUEST(xGetKeyboardMappingReq);
2055 REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
2057 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
2061 xkb = kbd->key->xkbInfo->desc;
2063 if ((stuff->firstKeyCode < xkb->min_key_code) ||
2064 (stuff->firstKeyCode > xkb->max_key_code)) {
2065 client->errorValue = stuff->firstKeyCode;
2068 if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) {
2069 client->errorValue = stuff->count;
2073 syms = XkbGetCoreMap(kbd);
2077 rep = (xGetKeyboardMappingReply) {
2079 .keySymsPerKeyCode = syms->mapWidth,
2080 .sequenceNumber = client->sequence,
2081 /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
2082 .length = syms->mapWidth * stuff->count
2084 WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
2085 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
2086 WriteSwappedDataToClient(client,
2087 syms->mapWidth * stuff->count * sizeof(KeySym),
2088 &syms->map[syms->mapWidth * (stuff->firstKeyCode -
2089 syms->minKeyCode)]);
2097 ProcGetPointerMapping(ClientPtr client)
2099 xGetPointerMappingReply rep;
2101 /* Apps may get different values each time they call GetPointerMapping as
2102 * the ClientPointer could change. */
2103 DeviceIntPtr ptr = PickPointer(client);
2104 ButtonClassPtr butc = ptr->button;
2108 REQUEST_SIZE_MATCH(xReq);
2110 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
2114 nElts = (butc) ? butc->numButtons : 0;
2115 rep = (xGetPointerMappingReply) {
2118 .sequenceNumber = client->sequence,
2119 .length = ((unsigned) nElts + (4 - 1)) / 4
2121 WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
2123 WriteToClient(client, nElts, &butc->map[1]);
2128 NoteLedState(DeviceIntPtr keybd, int led, Bool on)
2130 KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
2133 ctrl->leds |= ((Leds) 1 << (led - 1));
2135 ctrl->leds &= ~((Leds) 1 << (led - 1));
2139 Ones(unsigned long mask)
2143 y = (mask >> 1) & 033333333333;
2144 y = mask - y - ((y >> 1) & 033333333333);
2145 return (((y + (y >> 3)) & 030707070707) % 077);
2149 DoChangeKeyboardControl(ClientPtr client, DeviceIntPtr keybd, XID *vlist,
2158 int mask = vmask, i;
2159 XkbEventCauseRec cause;
2161 ctrl = keybd->kbdfeed->ctrl;
2163 index2 = (BITS32) lowbit(vmask);
2166 case KBKeyClickPercent:
2170 t = defaultKeyboardControl.click;
2172 else if (t < 0 || t > 100) {
2173 client->errorValue = t;
2182 t = defaultKeyboardControl.bell;
2184 else if (t < 0 || t > 100) {
2185 client->errorValue = t;
2194 t = defaultKeyboardControl.bell_pitch;
2197 client->errorValue = t;
2200 ctrl.bell_pitch = t;
2202 case KBBellDuration:
2206 t = defaultKeyboardControl.bell_duration;
2208 client->errorValue = t;
2211 ctrl.bell_duration = t;
2214 led = (CARD8) *vlist;
2216 if (led < 1 || led > 32) {
2217 client->errorValue = led;
2220 if (!(mask & KBLedMode))
2226 if (t == LedModeOff) {
2230 ctrl.leds &= ~(((Leds) (1)) << (led - 1));
2232 else if (t == LedModeOn) {
2236 ctrl.leds |= (((Leds) (1)) << (led - 1));
2239 client->errorValue = t;
2243 XkbSetCauseCoreReq(&cause, X_ChangeKeyboardControl, client);
2244 XkbSetIndicators(keybd, ((led == DO_ALL) ? ~0L : (1L << (led - 1))),
2246 ctrl.leds = keybd->kbdfeed->ctrl.leds;
2250 key = (KeyCode) *vlist;
2252 if ((KeyCode) key < keybd->key->xkbInfo->desc->min_key_code ||
2253 (KeyCode) key > keybd->key->xkbInfo->desc->max_key_code) {
2254 client->errorValue = key;
2257 if (!(mask & KBAutoRepeatMode))
2260 case KBAutoRepeatMode:
2262 mask = (1 << (key & 7));
2266 XkbDisableComputedAutoRepeats(keybd, key);
2267 if (t == AutoRepeatModeOff) {
2269 ctrl.autoRepeat = FALSE;
2271 ctrl.autoRepeats[i] &= ~mask;
2273 else if (t == AutoRepeatModeOn) {
2275 ctrl.autoRepeat = TRUE;
2277 ctrl.autoRepeats[i] |= mask;
2279 else if (t == AutoRepeatModeDefault) {
2281 ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
2283 ctrl.autoRepeats[i] =
2284 (ctrl.autoRepeats[i] & ~mask) |
2285 (defaultKeyboardControl.autoRepeats[i] & mask);
2288 client->errorValue = t;
2293 client->errorValue = mask;
2297 keybd->kbdfeed->ctrl = ctrl;
2299 /* The XKB RepeatKeys control and core protocol global autorepeat */
2300 /* value are linked */
2301 XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
2309 * Changes kbd control on the ClientPointer and all attached SDs.
2312 ProcChangeKeyboardControl(ClientPtr client)
2316 int ret = Success, error = Success;
2317 DeviceIntPtr pDev = NULL, keyboard;
2319 REQUEST(xChangeKeyboardControlReq);
2321 REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
2323 vmask = stuff->mask;
2324 vlist = (XID *) &stuff[1];
2326 if (client->req_len !=
2327 (sizeof(xChangeKeyboardControlReq) >> 2) + Ones(vmask))
2330 keyboard = PickKeyboard(client);
2332 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2333 if ((pDev == keyboard ||
2334 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2335 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2336 ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess);
2342 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
2343 if ((pDev == keyboard ||
2344 (!IsMaster(pDev) && GetMaster(pDev, MASTER_KEYBOARD) == keyboard))
2345 && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
2346 ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
2356 ProcGetKeyboardControl(ClientPtr client)
2359 DeviceIntPtr kbd = PickKeyboard(client);
2360 KeybdCtrl *ctrl = &kbd->kbdfeed->ctrl;
2361 xGetKeyboardControlReply rep;
2363 REQUEST_SIZE_MATCH(xReq);
2365 rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetAttrAccess);
2369 rep = (xGetKeyboardControlReply) {
2371 .globalAutoRepeat = ctrl->autoRepeat,
2372 .sequenceNumber = client->sequence,
2374 .ledMask = ctrl->leds,
2375 .keyClickPercent = ctrl->click,
2376 .bellPercent = ctrl->bell,
2377 .bellPitch = ctrl->bell_pitch,
2378 .bellDuration = ctrl->bell_duration
2380 for (i = 0; i < 32; i++)
2381 rep.map[i] = ctrl->autoRepeats[i];
2382 WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
2387 ProcBell(ClientPtr client)
2389 DeviceIntPtr dev, keybd = PickKeyboard(client);
2390 int base = keybd->kbdfeed->ctrl.bell;
2395 REQUEST_SIZE_MATCH(xBellReq);
2397 if (stuff->percent < -100 || stuff->percent > 100) {
2398 client->errorValue = stuff->percent;
2402 newpercent = (base * stuff->percent) / 100;
2403 if (stuff->percent < 0)
2404 newpercent = base + newpercent;
2406 newpercent = base - newpercent + stuff->percent;
2408 for (dev = inputInfo.devices; dev; dev = dev->next) {
2409 if ((dev == keybd ||
2410 (!IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == keybd)) &&
2411 dev->kbdfeed && dev->kbdfeed->BellProc) {
2413 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess);
2416 XkbHandleBell(FALSE, FALSE, dev, newpercent,
2417 &dev->kbdfeed->ctrl, 0, None, NULL, client);
2425 ProcChangePointerControl(ClientPtr client)
2427 DeviceIntPtr dev, mouse = PickPointer(client);
2428 PtrCtrl ctrl; /* might get BadValue part way through */
2431 REQUEST(xChangePointerControlReq);
2432 REQUEST_SIZE_MATCH(xChangePointerControlReq);
2434 ctrl = mouse->ptrfeed->ctrl;
2435 if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
2436 client->errorValue = stuff->doAccel;
2439 if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
2440 client->errorValue = stuff->doThresh;
2443 if (stuff->doAccel) {
2444 if (stuff->accelNum == -1) {
2445 ctrl.num = defaultPointerControl.num;
2447 else if (stuff->accelNum < 0) {
2448 client->errorValue = stuff->accelNum;
2452 ctrl.num = stuff->accelNum;
2455 if (stuff->accelDenum == -1) {
2456 ctrl.den = defaultPointerControl.den;
2458 else if (stuff->accelDenum <= 0) {
2459 client->errorValue = stuff->accelDenum;
2463 ctrl.den = stuff->accelDenum;
2466 if (stuff->doThresh) {
2467 if (stuff->threshold == -1) {
2468 ctrl.threshold = defaultPointerControl.threshold;
2470 else if (stuff->threshold < 0) {
2471 client->errorValue = stuff->threshold;
2475 ctrl.threshold = stuff->threshold;
2479 for (dev = inputInfo.devices; dev; dev = dev->next) {
2480 if ((dev == mouse ||
2481 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2483 rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess);
2489 for (dev = inputInfo.devices; dev; dev = dev->next) {
2490 if ((dev == mouse ||
2491 (!IsMaster(dev) && GetMaster(dev, MASTER_POINTER) == mouse)) &&
2493 dev->ptrfeed->ctrl = ctrl;
2501 ProcGetPointerControl(ClientPtr client)
2503 DeviceIntPtr ptr = PickPointer(client);
2504 PtrCtrl *ctrl = &ptr->ptrfeed->ctrl;
2505 xGetPointerControlReply rep;
2508 REQUEST_SIZE_MATCH(xReq);
2510 rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, DixGetAttrAccess);
2514 rep = (xGetPointerControlReply) {
2516 .sequenceNumber = client->sequence,
2518 .accelNumerator = ctrl->num,
2519 .accelDenominator = ctrl->den,
2520 .threshold = ctrl->threshold
2522 WriteReplyToClient(client, sizeof(xGenericReply), &rep);
2527 MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
2529 GrabPtr grab = dev->deviceGrab.grab;
2531 if ((grab && SameClient(grab, client) &&
2532 ((grab->eventMask & PointerMotionHintMask) ||
2533 (grab->ownerEvents &&
2534 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2535 PointerMotionHintMask)))) ||
2537 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
2538 PointerMotionHintMask)))
2539 dev->valuator->motionHintWindow = NullWindow;
2543 ProcGetMotionEvents(ClientPtr client)
2546 xTimecoord *coords = (xTimecoord *) NULL;
2547 xGetMotionEventsReply rep;
2548 int i, count, xmin, xmax, ymin, ymax, rc;
2549 unsigned long nEvents;
2550 DeviceIntPtr mouse = PickPointer(client);
2551 TimeStamp start, stop;
2553 REQUEST(xGetMotionEventsReq);
2554 REQUEST_SIZE_MATCH(xGetMotionEventsReq);
2556 rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2559 rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
2563 if (mouse->valuator->motionHintWindow)
2564 MaybeStopHint(mouse, client);
2565 rep = (xGetMotionEventsReply) {
2567 .sequenceNumber = client->sequence
2570 start = ClientTimeToServerTime(stuff->start);
2571 stop = ClientTimeToServerTime(stuff->stop);
2572 if ((CompareTimeStamps(start, stop) != LATER) &&
2573 (CompareTimeStamps(start, currentTime) != LATER) &&
2574 mouse->valuator->numMotionEvents) {
2575 if (CompareTimeStamps(stop, currentTime) == LATER)
2577 count = GetMotionHistory(mouse, &coords, start.milliseconds,
2578 stop.milliseconds, pWin->drawable.pScreen,
2580 xmin = pWin->drawable.x - wBorderWidth(pWin);
2581 xmax = pWin->drawable.x + (int) pWin->drawable.width +
2583 ymin = pWin->drawable.y - wBorderWidth(pWin);
2584 ymax = pWin->drawable.y + (int) pWin->drawable.height +
2586 for (i = 0; i < count; i++)
2587 if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
2588 (ymin <= coords[i].y) && (coords[i].y < ymax)) {
2589 coords[nEvents].time = coords[i].time;
2590 coords[nEvents].x = coords[i].x - pWin->drawable.x;
2591 coords[nEvents].y = coords[i].y - pWin->drawable.y;
2595 rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord));
2596 rep.nEvents = nEvents;
2597 WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
2599 client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
2600 WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
2608 ProcQueryKeymap(ClientPtr client)
2610 xQueryKeymapReply rep;
2612 DeviceIntPtr keybd = PickKeyboard(client);
2613 CARD8 *down = keybd->key->down;
2615 REQUEST_SIZE_MATCH(xReq);
2616 rep = (xQueryKeymapReply) {
2618 .sequenceNumber = client->sequence,
2622 rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
2623 /* If rc is Success, we're allowed to copy out the keymap.
2624 * If it's BadAccess, we leave it empty & lie to the client.
2626 if (rc == Success) {
2627 for (i = 0; i < 32; i++)
2628 rep.map[i] = down[i];
2630 else if (rc != BadAccess)
2633 WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
2639 * Recalculate the number of buttons for the master device. The number of
2640 * buttons on the master device is equal to the number of buttons on the
2641 * slave device with the highest number of buttons.
2644 RecalculateMasterButtons(DeviceIntPtr slave)
2646 DeviceIntPtr dev, master;
2649 if (!slave->button || IsMaster(slave))
2652 master = GetMaster(slave, MASTER_POINTER);
2656 for (dev = inputInfo.devices; dev; dev = dev->next) {
2657 if (IsMaster(dev) ||
2658 GetMaster(dev, MASTER_ATTACHED) != master || !dev->button)
2661 maxbuttons = max(maxbuttons, dev->button->numButtons);
2664 if (master->button && master->button->numButtons != maxbuttons) {
2666 DeviceChangedEvent event = {
2667 .header = ET_Internal,
2668 .type = ET_DeviceChanged,
2669 .time = GetTimeInMillis(),
2670 .deviceid = master->id,
2671 .flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE,
2672 .buttons.num_buttons = maxbuttons
2675 master->button->numButtons = maxbuttons;
2677 memcpy(&event.buttons.names, master->button->labels, maxbuttons *
2680 if (master->valuator) {
2681 event.num_valuators = master->valuator->numAxes;
2682 for (i = 0; i < event.num_valuators; i++) {
2683 event.valuators[i].min = master->valuator->axes[i].min_value;
2684 event.valuators[i].max = master->valuator->axes[i].max_value;
2685 event.valuators[i].resolution =
2686 master->valuator->axes[i].resolution;
2687 event.valuators[i].mode = master->valuator->axes[i].mode;
2688 event.valuators[i].name = master->valuator->axes[i].label;
2693 event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code;
2694 event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code;
2697 XISendDeviceChangedEvent(master, &event);
2702 * Generate release events for all keys/button currently down on this
2706 ReleaseButtonsAndKeys(DeviceIntPtr dev)
2708 InternalEvent *eventlist = InitEventList(GetMaximumEventsNum());
2709 ButtonClassPtr b = dev->button;
2710 KeyClassPtr k = dev->key;
2713 if (!eventlist) /* no release events for you */
2716 /* Release all buttons */
2717 for (i = 0; b && i < b->numButtons; i++) {
2718 if (BitIsOn(b->down, i)) {
2720 GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
2721 for (j = 0; j < nevents; j++)
2722 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2726 /* Release all keys */
2727 for (i = 0; k && i < MAP_LENGTH; i++) {
2728 if (BitIsOn(k->down, i)) {
2729 nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
2730 for (j = 0; j < nevents; j++)
2731 mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
2735 FreeEventList(eventlist, GetMaximumEventsNum());
2739 * Attach device 'dev' to device 'master'.
2740 * Client is set to the client that issued the request, or NULL if it comes
2741 * from some internal automatic pairing.
2743 * Master may be NULL to set the device floating.
2745 * We don't allow multi-layer hierarchies right now. You can't attach a slave
2749 AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
2753 if (!dev || IsMaster(dev))
2756 if (master && !IsMaster(master)) /* can't attach to slaves */
2759 /* set from floating to floating? */
2760 if (IsFloating(dev) && !master && dev->enabled)
2763 /* free the existing sprite. */
2764 if (IsFloating(dev) && dev->spriteInfo->paired == dev) {
2765 screen = miPointerGetScreen(dev);
2766 screen->DeviceCursorCleanup(dev, screen);
2767 free(dev->spriteInfo->sprite);
2770 dev->master = master;
2772 /* If device is set to floating, we need to create a sprite for it,
2773 * otherwise things go bad. However, we don't want to render the cursor,
2774 * so we reset spriteOwner.
2775 * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
2776 * alloc new memory but overwrite the previous one.
2779 WindowPtr currentRoot;
2781 if (dev->spriteInfo->sprite)
2782 currentRoot = GetCurrentRootWindow(dev);
2783 else /* new device auto-set to floating */
2784 currentRoot = screenInfo.screens[0]->root;
2786 /* we need to init a fake sprite */
2787 screen = currentRoot->drawable.pScreen;
2788 screen->DeviceCursorInitialize(dev, screen);
2789 dev->spriteInfo->sprite = NULL;
2790 InitializeSprite(dev, currentRoot);
2791 dev->spriteInfo->spriteOwner = FALSE;
2792 dev->spriteInfo->paired = dev;
2795 dev->spriteInfo->sprite = master->spriteInfo->sprite;
2796 dev->spriteInfo->paired = master;
2797 dev->spriteInfo->spriteOwner = FALSE;
2799 XkbPushLockedStateToSlaves(GetMaster(dev, MASTER_KEYBOARD), 0, 0);
2800 RecalculateMasterButtons(master);
2803 /* XXX: in theory, the MD should change back to its old, original
2804 * classes when the last SD is detached. Thanks to the XTEST devices,
2805 * we'll always have an SD attached until the MD is removed.
2806 * So let's not worry about that.
2813 * Return the device paired with the given device or NULL.
2814 * Returns the device paired with the parent master if the given device is a
2818 GetPairedDevice(DeviceIntPtr dev)
2820 if (!IsMaster(dev) && !IsFloating(dev))
2821 dev = GetMaster(dev, MASTER_ATTACHED);
2823 return dev->spriteInfo->paired;
2827 * Returns the requested master for this device.
2828 * The return values are:
2829 * - MASTER_ATTACHED: the master for this device or NULL for a floating
2831 * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a
2833 * - MASTER_POINTER: the master keyboard for this device or NULL for a
2835 * - POINTER_OR_FLOAT: the master pointer for this device or the device for
2837 * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for
2840 * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED,
2841 * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT.
2842 * @return The requested master device
2845 GetMaster(DeviceIntPtr dev, int which)
2847 DeviceIntPtr master;
2852 master = dev->master;
2854 (which == POINTER_OR_FLOAT || which == KEYBOARD_OR_FLOAT))
2858 if (master && which != MASTER_ATTACHED) {
2859 if (which == MASTER_KEYBOARD || which == KEYBOARD_OR_FLOAT) {
2860 if (master->type != MASTER_KEYBOARD)
2861 master = GetPairedDevice(master);
2864 if (master->type != MASTER_POINTER)
2865 master = GetPairedDevice(master);
2873 * Create a new device pair (== one pointer, one keyboard device).
2874 * Only allocates the devices, you will need to call ActivateDevice() and
2875 * EnableDevice() manually.
2876 * Either a master or a slave device can be created depending on
2877 * the value for master.
2880 AllocDevicePair(ClientPtr client, const char *name,
2882 DeviceIntPtr *keybd,
2883 DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master)
2885 DeviceIntPtr pointer;
2886 DeviceIntPtr keyboard;
2889 *ptr = *keybd = NULL;
2893 pointer = AddInputDevice(client, ptr_proc, TRUE);
2898 if (asprintf(&dev_name, "%s pointer", name) == -1) {
2899 RemoveDevice(pointer, FALSE);
2903 pointer->name = dev_name;
2905 pointer->public.processInputProc = ProcessOtherEvent;
2906 pointer->public.realInputProc = ProcessOtherEvent;
2907 XkbSetExtension(pointer, ProcessPointerEvent);
2908 pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
2909 pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
2910 pointer->coreEvents = TRUE;
2911 pointer->spriteInfo->spriteOwner = TRUE;
2913 pointer->lastSlave = NULL;
2914 pointer->last.slave = NULL;
2915 pointer->type = (master) ? MASTER_POINTER : SLAVE;
2917 keyboard = AddInputDevice(client, keybd_proc, TRUE);
2919 RemoveDevice(pointer, FALSE);
2924 if (asprintf(&dev_name, "%s keyboard", name) == -1) {
2925 RemoveDevice(keyboard, FALSE);
2926 RemoveDevice(pointer, FALSE);
2930 keyboard->name = dev_name;
2932 keyboard->public.processInputProc = ProcessOtherEvent;
2933 keyboard->public.realInputProc = ProcessOtherEvent;
2934 XkbSetExtension(keyboard, ProcessKeyboardEvent);
2935 keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
2936 keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
2937 keyboard->coreEvents = TRUE;
2938 keyboard->spriteInfo->spriteOwner = FALSE;
2940 keyboard->lastSlave = NULL;
2941 keyboard->last.slave = NULL;
2942 keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
2944 /* The ClassesRec stores the device classes currently not used. */
2945 if (IsMaster(pointer)) {
2946 pointer->unused_classes = calloc(1, sizeof(ClassesRec));
2947 keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
2957 #ifdef _F_SUPPORT_XTEST_TOUCH_EVENT_
2959 AllocHWKeyTouchDevicePair(ClientPtr client, const char *name,
2961 DeviceIntPtr *keybd,
2962 DeviceProc ptr_proc, DeviceProc keybd_proc, Bool master)
2964 DeviceIntPtr pointer;
2965 DeviceIntPtr keyboard;
2968 *ptr = *keybd = NULL;
2972 pointer = AddInputDevice(client, ptr_proc, TRUE);
2977 if (asprintf(&dev_name, "%s touch", name) == -1) {
2978 RemoveDevice(pointer, FALSE);
2982 pointer->name = dev_name;
2984 pointer->public.processInputProc = ProcessOtherEvent;
2985 pointer->public.realInputProc = ProcessOtherEvent;
2986 XkbSetExtension(pointer, ProcessPointerEvent);
2987 pointer->deviceGrab.ActivateGrab = ActivatePointerGrab;
2988 pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
2989 pointer->coreEvents = TRUE;
2990 pointer->spriteInfo->spriteOwner = TRUE;
2992 pointer->lastSlave = NULL;
2993 pointer->last.slave = NULL;
2994 pointer->type = (master) ? MASTER_POINTER : SLAVE;
2996 keyboard = AddInputDevice(client, keybd_proc, TRUE);
2998 RemoveDevice(pointer, FALSE);
3003 if (asprintf(&dev_name, "%s functionkeys", name) == -1) {
3004 RemoveDevice(keyboard, FALSE);
3005 RemoveDevice(pointer, FALSE);
3009 keyboard->name = dev_name;
3011 keyboard->public.processInputProc = ProcessOtherEvent;
3012 keyboard->public.realInputProc = ProcessOtherEvent;
3013 XkbSetExtension(keyboard, ProcessKeyboardEvent);
3014 keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
3015 keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
3016 keyboard->coreEvents = TRUE;
3017 keyboard->spriteInfo->spriteOwner = FALSE;
3019 keyboard->lastSlave = NULL;
3020 keyboard->last.slave = NULL;
3021 keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE;
3023 /* The ClassesRec stores the device classes currently not used. */
3024 if (IsMaster(pointer)) {
3025 pointer->unused_classes = calloc(1, sizeof(ClassesRec));
3026 keyboard->unused_classes = calloc(1, sizeof(ClassesRec));
3035 #endif //_F_SUPPORT_XTEST_TOUCH_EVENT_
3038 * Return Relative or Absolute for the device.
3041 valuator_get_mode(DeviceIntPtr dev, int axis)
3043 return (dev->valuator->axes[axis].mode & DeviceMode);
3047 * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
3048 * set the mode for all axes.
3051 valuator_set_mode(DeviceIntPtr dev, int axis, int mode)
3053 if (axis != VALUATOR_MODE_ALL_AXES)
3054 dev->valuator->axes[axis].mode = mode;
3058 for (i = 0; i < dev->valuator->numAxes; i++)
3059 dev->valuator->axes[i].mode = mode;