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 RecalculateMasterButtons(dev
);
421 /* initialise an idle timer for this device*/
422 dev
->idle_counter
= SyncInitDeviceIdleTime(dev
);
429 * Switch a device off through the driver and push it onto the off_devices
430 * list. A device will not send events while disabled. All clients are
431 * notified about the device being disabled.
433 * Master keyboard devices have to be disabled before master pointer devices
434 * otherwise things turn bad.
436 * @param sendevent True if an XI2 event should be sent.
437 * @return TRUE on success or FALSE otherwise.
440 DisableDevice(DeviceIntPtr dev
, BOOL sendevent
)
442 DeviceIntPtr
*prev
, other
;
444 int flags
[MAXDEVICES
] = { 0 };
449 for (prev
= &inputInfo
.devices
;
450 *prev
&& (*prev
!= dev
); prev
= &(*prev
)->next
);
454 TouchEndPhysicallyActiveTouches(dev
);
455 ReleaseButtonsAndKeys(dev
);
456 SyncRemoveDeviceIdleTime(dev
->idle_counter
);
457 dev
->idle_counter
= NULL
;
459 /* float attached devices */
461 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
462 if (!IsMaster(other
) && GetMaster(other
, MASTER_ATTACHED
) == dev
) {
463 AttachDevice(NULL
, other
, NULL
);
464 flags
[other
->id
] |= XISlaveDetached
;
469 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
470 if (IsMaster(other
) && other
->lastSlave
== dev
)
471 other
->lastSlave
= NULL
;
475 if (IsMaster(dev
) && dev
->spriteInfo
->sprite
) {
476 for (other
= inputInfo
.devices
; other
; other
= other
->next
)
477 if (other
->spriteInfo
->paired
== dev
&& !other
->spriteInfo
->spriteOwner
)
478 DisableDevice(other
, sendevent
);
481 if (dev
->spriteInfo
->paired
)
482 dev
->spriteInfo
->paired
= NULL
;
484 (void) (*dev
->deviceProc
) (dev
, DEVICE_OFF
);
485 dev
->enabled
= FALSE
;
489 /* now that the device is disabled, we can reset the signal handler's
492 for (other
= inputInfo
.devices
; other
; other
= other
->next
) {
493 if (other
->last
.slave
== dev
)
494 other
->last
.slave
= NULL
;
502 dev
->next
= inputInfo
.off_devices
;
503 inputInfo
.off_devices
= dev
;
506 XIChangeDeviceProperty(dev
, XIGetKnownProperty(XI_PROP_ENABLED
),
507 XA_INTEGER
, 8, PropModeReplace
, 1, &enabled
, TRUE
);
509 SendDevicePresenceEvent(dev
->id
, DeviceDisabled
);
511 flags
[dev
->id
] = XIDeviceDisabled
;
512 XISendDeviceHierarchyEvent(flags
);
515 RecalculateMasterButtons(dev
);
521 DisableAllDevices(void)
523 DeviceIntPtr dev
, tmp
;
525 /* Disable slave devices first, excluding XTest devices */
526 nt_list_for_each_entry_safe(dev
, tmp
, inputInfo
.devices
, next
) {
527 if (!IsXTestDevice(dev
, NULL
) && !IsMaster(dev
))
528 DisableDevice(dev
, FALSE
);
530 /* Disable XTest devices */
531 nt_list_for_each_entry_safe(dev
, tmp
, inputInfo
.devices
, next
) {
533 DisableDevice(dev
, FALSE
);
535 /* master keyboards need to be disabled first */
536 nt_list_for_each_entry_safe(dev
, tmp
, inputInfo
.devices
, next
) {
537 if (dev
->enabled
&& IsMaster(dev
) && IsKeyboardDevice(dev
))
538 DisableDevice(dev
, FALSE
);
540 nt_list_for_each_entry_safe(dev
, tmp
, inputInfo
.devices
, next
) {
542 DisableDevice(dev
, FALSE
);
547 * Initialise a new device through the driver and tell all clients about the
550 * Must be called before EnableDevice.
551 * The device will NOT send events until it is enabled!
553 * @param sendevent True if an XI2 event should be sent.
554 * @return Success or an error code on failure.
557 ActivateDevice(DeviceIntPtr dev
, BOOL sendevent
)
560 ScreenPtr pScreen
= screenInfo
.screens
[0];
562 if (!dev
|| !dev
->deviceProc
)
563 return BadImplementation
;
565 ret
= (*dev
->deviceProc
) (dev
, DEVICE_INIT
);
566 dev
->inited
= (ret
== Success
);
570 /* Initialize memory for sprites. */
571 if (IsMaster(dev
) && dev
->spriteInfo
->spriteOwner
)
572 if (!pScreen
->DeviceCursorInitialize(dev
, pScreen
))
575 SendDevicePresenceEvent(dev
->id
, DeviceAdded
);
577 int flags
[MAXDEVICES
] = { 0 };
578 flags
[dev
->id
] = XISlaveAdded
;
579 XISendDeviceHierarchyEvent(flags
);
586 * The actual task of ringing the bell is the job of the DDX.
589 CoreKeyboardBell(int volume
, DeviceIntPtr pDev
, pointer arg
, int something
)
591 KeybdCtrl
*ctrl
= arg
;
593 DDXRingBell(volume
, ctrl
->bell_pitch
, ctrl
->bell_duration
);
597 CoreKeyboardCtl(DeviceIntPtr pDev
, KeybdCtrl
* ctrl
)
603 * Device control function for the Virtual Core Keyboard.
606 CoreKeyboardProc(DeviceIntPtr pDev
, int what
)
611 if (!InitKeyboardDeviceStruct(pDev
, NULL
, CoreKeyboardBell
,
613 ErrorF("Keyboard initialization failed. This could be a missing "
614 "or incorrect setup of xkeyboard-config.\n");
631 * Device control function for the Virtual Core Pointer.
634 CorePointerProc(DeviceIntPtr pDev
, int what
)
638 BYTE map
[NBUTTONS
+ 1];
640 Atom btn_labels
[NBUTTONS
] = { 0 };
641 Atom axes_labels
[NAXES
] = { 0 };
642 ScreenPtr scr
= screenInfo
.screens
[0];
646 for (i
= 1; i
<= NBUTTONS
; i
++)
649 btn_labels
[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT
);
650 btn_labels
[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE
);
651 btn_labels
[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT
);
652 btn_labels
[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP
);
653 btn_labels
[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN
);
654 btn_labels
[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT
);
655 btn_labels
[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT
);
656 /* don't know about the rest */
658 axes_labels
[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X
);
659 axes_labels
[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y
);
661 if (!InitPointerDeviceStruct
662 ((DevicePtr
) pDev
, map
, NBUTTONS
, btn_labels
,
663 (PtrCtrlProcPtr
) NoopDDA
, GetMotionHistorySize(), NAXES
,
665 ErrorF("Could not initialize device '%s'. Out of memory.\n",
667 return BadAlloc
; /* IPDS only fails on allocs */
669 /* axisVal is per-screen, last.valuators is desktop-wide */
670 pDev
->valuator
->axisVal
[0] = scr
->width
/ 2;
671 pDev
->last
.valuators
[0] = pDev
->valuator
->axisVal
[0] + scr
->x
;
672 pDev
->valuator
->axisVal
[1] = scr
->height
/ 2;
673 pDev
->last
.valuators
[1] = pDev
->valuator
->axisVal
[1] + scr
->y
;
690 * Initialise the two core devices, VCP and VCK (see events.c).
691 * Both devices are not tied to physical devices, but guarantee that there is
692 * always a keyboard and a pointer present and keep the protocol semantics.
694 * Note that the server MUST have two core devices at all times, even if there
695 * is no physical device connected.
698 InitCoreDevices(void)
700 if (AllocDevicePair(serverClient
, "Virtual core",
701 &inputInfo
.pointer
, &inputInfo
.keyboard
,
702 CorePointerProc
, CoreKeyboardProc
, TRUE
) != Success
)
703 FatalError("Failed to allocate core devices");
705 if (ActivateDevice(inputInfo
.pointer
, TRUE
) != Success
||
706 ActivateDevice(inputInfo
.keyboard
, TRUE
) != Success
)
707 FatalError("Failed to activate core devices.");
708 if (!EnableDevice(inputInfo
.pointer
, TRUE
) ||
709 !EnableDevice(inputInfo
.keyboard
, TRUE
))
710 FatalError("Failed to enable core devices.");
716 * Activate all switched-off devices and then enable all those devices.
718 * Will return an error if no core keyboard or core pointer is present.
719 * In theory this should never happen if you call InitCoreDevices() first.
721 * InitAndStartDevices needs to be called AFTER the windows are initialized.
722 * Devices will start sending events after InitAndStartDevices() has
725 * @return Success or error code on failure.
728 InitAndStartDevices(void)
730 DeviceIntPtr dev
, next
;
732 for (dev
= inputInfo
.off_devices
; dev
; dev
= dev
->next
) {
733 DebugF("(dix) initialising device %d\n", dev
->id
);
735 ActivateDevice(dev
, TRUE
);
738 /* enable real devices */
739 for (dev
= inputInfo
.off_devices
; dev
; dev
= next
) {
740 DebugF("(dix) enabling device %d\n", dev
->id
);
742 if (dev
->inited
&& dev
->startup
)
743 EnableDevice(dev
, TRUE
);
750 * Free the given device class and reset the pointer to NULL.
753 FreeDeviceClass(int type
, pointer
*class)
761 KeyClassPtr
*k
= (KeyClassPtr
*) class;
764 XkbFreeInfo((*k
)->xkbInfo
);
765 (*k
)->xkbInfo
= NULL
;
772 ButtonClassPtr
*b
= (ButtonClassPtr
*) class;
774 free((*b
)->xkb_acts
);
780 ValuatorClassPtr
*v
= (ValuatorClassPtr
*) class;
788 TouchClassPtr
*t
= (TouchClassPtr
*) class;
791 for (i
= 0; i
< (*t
)->num_touches
; i
++) {
792 free((*t
)->touches
[i
].sprite
.spriteTrace
);
793 free((*t
)->touches
[i
].listeners
);
794 free((*t
)->touches
[i
].valuators
);
803 FocusClassPtr
*f
= (FocusClassPtr
*) class;
811 ProximityClassPtr
*p
= (ProximityClassPtr
*) class;
821 FreeFeedbackClass(int type
, pointer
*class)
827 case KbdFeedbackClass
:
829 KbdFeedbackPtr
*kbdfeed
= (KbdFeedbackPtr
*) class;
830 KbdFeedbackPtr k
, knext
;
832 for (k
= (*kbdfeed
); k
; k
= knext
) {
835 XkbFreeSrvLedInfo(k
->xkb_sli
);
840 case PtrFeedbackClass
:
842 PtrFeedbackPtr
*ptrfeed
= (PtrFeedbackPtr
*) class;
843 PtrFeedbackPtr p
, pnext
;
845 for (p
= (*ptrfeed
); p
; p
= pnext
) {
851 case IntegerFeedbackClass
:
853 IntegerFeedbackPtr
*intfeed
= (IntegerFeedbackPtr
*) class;
854 IntegerFeedbackPtr i
, inext
;
856 for (i
= (*intfeed
); i
; i
= inext
) {
862 case StringFeedbackClass
:
864 StringFeedbackPtr
*stringfeed
= (StringFeedbackPtr
*) class;
865 StringFeedbackPtr s
, snext
;
867 for (s
= (*stringfeed
); s
; s
= snext
) {
869 free(s
->ctrl
.symbols_supported
);
870 free(s
->ctrl
.symbols_displayed
);
875 case BellFeedbackClass
:
877 BellFeedbackPtr
*bell
= (BellFeedbackPtr
*) class;
878 BellFeedbackPtr b
, bnext
;
880 for (b
= (*bell
); b
; b
= bnext
) {
886 case LedFeedbackClass
:
888 LedFeedbackPtr
*leds
= (LedFeedbackPtr
*) class;
889 LedFeedbackPtr l
, lnext
;
891 for (l
= (*leds
); l
; l
= lnext
) {
894 XkbFreeSrvLedInfo(l
->xkb_sli
);
904 FreeAllDeviceClasses(ClassesPtr classes
)
909 FreeDeviceClass(KeyClass
, (pointer
) &classes
->key
);
910 FreeDeviceClass(ValuatorClass
, (pointer
) &classes
->valuator
);
911 FreeDeviceClass(XITouchClass
, (pointer
) &classes
->touch
);
912 FreeDeviceClass(ButtonClass
, (pointer
) &classes
->button
);
913 FreeDeviceClass(FocusClass
, (pointer
) &classes
->focus
);
914 FreeDeviceClass(ProximityClass
, (pointer
) &classes
->proximity
);
916 FreeFeedbackClass(KbdFeedbackClass
, (pointer
) &classes
->kbdfeed
);
917 FreeFeedbackClass(PtrFeedbackClass
, (pointer
) &classes
->ptrfeed
);
918 FreeFeedbackClass(IntegerFeedbackClass
, (pointer
) &classes
->intfeed
);
919 FreeFeedbackClass(StringFeedbackClass
, (pointer
) &classes
->stringfeed
);
920 FreeFeedbackClass(BellFeedbackClass
, (pointer
) &classes
->bell
);
921 FreeFeedbackClass(LedFeedbackClass
, (pointer
) &classes
->leds
);
926 * Close down a device and free all resources.
927 * Once closed down, the driver will probably not expect you that you'll ever
928 * enable it again and free associated structs. If you want the device to just
929 * be disabled, DisableDevice().
930 * Don't call this function directly, use RemoveDevice() instead.
933 CloseDevice(DeviceIntPtr dev
)
935 ScreenPtr screen
= screenInfo
.screens
[0];
942 XIDeleteAllDeviceProperties(dev
);
945 (void) (*dev
->deviceProc
) (dev
, DEVICE_CLOSE
);
947 /* free sprite memory */
948 if (IsMaster(dev
) && dev
->spriteInfo
->sprite
)
949 screen
->DeviceCursorCleanup(dev
, screen
);
951 /* free acceleration info */
952 if (dev
->valuator
&& dev
->valuator
->accelScheme
.AccelCleanupProc
)
953 dev
->valuator
->accelScheme
.AccelCleanupProc(dev
);
955 while (dev
->xkb_interest
)
956 XkbRemoveResourceClient((DevicePtr
) dev
, dev
->xkb_interest
->resource
);
960 classes
= (ClassesPtr
) &dev
->key
;
961 FreeAllDeviceClasses(classes
);
964 classes
= dev
->unused_classes
;
965 FreeAllDeviceClasses(classes
);
971 /* a client may have the device set as client pointer */
972 for (j
= 0; j
< currentMaxClients
; j
++) {
973 if (clients
[j
] && clients
[j
]->clientPtr
== dev
) {
974 clients
[j
]->clientPtr
= NULL
;
975 clients
[j
]->clientPtr
= PickPointer(clients
[j
]);
979 if (dev
->deviceGrab
.grab
)
980 FreeGrab(dev
->deviceGrab
.grab
);
981 free(dev
->deviceGrab
.sync
.event
);
982 free(dev
->config_info
); /* Allocated in xf86ActivateDevice. */
983 free(dev
->last
.scroll
);
984 for (j
= 0; j
< dev
->last
.num_touches
; j
++)
985 free(dev
->last
.touches
[j
].valuators
);
986 free(dev
->last
.touches
);
987 dev
->config_info
= NULL
;
988 dixFreePrivates(dev
->devPrivates
, PRIVATE_DEVICE
);
993 * Shut down all devices of one list and free all resources.
997 CloseDeviceList(DeviceIntPtr
*listHead
)
999 /* Used to mark devices that we tried to free */
1000 Bool freedIds
[MAXDEVICES
];
1004 if (listHead
== NULL
)
1007 for (i
= 0; i
< MAXDEVICES
; i
++)
1008 freedIds
[i
] = FALSE
;
1011 while (dev
!= NULL
) {
1012 freedIds
[dev
->id
] = TRUE
;
1013 DeleteInputDeviceRequest(dev
);
1016 while (dev
!= NULL
&& freedIds
[dev
->id
])
1022 * Shut down all devices, free all resources, etc.
1023 * Only useful if you're shutting down the server!
1026 CloseDownDevices(void)
1032 /* Float all SDs before closing them. Note that at this point resources
1033 * (e.g. cursors) have been freed already, so we can't just call
1034 * AttachDevice(NULL, dev, NULL). Instead, we have to forcibly set master
1035 * to NULL and pretend nothing happened.
1037 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
1038 if (!IsMaster(dev
) && !IsFloating(dev
))
1042 CloseDeviceList(&inputInfo
.devices
);
1043 CloseDeviceList(&inputInfo
.off_devices
);
1045 CloseDevice(inputInfo
.pointer
);
1047 CloseDevice(inputInfo
.keyboard
);
1049 inputInfo
.devices
= NULL
;
1050 inputInfo
.off_devices
= NULL
;
1051 inputInfo
.keyboard
= NULL
;
1052 inputInfo
.pointer
= NULL
;
1054 XkbDeleteRulesDflts();
1055 XkbDeleteRulesUsed();
1061 * Signal all devices that we're in the process of aborting.
1062 * This function is called from a signal handler.
1068 nt_list_for_each_entry(dev
, inputInfo
.devices
, next
) {
1070 (*dev
->deviceProc
) (dev
, DEVICE_ABORT
);
1073 nt_list_for_each_entry(dev
, inputInfo
.off_devices
, next
) {
1075 (*dev
->deviceProc
) (dev
, DEVICE_ABORT
);
1080 * Remove the cursor sprite for all devices. This needs to be done before any
1081 * resources are freed or any device is deleted.
1084 UndisplayDevices(void)
1087 ScreenPtr screen
= screenInfo
.screens
[0];
1089 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
)
1090 screen
->DisplayCursor(dev
, screen
, NullCursor
);
1094 * Remove a device from the device list, closes it and thus frees all
1096 * Removes both enabled and disabled devices and notifies all devices about
1097 * the removal of the device.
1099 * No PresenceNotify is sent for device that the client never saw. This can
1100 * happen if a malloc fails during the addition of master devices. If
1101 * dev->init is FALSE it means the client never received a DeviceAdded event,
1102 * so let's not send a DeviceRemoved event either.
1104 * @param sendevent True if an XI2 event should be sent.
1107 RemoveDevice(DeviceIntPtr dev
, BOOL sendevent
)
1109 DeviceIntPtr prev
, tmp
, next
;
1111 ScreenPtr screen
= screenInfo
.screens
[0];
1114 int flags
[MAXDEVICES
] = { 0 };
1116 DebugF("(dix) removing device %d\n", dev
->id
);
1118 if (!dev
|| dev
== inputInfo
.keyboard
|| dev
== inputInfo
.pointer
)
1119 return BadImplementation
;
1121 initialized
= dev
->inited
;
1125 if (DevHasCursor(dev
))
1126 screen
->DisplayCursor(dev
, screen
, NullCursor
);
1128 DisableDevice(dev
, sendevent
);
1129 flags
[dev
->id
] = XIDeviceDisabled
;
1133 for (tmp
= inputInfo
.devices
; tmp
; (prev
= tmp
), (tmp
= next
)) {
1138 inputInfo
.devices
= next
;
1142 flags
[tmp
->id
] = IsMaster(tmp
) ? XIMasterRemoved
: XISlaveRemoved
;
1149 for (tmp
= inputInfo
.off_devices
; tmp
; (prev
= tmp
), (tmp
= next
)) {
1152 flags
[tmp
->id
] = IsMaster(tmp
) ? XIMasterRemoved
: XISlaveRemoved
;
1156 inputInfo
.off_devices
= next
;
1164 if (ret
== Success
&& initialized
) {
1165 inputInfo
.numDevices
--;
1166 SendDevicePresenceEvent(deviceid
, DeviceRemoved
);
1168 XISendDeviceHierarchyEvent(flags
);
1175 NumMotionEvents(void)
1177 /* only called to fill data in initial connection reply.
1178 * VCP is ok here, it is the only fixed device we have. */
1179 return inputInfo
.pointer
->valuator
->numMotionEvents
;
1183 dixLookupDevice(DeviceIntPtr
*pDev
, int id
, ClientPtr client
, Mask access_mode
)
1190 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
1194 for (dev
= inputInfo
.off_devices
; dev
; dev
= dev
->next
) {
1201 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, dev
, access_mode
);
1208 QueryMinMaxKeyCodes(KeyCode
*minCode
, KeyCode
*maxCode
)
1210 if (inputInfo
.keyboard
) {
1211 *minCode
= inputInfo
.keyboard
->key
->xkbInfo
->desc
->min_key_code
;
1212 *maxCode
= inputInfo
.keyboard
->key
->xkbInfo
->desc
->max_key_code
;
1216 /* Notably, this function does not expand the destination's keycode range, or
1217 * notify clients. */
1219 SetKeySymsMap(KeySymsPtr dst
, KeySymsPtr src
)
1223 int rowDif
= src
->minKeyCode
- dst
->minKeyCode
;
1225 /* if keysym map size changes, grow map first */
1226 if (src
->mapWidth
< dst
->mapWidth
) {
1227 for (i
= src
->minKeyCode
; i
<= src
->maxKeyCode
; i
++) {
1228 #define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c))
1229 #define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c))
1230 for (j
= 0; j
< src
->mapWidth
; j
++)
1231 dst
->map
[DI(i
, j
)] = src
->map
[SI(i
, j
)];
1232 for (j
= src
->mapWidth
; j
< dst
->mapWidth
; j
++)
1233 dst
->map
[DI(i
, j
)] = NoSymbol
;
1239 else if (src
->mapWidth
> dst
->mapWidth
) {
1240 i
= sizeof(KeySym
) * src
->mapWidth
*
1241 (dst
->maxKeyCode
- dst
->minKeyCode
+ 1);
1242 tmp
= calloc(sizeof(KeySym
), i
);
1247 for (i
= 0; i
<= dst
->maxKeyCode
- dst
->minKeyCode
; i
++)
1248 memmove(&tmp
[i
* src
->mapWidth
], &dst
->map
[i
* dst
->mapWidth
],
1249 dst
->mapWidth
* sizeof(KeySym
));
1252 dst
->mapWidth
= src
->mapWidth
;
1255 else if (!dst
->map
) {
1256 i
= sizeof(KeySym
) * src
->mapWidth
*
1257 (dst
->maxKeyCode
- dst
->minKeyCode
+ 1);
1258 tmp
= calloc(sizeof(KeySym
), i
);
1263 dst
->mapWidth
= src
->mapWidth
;
1266 memmove(&dst
->map
[rowDif
* dst
->mapWidth
], src
->map
,
1267 (src
->maxKeyCode
- src
->minKeyCode
+ 1) *
1268 dst
->mapWidth
* sizeof(KeySym
));
1274 InitButtonClassDeviceStruct(DeviceIntPtr dev
, int numButtons
, Atom
*labels
,
1277 ButtonClassPtr butc
;
1280 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1281 BUG_RETURN_VAL(dev
->button
!= NULL
, FALSE
);
1282 BUG_RETURN_VAL(numButtons
>= MAX_BUTTONS
, FALSE
);
1284 butc
= calloc(1, sizeof(ButtonClassRec
));
1287 butc
->numButtons
= numButtons
;
1288 butc
->sourceid
= dev
->id
;
1289 for (i
= 1; i
<= numButtons
; i
++)
1290 butc
->map
[i
] = map
[i
];
1291 for (i
= numButtons
+ 1; i
< MAP_LENGTH
; i
++)
1293 memcpy(butc
->labels
, labels
, numButtons
* sizeof(Atom
));
1299 * Allocate a valuator class and set up the pointers for the axis values
1302 * @param src If non-NULL, the memory is reallocated from src. If NULL, the
1303 * memory is calloc'd.
1304 * @parma numAxes Number of axes to allocate.
1305 * @return The allocated valuator struct.
1308 AllocValuatorClass(ValuatorClassPtr src
, int numAxes
)
1312 /* force alignment with double */
1314 ValuatorClassRec valc
;
1320 sizeof(union align_u
) + numAxes
* (sizeof(double) + sizeof(AxisInfo
));
1321 align
= (union align_u
*) realloc(src
, size
);
1327 memset(align
, 0, size
);
1330 v
->numAxes
= numAxes
;
1331 v
->axisVal
= (double *) (align
+ 1);
1332 v
->axes
= (AxisInfoPtr
) (v
->axisVal
+ numAxes
);
1338 InitValuatorClassDeviceStruct(DeviceIntPtr dev
, int numAxes
, Atom
*labels
,
1339 int numMotionEvents
, int mode
)
1342 ValuatorClassPtr valc
;
1344 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1346 if (numAxes
> MAX_VALUATORS
) {
1347 LogMessage(X_WARNING
,
1348 "Device '%s' has %d axes, only using first %d.\n",
1349 dev
->name
, numAxes
, MAX_VALUATORS
);
1350 numAxes
= MAX_VALUATORS
;
1353 valc
= AllocValuatorClass(NULL
, numAxes
);
1357 dev
->last
.scroll
= valuator_mask_new(numAxes
);
1358 if (!dev
->last
.scroll
) {
1363 valc
->sourceid
= dev
->id
;
1364 valc
->motion
= NULL
;
1365 valc
->first_motion
= 0;
1366 valc
->last_motion
= 0;
1367 valc
->h_scroll_axis
= -1;
1368 valc
->v_scroll_axis
= -1;
1370 valc
->numMotionEvents
= numMotionEvents
;
1371 valc
->motionHintWindow
= NullWindow
;
1373 if ((mode
& OutOfProximity
) && !dev
->proximity
)
1374 InitProximityClassDeviceStruct(dev
);
1376 dev
->valuator
= valc
;
1378 AllocateMotionHistory(dev
);
1380 for (i
= 0; i
< numAxes
; i
++) {
1381 InitValuatorAxisStruct(dev
, i
, labels
[i
], NO_AXIS_LIMITS
,
1382 NO_AXIS_LIMITS
, 0, 0, 0, mode
);
1383 valc
->axisVal
[i
] = 0;
1386 dev
->last
.numValuators
= numAxes
;
1388 if (IsMaster(dev
) || /* do not accelerate master or xtest devices */
1389 IsXTestDevice(dev
, NULL
))
1390 InitPointerAccelerationScheme(dev
, PtrAccelNoOp
);
1392 InitPointerAccelerationScheme(dev
, PtrAccelDefault
);
1396 /* global list of acceleration schemes */
1397 ValuatorAccelerationRec pointerAccelerationScheme
[] = {
1398 {PtrAccelNoOp
, NULL
, NULL
, NULL
, NULL
},
1399 {PtrAccelPredictable
, acceleratePointerPredictable
, NULL
,
1400 InitPredictableAccelerationScheme
, AccelerationDefaultCleanup
},
1401 {PtrAccelLightweight
, acceleratePointerLightweight
, NULL
, NULL
, NULL
},
1402 {-1, NULL
, NULL
, NULL
, NULL
} /* terminator */
1406 * install an acceleration scheme. returns TRUE on success, and should not
1407 * change anything if unsuccessful.
1410 InitPointerAccelerationScheme(DeviceIntPtr dev
, int scheme
)
1413 ValuatorClassPtr val
;
1415 val
= dev
->valuator
;
1420 if (IsMaster(dev
) && scheme
!= PtrAccelNoOp
)
1423 for (x
= 0; pointerAccelerationScheme
[x
].number
>= 0; x
++) {
1424 if (pointerAccelerationScheme
[x
].number
== scheme
) {
1433 if (val
->accelScheme
.AccelCleanupProc
)
1434 val
->accelScheme
.AccelCleanupProc(dev
);
1436 if (pointerAccelerationScheme
[i
].AccelInitProc
) {
1437 if (!pointerAccelerationScheme
[i
].AccelInitProc(dev
,
1438 &pointerAccelerationScheme
[i
])) {
1443 val
->accelScheme
= pointerAccelerationScheme
[i
];
1449 InitFocusClassDeviceStruct(DeviceIntPtr dev
)
1453 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1454 BUG_RETURN_VAL(dev
->focus
!= NULL
, FALSE
);
1456 focc
= malloc(sizeof(FocusClassRec
));
1459 focc
->win
= PointerRootWin
;
1460 focc
->revert
= None
;
1461 focc
->time
= currentTime
;
1462 focc
->trace
= (WindowPtr
*) NULL
;
1463 focc
->traceSize
= 0;
1464 focc
->traceGood
= 0;
1465 focc
->sourceid
= dev
->id
;
1471 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev
, PtrCtrlProcPtr controlProc
)
1473 PtrFeedbackPtr feedc
;
1475 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1476 BUG_RETURN_VAL(dev
->ptrfeed
!= NULL
, FALSE
);
1478 feedc
= malloc(sizeof(PtrFeedbackClassRec
));
1481 feedc
->CtrlProc
= controlProc
;
1482 feedc
->ctrl
= defaultPointerControl
;
1484 if ((feedc
->next
= dev
->ptrfeed
))
1485 feedc
->ctrl
.id
= dev
->ptrfeed
->ctrl
.id
+ 1;
1486 dev
->ptrfeed
= feedc
;
1487 (*controlProc
) (dev
, &feedc
->ctrl
);
1491 static LedCtrl defaultLedControl
= {
1492 DEFAULT_LEDS
, DEFAULT_LEDS_MASK
, 0
1495 static BellCtrl defaultBellControl
= {
1498 DEFAULT_BELL_DURATION
,
1502 static IntegerCtrl defaultIntegerControl
= {
1503 DEFAULT_INT_RESOLUTION
,
1504 DEFAULT_INT_MIN_VALUE
,
1505 DEFAULT_INT_MAX_VALUE
,
1506 DEFAULT_INT_DISPLAYED
,
1511 InitStringFeedbackClassDeviceStruct(DeviceIntPtr dev
,
1512 StringCtrlProcPtr controlProc
,
1513 int max_symbols
, int num_symbols_supported
,
1517 StringFeedbackPtr feedc
;
1519 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1520 BUG_RETURN_VAL(dev
->stringfeed
!= NULL
, FALSE
);
1522 feedc
= malloc(sizeof(StringFeedbackClassRec
));
1525 feedc
->CtrlProc
= controlProc
;
1526 feedc
->ctrl
.num_symbols_supported
= num_symbols_supported
;
1527 feedc
->ctrl
.num_symbols_displayed
= 0;
1528 feedc
->ctrl
.max_symbols
= max_symbols
;
1529 feedc
->ctrl
.symbols_supported
=
1530 malloc(sizeof(KeySym
) * num_symbols_supported
);
1531 feedc
->ctrl
.symbols_displayed
= malloc(sizeof(KeySym
) * max_symbols
);
1532 if (!feedc
->ctrl
.symbols_supported
|| !feedc
->ctrl
.symbols_displayed
) {
1533 free(feedc
->ctrl
.symbols_supported
);
1534 free(feedc
->ctrl
.symbols_displayed
);
1538 for (i
= 0; i
< num_symbols_supported
; i
++)
1539 *(feedc
->ctrl
.symbols_supported
+ i
) = *symbols
++;
1540 for (i
= 0; i
< max_symbols
; i
++)
1541 *(feedc
->ctrl
.symbols_displayed
+ i
) = (KeySym
) 0;
1543 if ((feedc
->next
= dev
->stringfeed
))
1544 feedc
->ctrl
.id
= dev
->stringfeed
->ctrl
.id
+ 1;
1545 dev
->stringfeed
= feedc
;
1546 (*controlProc
) (dev
, &feedc
->ctrl
);
1551 InitBellFeedbackClassDeviceStruct(DeviceIntPtr dev
, BellProcPtr bellProc
,
1552 BellCtrlProcPtr controlProc
)
1554 BellFeedbackPtr feedc
;
1556 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1557 BUG_RETURN_VAL(dev
->bell
!= NULL
, FALSE
);
1559 feedc
= malloc(sizeof(BellFeedbackClassRec
));
1562 feedc
->CtrlProc
= controlProc
;
1563 feedc
->BellProc
= bellProc
;
1564 feedc
->ctrl
= defaultBellControl
;
1566 if ((feedc
->next
= dev
->bell
))
1567 feedc
->ctrl
.id
= dev
->bell
->ctrl
.id
+ 1;
1569 (*controlProc
) (dev
, &feedc
->ctrl
);
1574 InitLedFeedbackClassDeviceStruct(DeviceIntPtr dev
, LedCtrlProcPtr controlProc
)
1576 LedFeedbackPtr feedc
;
1578 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1579 BUG_RETURN_VAL(dev
->leds
!= NULL
, FALSE
);
1581 feedc
= malloc(sizeof(LedFeedbackClassRec
));
1584 feedc
->CtrlProc
= controlProc
;
1585 feedc
->ctrl
= defaultLedControl
;
1587 if ((feedc
->next
= dev
->leds
))
1588 feedc
->ctrl
.id
= dev
->leds
->ctrl
.id
+ 1;
1589 feedc
->xkb_sli
= NULL
;
1591 (*controlProc
) (dev
, &feedc
->ctrl
);
1596 InitIntegerFeedbackClassDeviceStruct(DeviceIntPtr dev
,
1597 IntegerCtrlProcPtr controlProc
)
1599 IntegerFeedbackPtr feedc
;
1601 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1602 BUG_RETURN_VAL(dev
->intfeed
!= NULL
, FALSE
);
1604 feedc
= malloc(sizeof(IntegerFeedbackClassRec
));
1607 feedc
->CtrlProc
= controlProc
;
1608 feedc
->ctrl
= defaultIntegerControl
;
1610 if ((feedc
->next
= dev
->intfeed
))
1611 feedc
->ctrl
.id
= dev
->intfeed
->ctrl
.id
+ 1;
1612 dev
->intfeed
= feedc
;
1613 (*controlProc
) (dev
, &feedc
->ctrl
);
1618 InitPointerDeviceStruct(DevicePtr device
, CARD8
*map
, int numButtons
,
1619 Atom
*btn_labels
, PtrCtrlProcPtr controlProc
,
1620 int numMotionEvents
, int numAxes
, Atom
*axes_labels
)
1622 DeviceIntPtr dev
= (DeviceIntPtr
) device
;
1624 BUG_RETURN_VAL(dev
== NULL
, FALSE
);
1625 BUG_RETURN_VAL(dev
->button
!= NULL
, FALSE
);
1626 BUG_RETURN_VAL(dev
->valuator
!= NULL
, FALSE
);
1627 BUG_RETURN_VAL(dev
->ptrfeed
!= NULL
, FALSE
);
1629 return (InitButtonClassDeviceStruct(dev
, numButtons
, btn_labels
, map
) &&
1630 InitValuatorClassDeviceStruct(dev
, numAxes
, axes_labels
,
1631 numMotionEvents
, Relative
) &&
1632 InitPtrFeedbackClassDeviceStruct(dev
, controlProc
));
1636 * Sets up multitouch capabilities on @device.
1638 * @max_touches The maximum number of simultaneous touches, or 0 for unlimited.
1639 * @mode The mode of the touch device (XIDirectTouch or XIDependentTouch).
1640 * @num_axes The number of touch valuator axes.
1643 InitTouchClassDeviceStruct(DeviceIntPtr device
, unsigned int max_touches
,
1644 unsigned int mode
, unsigned int num_axes
)
1646 TouchClassPtr touch
;
1649 BUG_RETURN_VAL(device
== NULL
, FALSE
);
1650 BUG_RETURN_VAL(device
->touch
!= NULL
, FALSE
);
1651 BUG_RETURN_VAL(device
->valuator
== NULL
, FALSE
);
1653 /* Check the mode is valid, and at least X and Y axes. */
1654 BUG_RETURN_VAL(mode
!= XIDirectTouch
&& mode
!= XIDependentTouch
, FALSE
);
1655 BUG_RETURN_VAL(num_axes
< 2, FALSE
);
1657 if (num_axes
> MAX_VALUATORS
) {
1658 LogMessage(X_WARNING
,
1659 "Device '%s' has %d touch axes, only using first %d.\n",
1660 device
->name
, num_axes
, MAX_VALUATORS
);
1661 num_axes
= MAX_VALUATORS
;
1664 touch
= calloc(1, sizeof(*touch
));
1668 touch
->max_touches
= max_touches
;
1669 if (max_touches
== 0)
1670 max_touches
= 5; /* arbitrary number plucked out of the air */
1671 touch
->touches
= calloc(max_touches
, sizeof(*touch
->touches
));
1672 if (!touch
->touches
)
1674 touch
->num_touches
= max_touches
;
1675 for (i
= 0; i
< max_touches
; i
++)
1676 TouchInitTouchPoint(touch
, device
->valuator
, i
);
1679 touch
->sourceid
= device
->id
;
1681 device
->touch
= touch
;
1682 device
->last
.touches
= calloc(max_touches
, sizeof(*device
->last
.touches
));
1683 device
->last
.num_touches
= touch
->num_touches
;
1684 for (i
= 0; i
< touch
->num_touches
; i
++)
1685 TouchInitDDXTouchPoint(device
, &device
->last
.touches
[i
]);
1690 for (i
= 0; i
< touch
->num_touches
; i
++)
1691 TouchFreeTouchPoint(device
, i
);
1693 free(touch
->touches
);
1700 * Check if the given buffer contains elements between low (inclusive) and
1701 * high (inclusive) only.
1703 * @return TRUE if the device map is invalid, FALSE otherwise.
1706 BadDeviceMap(BYTE
* buff
, int length
, unsigned low
, unsigned high
, XID
*errval
)
1710 for (i
= 0; i
< length
; i
++)
1711 if (buff
[i
]) { /* only check non-zero elements */
1712 if ((low
> buff
[i
]) || (high
< buff
[i
])) {
1721 ProcSetModifierMapping(ClientPtr client
)
1723 xSetModifierMappingReply rep
;
1726 REQUEST(xSetModifierMappingReq
);
1727 REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq
);
1729 if (client
->req_len
!= ((stuff
->numKeyPerModifier
<< 1) +
1730 bytes_to_int32(sizeof(xSetModifierMappingReq
))))
1733 rep
= (xSetModifierMappingReply
) {
1735 .sequenceNumber
= client
->sequence
,
1739 rc
= change_modmap(client
, PickKeyboard(client
), (KeyCode
*) &stuff
[1],
1740 stuff
->numKeyPerModifier
);
1741 if (rc
== MappingFailed
|| rc
== -1)
1743 if (rc
!= Success
&& rc
!= MappingSuccess
&& rc
!= MappingFailed
&&
1749 WriteReplyToClient(client
, sizeof(xSetModifierMappingReply
), &rep
);
1754 ProcGetModifierMapping(ClientPtr client
)
1756 xGetModifierMappingReply rep
;
1757 int max_keys_per_mod
= 0;
1758 KeyCode
*modkeymap
= NULL
;
1760 REQUEST_SIZE_MATCH(xReq
);
1762 generate_modkeymap(client
, PickKeyboard(client
), &modkeymap
,
1765 rep
= (xGetModifierMappingReply
) {
1767 .numKeyPerModifier
= max_keys_per_mod
,
1768 .sequenceNumber
= client
->sequence
,
1769 /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1770 .length
= max_keys_per_mod
<< 1
1773 WriteReplyToClient(client
, sizeof(xGetModifierMappingReply
), &rep
);
1774 WriteToClient(client
, max_keys_per_mod
* 8, modkeymap
);
1782 ProcChangeKeyboardMapping(ClientPtr client
)
1784 REQUEST(xChangeKeyboardMappingReq
);
1787 DeviceIntPtr pDev
, tmp
;
1790 REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq
);
1792 len
= client
->req_len
- bytes_to_int32(sizeof(xChangeKeyboardMappingReq
));
1793 if (len
!= (stuff
->keyCodes
* stuff
->keySymsPerKeyCode
))
1796 pDev
= PickKeyboard(client
);
1798 if ((stuff
->firstKeyCode
< pDev
->key
->xkbInfo
->desc
->min_key_code
) ||
1799 (stuff
->firstKeyCode
> pDev
->key
->xkbInfo
->desc
->max_key_code
)) {
1800 client
->errorValue
= stuff
->firstKeyCode
;
1804 if (((unsigned) (stuff
->firstKeyCode
+ stuff
->keyCodes
- 1) >
1805 pDev
->key
->xkbInfo
->desc
->max_key_code
) ||
1806 (stuff
->keySymsPerKeyCode
== 0)) {
1807 client
->errorValue
= stuff
->keySymsPerKeyCode
;
1811 keysyms
.minKeyCode
= stuff
->firstKeyCode
;
1812 keysyms
.maxKeyCode
= stuff
->firstKeyCode
+ stuff
->keyCodes
- 1;
1813 keysyms
.mapWidth
= stuff
->keySymsPerKeyCode
;
1814 keysyms
.map
= (KeySym
*) &stuff
[1];
1816 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, pDev
, DixManageAccess
);
1820 XkbApplyMappingChange(pDev
, &keysyms
, stuff
->firstKeyCode
,
1821 stuff
->keyCodes
, NULL
, client
);
1823 for (tmp
= inputInfo
.devices
; tmp
; tmp
= tmp
->next
) {
1824 if (IsMaster(tmp
) || GetMaster(tmp
, MASTER_KEYBOARD
) != pDev
)
1829 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, pDev
, DixManageAccess
);
1833 XkbApplyMappingChange(tmp
, &keysyms
, stuff
->firstKeyCode
,
1834 stuff
->keyCodes
, NULL
, client
);
1841 ProcSetPointerMapping(ClientPtr client
)
1846 DeviceIntPtr ptr
= PickPointer(client
);
1847 xSetPointerMappingReply rep
;
1849 REQUEST(xSetPointerMappingReq
);
1850 REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq
);
1852 if (client
->req_len
!=
1853 bytes_to_int32(sizeof(xSetPointerMappingReq
) + stuff
->nElts
))
1856 rep
= (xSetPointerMappingReply
) {
1858 .success
= MappingSuccess
,
1859 .sequenceNumber
= client
->sequence
,
1862 map
= (BYTE
*) &stuff
[1];
1864 /* So we're bounded here by the number of core buttons. This check
1865 * probably wants disabling through XFixes. */
1866 /* MPX: With ClientPointer, we can return the right number of buttons.
1867 * Let's just hope nobody changed ClientPointer between GetPointerMapping
1868 * and SetPointerMapping
1870 if (stuff
->nElts
!= ptr
->button
->numButtons
) {
1871 client
->errorValue
= stuff
->nElts
;
1875 /* Core protocol specs don't allow for duplicate mappings; this check
1876 * almost certainly wants disabling through XFixes too. */
1877 for (i
= 0; i
< stuff
->nElts
; i
++) {
1878 for (j
= i
+ 1; j
< stuff
->nElts
; j
++) {
1879 if (map
[i
] && map
[i
] == map
[j
]) {
1880 client
->errorValue
= map
[i
];
1886 ret
= ApplyPointerMapping(ptr
, map
, stuff
->nElts
, client
);
1887 if (ret
== MappingBusy
)
1891 else if (ret
!= Success
)
1894 WriteReplyToClient(client
, sizeof(xSetPointerMappingReply
), &rep
);
1899 ProcGetKeyboardMapping(ClientPtr client
)
1901 xGetKeyboardMappingReply rep
;
1902 DeviceIntPtr kbd
= PickKeyboard(client
);
1907 REQUEST(xGetKeyboardMappingReq
);
1908 REQUEST_SIZE_MATCH(xGetKeyboardMappingReq
);
1910 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, kbd
, DixGetAttrAccess
);
1914 xkb
= kbd
->key
->xkbInfo
->desc
;
1916 if ((stuff
->firstKeyCode
< xkb
->min_key_code
) ||
1917 (stuff
->firstKeyCode
> xkb
->max_key_code
)) {
1918 client
->errorValue
= stuff
->firstKeyCode
;
1921 if (stuff
->firstKeyCode
+ stuff
->count
> xkb
->max_key_code
+ 1) {
1922 client
->errorValue
= stuff
->count
;
1926 syms
= XkbGetCoreMap(kbd
);
1930 rep
= (xGetKeyboardMappingReply
) {
1932 .keySymsPerKeyCode
= syms
->mapWidth
,
1933 .sequenceNumber
= client
->sequence
,
1934 /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
1935 .length
= syms
->mapWidth
* stuff
->count
1937 WriteReplyToClient(client
, sizeof(xGetKeyboardMappingReply
), &rep
);
1938 client
->pSwapReplyFunc
= (ReplySwapPtr
) CopySwap32Write
;
1939 WriteSwappedDataToClient(client
,
1940 syms
->mapWidth
* stuff
->count
* sizeof(KeySym
),
1941 &syms
->map
[syms
->mapWidth
* (stuff
->firstKeyCode
-
1942 syms
->minKeyCode
)]);
1950 ProcGetPointerMapping(ClientPtr client
)
1952 xGetPointerMappingReply rep
;
1954 /* Apps may get different values each time they call GetPointerMapping as
1955 * the ClientPointer could change. */
1956 DeviceIntPtr ptr
= PickPointer(client
);
1957 ButtonClassPtr butc
= ptr
->button
;
1961 REQUEST_SIZE_MATCH(xReq
);
1963 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, ptr
, DixGetAttrAccess
);
1967 nElts
= (butc
) ? butc
->numButtons
: 0;
1968 rep
= (xGetPointerMappingReply
) {
1971 .sequenceNumber
= client
->sequence
,
1972 .length
= ((unsigned) nElts
+ (4 - 1)) / 4
1974 WriteReplyToClient(client
, sizeof(xGetPointerMappingReply
), &rep
);
1976 WriteToClient(client
, nElts
, &butc
->map
[1]);
1981 NoteLedState(DeviceIntPtr keybd
, int led
, Bool on
)
1983 KeybdCtrl
*ctrl
= &keybd
->kbdfeed
->ctrl
;
1986 ctrl
->leds
|= ((Leds
) 1 << (led
- 1));
1988 ctrl
->leds
&= ~((Leds
) 1 << (led
- 1));
1992 Ones(unsigned long mask
)
1996 y
= (mask
>> 1) & 033333333333;
1997 y
= mask
- y
- ((y
>> 1) & 033333333333);
1998 return (((y
+ (y
>> 3)) & 030707070707) % 077);
2002 DoChangeKeyboardControl(ClientPtr client
, DeviceIntPtr keybd
, XID
*vlist
,
2011 int mask
= vmask
, i
;
2012 XkbEventCauseRec cause
;
2014 ctrl
= keybd
->kbdfeed
->ctrl
;
2016 index2
= (BITS32
) lowbit(vmask
);
2019 case KBKeyClickPercent
:
2023 t
= defaultKeyboardControl
.click
;
2025 else if (t
< 0 || t
> 100) {
2026 client
->errorValue
= t
;
2035 t
= defaultKeyboardControl
.bell
;
2037 else if (t
< 0 || t
> 100) {
2038 client
->errorValue
= t
;
2047 t
= defaultKeyboardControl
.bell_pitch
;
2050 client
->errorValue
= t
;
2053 ctrl
.bell_pitch
= t
;
2055 case KBBellDuration
:
2059 t
= defaultKeyboardControl
.bell_duration
;
2061 client
->errorValue
= t
;
2064 ctrl
.bell_duration
= t
;
2067 led
= (CARD8
) *vlist
;
2069 if (led
< 1 || led
> 32) {
2070 client
->errorValue
= led
;
2073 if (!(mask
& KBLedMode
))
2079 if (t
== LedModeOff
) {
2083 ctrl
.leds
&= ~(((Leds
) (1)) << (led
- 1));
2085 else if (t
== LedModeOn
) {
2089 ctrl
.leds
|= (((Leds
) (1)) << (led
- 1));
2092 client
->errorValue
= t
;
2096 XkbSetCauseCoreReq(&cause
, X_ChangeKeyboardControl
, client
);
2097 XkbSetIndicators(keybd
, ((led
== DO_ALL
) ? ~0L : (1L << (led
- 1))),
2099 ctrl
.leds
= keybd
->kbdfeed
->ctrl
.leds
;
2103 key
= (KeyCode
) *vlist
;
2105 if ((KeyCode
) key
< keybd
->key
->xkbInfo
->desc
->min_key_code
||
2106 (KeyCode
) key
> keybd
->key
->xkbInfo
->desc
->max_key_code
) {
2107 client
->errorValue
= key
;
2110 if (!(mask
& KBAutoRepeatMode
))
2113 case KBAutoRepeatMode
:
2115 mask
= (1 << (key
& 7));
2119 XkbDisableComputedAutoRepeats(keybd
, key
);
2120 if (t
== AutoRepeatModeOff
) {
2122 ctrl
.autoRepeat
= FALSE
;
2124 ctrl
.autoRepeats
[i
] &= ~mask
;
2126 else if (t
== AutoRepeatModeOn
) {
2128 ctrl
.autoRepeat
= TRUE
;
2130 ctrl
.autoRepeats
[i
] |= mask
;
2132 else if (t
== AutoRepeatModeDefault
) {
2134 ctrl
.autoRepeat
= defaultKeyboardControl
.autoRepeat
;
2136 ctrl
.autoRepeats
[i
] =
2137 (ctrl
.autoRepeats
[i
] & ~mask
) |
2138 (defaultKeyboardControl
.autoRepeats
[i
] & mask
);
2141 client
->errorValue
= t
;
2146 client
->errorValue
= mask
;
2150 keybd
->kbdfeed
->ctrl
= ctrl
;
2152 /* The XKB RepeatKeys control and core protocol global autorepeat */
2153 /* value are linked */
2154 XkbSetRepeatKeys(keybd
, key
, keybd
->kbdfeed
->ctrl
.autoRepeat
);
2162 * Changes kbd control on the ClientPointer and all attached SDs.
2165 ProcChangeKeyboardControl(ClientPtr client
)
2169 int ret
= Success
, error
= Success
;
2170 DeviceIntPtr pDev
= NULL
, keyboard
;
2172 REQUEST(xChangeKeyboardControlReq
);
2174 REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq
);
2176 vmask
= stuff
->mask
;
2177 vlist
= (XID
*) &stuff
[1];
2179 if (client
->req_len
!=
2180 (sizeof(xChangeKeyboardControlReq
) >> 2) + Ones(vmask
))
2183 keyboard
= PickKeyboard(client
);
2185 for (pDev
= inputInfo
.devices
; pDev
; pDev
= pDev
->next
) {
2186 if ((pDev
== keyboard
||
2187 (!IsMaster(pDev
) && GetMaster(pDev
, MASTER_KEYBOARD
) == keyboard
))
2188 && pDev
->kbdfeed
&& pDev
->kbdfeed
->CtrlProc
) {
2189 ret
= XaceHook(XACE_DEVICE_ACCESS
, client
, pDev
, DixManageAccess
);
2195 for (pDev
= inputInfo
.devices
; pDev
; pDev
= pDev
->next
) {
2196 if ((pDev
== keyboard
||
2197 (!IsMaster(pDev
) && GetMaster(pDev
, MASTER_KEYBOARD
) == keyboard
))
2198 && pDev
->kbdfeed
&& pDev
->kbdfeed
->CtrlProc
) {
2199 ret
= DoChangeKeyboardControl(client
, pDev
, vlist
, vmask
);
2209 ProcGetKeyboardControl(ClientPtr client
)
2212 DeviceIntPtr kbd
= PickKeyboard(client
);
2213 KeybdCtrl
*ctrl
= &kbd
->kbdfeed
->ctrl
;
2214 xGetKeyboardControlReply rep
;
2216 REQUEST_SIZE_MATCH(xReq
);
2218 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, kbd
, DixGetAttrAccess
);
2222 rep
= (xGetKeyboardControlReply
) {
2224 .globalAutoRepeat
= ctrl
->autoRepeat
,
2225 .sequenceNumber
= client
->sequence
,
2227 .ledMask
= ctrl
->leds
,
2228 .keyClickPercent
= ctrl
->click
,
2229 .bellPercent
= ctrl
->bell
,
2230 .bellPitch
= ctrl
->bell_pitch
,
2231 .bellDuration
= ctrl
->bell_duration
2233 for (i
= 0; i
< 32; i
++)
2234 rep
.map
[i
] = ctrl
->autoRepeats
[i
];
2235 WriteReplyToClient(client
, sizeof(xGetKeyboardControlReply
), &rep
);
2240 ProcBell(ClientPtr client
)
2242 DeviceIntPtr dev
, keybd
= PickKeyboard(client
);
2243 int base
= keybd
->kbdfeed
->ctrl
.bell
;
2248 REQUEST_SIZE_MATCH(xBellReq
);
2250 if (stuff
->percent
< -100 || stuff
->percent
> 100) {
2251 client
->errorValue
= stuff
->percent
;
2255 newpercent
= (base
* stuff
->percent
) / 100;
2256 if (stuff
->percent
< 0)
2257 newpercent
= base
+ newpercent
;
2259 newpercent
= base
- newpercent
+ stuff
->percent
;
2261 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
2262 if ((dev
== keybd
||
2263 (!IsMaster(dev
) && GetMaster(dev
, MASTER_KEYBOARD
) == keybd
)) &&
2264 dev
->kbdfeed
&& dev
->kbdfeed
->BellProc
) {
2266 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, dev
, DixBellAccess
);
2269 XkbHandleBell(FALSE
, FALSE
, dev
, newpercent
,
2270 &dev
->kbdfeed
->ctrl
, 0, None
, NULL
, client
);
2278 ProcChangePointerControl(ClientPtr client
)
2280 DeviceIntPtr dev
, mouse
= PickPointer(client
);
2281 PtrCtrl ctrl
; /* might get BadValue part way through */
2284 REQUEST(xChangePointerControlReq
);
2285 REQUEST_SIZE_MATCH(xChangePointerControlReq
);
2287 ctrl
= mouse
->ptrfeed
->ctrl
;
2288 if ((stuff
->doAccel
!= xTrue
) && (stuff
->doAccel
!= xFalse
)) {
2289 client
->errorValue
= stuff
->doAccel
;
2292 if ((stuff
->doThresh
!= xTrue
) && (stuff
->doThresh
!= xFalse
)) {
2293 client
->errorValue
= stuff
->doThresh
;
2296 if (stuff
->doAccel
) {
2297 if (stuff
->accelNum
== -1) {
2298 ctrl
.num
= defaultPointerControl
.num
;
2300 else if (stuff
->accelNum
< 0) {
2301 client
->errorValue
= stuff
->accelNum
;
2305 ctrl
.num
= stuff
->accelNum
;
2308 if (stuff
->accelDenum
== -1) {
2309 ctrl
.den
= defaultPointerControl
.den
;
2311 else if (stuff
->accelDenum
<= 0) {
2312 client
->errorValue
= stuff
->accelDenum
;
2316 ctrl
.den
= stuff
->accelDenum
;
2319 if (stuff
->doThresh
) {
2320 if (stuff
->threshold
== -1) {
2321 ctrl
.threshold
= defaultPointerControl
.threshold
;
2323 else if (stuff
->threshold
< 0) {
2324 client
->errorValue
= stuff
->threshold
;
2328 ctrl
.threshold
= stuff
->threshold
;
2332 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
2333 if ((dev
== mouse
||
2334 (!IsMaster(dev
) && GetMaster(dev
, MASTER_POINTER
) == mouse
)) &&
2336 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, dev
, DixManageAccess
);
2342 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
2343 if ((dev
== mouse
||
2344 (!IsMaster(dev
) && GetMaster(dev
, MASTER_POINTER
) == mouse
)) &&
2346 dev
->ptrfeed
->ctrl
= ctrl
;
2354 ProcGetPointerControl(ClientPtr client
)
2356 DeviceIntPtr ptr
= PickPointer(client
);
2357 PtrCtrl
*ctrl
= &ptr
->ptrfeed
->ctrl
;
2358 xGetPointerControlReply rep
;
2361 REQUEST_SIZE_MATCH(xReq
);
2363 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, ptr
, DixGetAttrAccess
);
2367 rep
= (xGetPointerControlReply
) {
2369 .sequenceNumber
= client
->sequence
,
2371 .accelNumerator
= ctrl
->num
,
2372 .accelDenominator
= ctrl
->den
,
2373 .threshold
= ctrl
->threshold
2375 WriteReplyToClient(client
, sizeof(xGenericReply
), &rep
);
2380 MaybeStopHint(DeviceIntPtr dev
, ClientPtr client
)
2382 GrabPtr grab
= dev
->deviceGrab
.grab
;
2384 if ((grab
&& SameClient(grab
, client
) &&
2385 ((grab
->eventMask
& PointerMotionHintMask
) ||
2386 (grab
->ownerEvents
&&
2387 (EventMaskForClient(dev
->valuator
->motionHintWindow
, client
) &
2388 PointerMotionHintMask
)))) ||
2390 (EventMaskForClient(dev
->valuator
->motionHintWindow
, client
) &
2391 PointerMotionHintMask
)))
2392 dev
->valuator
->motionHintWindow
= NullWindow
;
2396 ProcGetMotionEvents(ClientPtr client
)
2399 xTimecoord
*coords
= (xTimecoord
*) NULL
;
2400 xGetMotionEventsReply rep
;
2401 int i
, count
, xmin
, xmax
, ymin
, ymax
, rc
;
2402 unsigned long nEvents
;
2403 DeviceIntPtr mouse
= PickPointer(client
);
2404 TimeStamp start
, stop
;
2406 REQUEST(xGetMotionEventsReq
);
2407 REQUEST_SIZE_MATCH(xGetMotionEventsReq
);
2409 rc
= dixLookupWindow(&pWin
, stuff
->window
, client
, DixGetAttrAccess
);
2412 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, mouse
, DixReadAccess
);
2416 if (mouse
->valuator
->motionHintWindow
)
2417 MaybeStopHint(mouse
, client
);
2418 rep
= (xGetMotionEventsReply
) {
2420 .sequenceNumber
= client
->sequence
2423 start
= ClientTimeToServerTime(stuff
->start
);
2424 stop
= ClientTimeToServerTime(stuff
->stop
);
2425 if ((CompareTimeStamps(start
, stop
) != LATER
) &&
2426 (CompareTimeStamps(start
, currentTime
) != LATER
) &&
2427 mouse
->valuator
->numMotionEvents
) {
2428 if (CompareTimeStamps(stop
, currentTime
) == LATER
)
2430 count
= GetMotionHistory(mouse
, &coords
, start
.milliseconds
,
2431 stop
.milliseconds
, pWin
->drawable
.pScreen
,
2433 xmin
= pWin
->drawable
.x
- wBorderWidth(pWin
);
2434 xmax
= pWin
->drawable
.x
+ (int) pWin
->drawable
.width
+
2436 ymin
= pWin
->drawable
.y
- wBorderWidth(pWin
);
2437 ymax
= pWin
->drawable
.y
+ (int) pWin
->drawable
.height
+
2439 for (i
= 0; i
< count
; i
++)
2440 if ((xmin
<= coords
[i
].x
) && (coords
[i
].x
< xmax
) &&
2441 (ymin
<= coords
[i
].y
) && (coords
[i
].y
< ymax
)) {
2442 coords
[nEvents
].time
= coords
[i
].time
;
2443 coords
[nEvents
].x
= coords
[i
].x
- pWin
->drawable
.x
;
2444 coords
[nEvents
].y
= coords
[i
].y
- pWin
->drawable
.y
;
2448 rep
.length
= nEvents
* bytes_to_int32(sizeof(xTimecoord
));
2449 rep
.nEvents
= nEvents
;
2450 WriteReplyToClient(client
, sizeof(xGetMotionEventsReply
), &rep
);
2452 client
->pSwapReplyFunc
= (ReplySwapPtr
) SwapTimeCoordWrite
;
2453 WriteSwappedDataToClient(client
, nEvents
* sizeof(xTimecoord
),
2461 ProcQueryKeymap(ClientPtr client
)
2463 xQueryKeymapReply rep
;
2465 DeviceIntPtr keybd
= PickKeyboard(client
);
2466 CARD8
*down
= keybd
->key
->down
;
2468 REQUEST_SIZE_MATCH(xReq
);
2469 rep
= (xQueryKeymapReply
) {
2471 .sequenceNumber
= client
->sequence
,
2475 rc
= XaceHook(XACE_DEVICE_ACCESS
, client
, keybd
, DixReadAccess
);
2476 /* If rc is Success, we're allowed to copy out the keymap.
2477 * If it's BadAccess, we leave it empty & lie to the client.
2479 if (rc
== Success
) {
2480 for (i
= 0; i
< 32; i
++)
2481 rep
.map
[i
] = down
[i
];
2483 else if (rc
!= BadAccess
)
2486 WriteReplyToClient(client
, sizeof(xQueryKeymapReply
), &rep
);
2492 * Recalculate the number of buttons for the master device. The number of
2493 * buttons on the master device is equal to the number of buttons on the
2494 * slave device with the highest number of buttons.
2497 RecalculateMasterButtons(DeviceIntPtr slave
)
2499 DeviceIntPtr dev
, master
;
2502 if (!slave
->button
|| IsMaster(slave
))
2505 master
= GetMaster(slave
, MASTER_POINTER
);
2509 for (dev
= inputInfo
.devices
; dev
; dev
= dev
->next
) {
2510 if (IsMaster(dev
) ||
2511 GetMaster(dev
, MASTER_ATTACHED
) != master
|| !dev
->button
)
2514 maxbuttons
= max(maxbuttons
, dev
->button
->numButtons
);
2517 if (master
->button
&& master
->button
->numButtons
!= maxbuttons
) {
2519 DeviceChangedEvent event
= {
2520 .header
= ET_Internal
,
2521 .type
= ET_DeviceChanged
,
2522 .time
= GetTimeInMillis(),
2523 .deviceid
= master
->id
,
2524 .flags
= DEVCHANGE_POINTER_EVENT
| DEVCHANGE_DEVICE_CHANGE
,
2525 .buttons
.num_buttons
= maxbuttons
2528 master
->button
->numButtons
= maxbuttons
;
2530 memcpy(&event
.buttons
.names
, master
->button
->labels
, maxbuttons
*
2533 if (master
->valuator
) {
2534 event
.num_valuators
= master
->valuator
->numAxes
;
2535 for (i
= 0; i
< event
.num_valuators
; i
++) {
2536 event
.valuators
[i
].min
= master
->valuator
->axes
[i
].min_value
;
2537 event
.valuators
[i
].max
= master
->valuator
->axes
[i
].max_value
;
2538 event
.valuators
[i
].resolution
=
2539 master
->valuator
->axes
[i
].resolution
;
2540 event
.valuators
[i
].mode
= master
->valuator
->axes
[i
].mode
;
2541 event
.valuators
[i
].name
= master
->valuator
->axes
[i
].label
;
2546 event
.keys
.min_keycode
= master
->key
->xkbInfo
->desc
->min_key_code
;
2547 event
.keys
.max_keycode
= master
->key
->xkbInfo
->desc
->max_key_code
;
2550 XISendDeviceChangedEvent(master
, &event
);
2555 * Generate release events for all keys/button currently down on this
2559 ReleaseButtonsAndKeys(DeviceIntPtr dev
)
2561 InternalEvent
*eventlist
= InitEventList(GetMaximumEventsNum());
2562 ButtonClassPtr b
= dev
->button
;
2563 KeyClassPtr k
= dev
->key
;
2566 if (!eventlist
) /* no release events for you */
2569 /* Release all buttons */
2570 for (i
= 0; b
&& i
< b
->numButtons
; i
++) {
2571 if (BitIsOn(b
->down
, i
)) {
2573 GetPointerEvents(eventlist
, dev
, ButtonRelease
, i
, 0, NULL
);
2574 for (j
= 0; j
< nevents
; j
++)
2575 mieqProcessDeviceEvent(dev
, &eventlist
[j
], NULL
);
2579 /* Release all keys */
2580 for (i
= 0; k
&& i
< MAP_LENGTH
; i
++) {
2581 if (BitIsOn(k
->down
, i
)) {
2582 nevents
= GetKeyboardEvents(eventlist
, dev
, KeyRelease
, i
, NULL
);
2583 for (j
= 0; j
< nevents
; j
++)
2584 mieqProcessDeviceEvent(dev
, &eventlist
[j
], NULL
);
2588 FreeEventList(eventlist
, GetMaximumEventsNum());
2592 * Attach device 'dev' to device 'master'.
2593 * Client is set to the client that issued the request, or NULL if it comes
2594 * from some internal automatic pairing.
2596 * Master may be NULL to set the device floating.
2598 * We don't allow multi-layer hierarchies right now. You can't attach a slave
2602 AttachDevice(ClientPtr client
, DeviceIntPtr dev
, DeviceIntPtr master
)
2606 if (!dev
|| IsMaster(dev
))
2609 if (master
&& !IsMaster(master
)) /* can't attach to slaves */
2612 /* set from floating to floating? */
2613 if (IsFloating(dev
) && !master
&& dev
->enabled
)
2616 /* free the existing sprite. */
2617 if (IsFloating(dev
) && dev
->spriteInfo
->paired
== dev
) {
2618 screen
= miPointerGetScreen(dev
);
2619 screen
->DeviceCursorCleanup(dev
, screen
);
2620 free(dev
->spriteInfo
->sprite
);
2623 dev
->master
= master
;
2625 /* If device is set to floating, we need to create a sprite for it,
2626 * otherwise things go bad. However, we don't want to render the cursor,
2627 * so we reset spriteOwner.
2628 * Sprite has to be forced to NULL first, otherwise InitializeSprite won't
2629 * alloc new memory but overwrite the previous one.
2632 WindowPtr currentRoot
;
2634 if (dev
->spriteInfo
->sprite
)
2635 currentRoot
= GetCurrentRootWindow(dev
);
2636 else /* new device auto-set to floating */
2637 currentRoot
= screenInfo
.screens
[0]->root
;
2639 /* we need to init a fake sprite */
2640 screen
= currentRoot
->drawable
.pScreen
;
2641 screen
->DeviceCursorInitialize(dev
, screen
);
2642 dev
->spriteInfo
->sprite
= NULL
;
2643 InitializeSprite(dev
, currentRoot
);
2644 dev
->spriteInfo
->spriteOwner
= FALSE
;
2645 dev
->spriteInfo
->paired
= dev
;
2648 dev
->spriteInfo
->sprite
= master
->spriteInfo
->sprite
;
2649 dev
->spriteInfo
->paired
= master
;
2650 dev
->spriteInfo
->spriteOwner
= FALSE
;
2652 RecalculateMasterButtons(master
);
2655 /* XXX: in theory, the MD should change back to its old, original
2656 * classes when the last SD is detached. Thanks to the XTEST devices,
2657 * we'll always have an SD attached until the MD is removed.
2658 * So let's not worry about that.
2665 * Return the device paired with the given device or NULL.
2666 * Returns the device paired with the parent master if the given device is a
2670 GetPairedDevice(DeviceIntPtr dev
)
2672 if (!IsMaster(dev
) && !IsFloating(dev
))
2673 dev
= GetMaster(dev
, MASTER_ATTACHED
);
2675 return dev
->spriteInfo
->paired
;
2679 * Returns the requested master for this device.
2680 * The return values are:
2681 * - MASTER_ATTACHED: the master for this device or NULL for a floating
2683 * - MASTER_KEYBOARD: the master keyboard for this device or NULL for a
2685 * - MASTER_POINTER: the master keyboard for this device or NULL for a
2687 * - POINTER_OR_FLOAT: the master pointer for this device or the device for
2689 * - KEYBOARD_OR_FLOAT: the master keyboard for this device or the device for
2692 * @param which ::MASTER_KEYBOARD or ::MASTER_POINTER, ::MASTER_ATTACHED,
2693 * ::POINTER_OR_FLOAT or ::KEYBOARD_OR_FLOAT.
2694 * @return The requested master device
2697 GetMaster(DeviceIntPtr dev
, int which
)
2699 DeviceIntPtr master
;
2704 master
= dev
->master
;
2706 (which
== POINTER_OR_FLOAT
|| which
== KEYBOARD_OR_FLOAT
))
2710 if (master
&& which
!= MASTER_ATTACHED
) {
2711 if (which
== MASTER_KEYBOARD
|| which
== KEYBOARD_OR_FLOAT
) {
2712 if (master
->type
!= MASTER_KEYBOARD
)
2713 master
= GetPairedDevice(master
);
2716 if (master
->type
!= MASTER_POINTER
)
2717 master
= GetPairedDevice(master
);
2725 * Create a new device pair (== one pointer, one keyboard device).
2726 * Only allocates the devices, you will need to call ActivateDevice() and
2727 * EnableDevice() manually.
2728 * Either a master or a slave device can be created depending on
2729 * the value for master.
2732 AllocDevicePair(ClientPtr client
, const char *name
,
2734 DeviceIntPtr
*keybd
,
2735 DeviceProc ptr_proc
, DeviceProc keybd_proc
, Bool master
)
2737 DeviceIntPtr pointer
;
2738 DeviceIntPtr keyboard
;
2740 *ptr
= *keybd
= NULL
;
2744 pointer
= AddInputDevice(client
, ptr_proc
, TRUE
);
2749 if (asprintf(&pointer
->name
, "%s pointer", name
) == -1) {
2750 pointer
->name
= NULL
;
2751 RemoveDevice(pointer
, FALSE
);
2756 pointer
->public.processInputProc
= ProcessOtherEvent
;
2757 pointer
->public.realInputProc
= ProcessOtherEvent
;
2758 XkbSetExtension(pointer
, ProcessPointerEvent
);
2759 pointer
->deviceGrab
.ActivateGrab
= ActivatePointerGrab
;
2760 pointer
->deviceGrab
.DeactivateGrab
= DeactivatePointerGrab
;
2761 pointer
->coreEvents
= TRUE
;
2762 pointer
->spriteInfo
->spriteOwner
= TRUE
;
2764 pointer
->lastSlave
= NULL
;
2765 pointer
->last
.slave
= NULL
;
2766 pointer
->type
= (master
) ? MASTER_POINTER
: SLAVE
;
2768 keyboard
= AddInputDevice(client
, keybd_proc
, TRUE
);
2770 RemoveDevice(pointer
, FALSE
);
2775 if (asprintf(&keyboard
->name
, "%s keyboard", name
) == -1) {
2776 keyboard
->name
= NULL
;
2777 RemoveDevice(keyboard
, FALSE
);
2778 RemoveDevice(pointer
, FALSE
);
2783 keyboard
->public.processInputProc
= ProcessOtherEvent
;
2784 keyboard
->public.realInputProc
= ProcessOtherEvent
;
2785 XkbSetExtension(keyboard
, ProcessKeyboardEvent
);
2786 keyboard
->deviceGrab
.ActivateGrab
= ActivateKeyboardGrab
;
2787 keyboard
->deviceGrab
.DeactivateGrab
= DeactivateKeyboardGrab
;
2788 keyboard
->coreEvents
= TRUE
;
2789 keyboard
->spriteInfo
->spriteOwner
= FALSE
;
2791 keyboard
->lastSlave
= NULL
;
2792 keyboard
->last
.slave
= NULL
;
2793 keyboard
->type
= (master
) ? MASTER_KEYBOARD
: SLAVE
;
2795 /* The ClassesRec stores the device classes currently not used. */
2796 if (IsMaster(pointer
)) {
2797 pointer
->unused_classes
= calloc(1, sizeof(ClassesRec
));
2798 keyboard
->unused_classes
= calloc(1, sizeof(ClassesRec
));
2809 * Return Relative or Absolute for the device.
2812 valuator_get_mode(DeviceIntPtr dev
, int axis
)
2814 return (dev
->valuator
->axes
[axis
].mode
& DeviceMode
);
2818 * Set the given mode for the axis. If axis is VALUATOR_MODE_ALL_AXES, then
2819 * set the mode for all axes.
2822 valuator_set_mode(DeviceIntPtr dev
, int axis
, int mode
)
2824 if (axis
!= VALUATOR_MODE_ALL_AXES
)
2825 dev
->valuator
->axes
[axis
].mode
= mode
;
2829 for (i
= 0; i
< dev
->valuator
->numAxes
; i
++)
2830 dev
->valuator
->axes
[i
].mode
= mode
;