Bug Summary

File:dix/devices.c
Location:line 1606, column 9
Description:Value stored to 'num_axes' is never read

Annotated Source Code

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