Bug Summary

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