Initial commit
[xorg_rtime.git] / xorg-server-1.4 / dix / devices.c
blob9f3c5765381cf18420dde1f9bbafbf3e28a9bd95
1 /************************************************************
3 Copyright 1987, 1998 The Open Group
5 Permission to use, copy, modify, distribute, and sell this software and its
6 documentation for any purpose is hereby granted without fee, provided that
7 the above copyright notice appear in all copies and that both that
8 copyright notice and this permission notice appear in supporting
9 documentation.
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 Except as contained in this notice, the name of The Open Group shall not be
22 used in advertising or otherwise to promote the sale, use or other dealings
23 in this Software without prior written authorization from The Open Group.
26 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
28 All Rights Reserved
30 Permission to use, copy, modify, and distribute this software and its
31 documentation for any purpose and without fee is hereby granted,
32 provided that the above copyright notice appear in all copies and that
33 both that copyright notice and this permission notice appear in
34 supporting documentation, and that the name of Digital not be
35 used in advertising or publicity pertaining to distribution of the
36 software without specific, written prior permission.
38 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44 SOFTWARE.
46 ********************************************************/
50 #ifdef HAVE_DIX_CONFIG_H
51 #include <dix-config.h>
52 #endif
54 #include <X11/X.h>
55 #include "misc.h"
56 #include "resource.h"
57 #define NEED_EVENTS
58 #define NEED_REPLIES
59 #include <X11/Xproto.h>
60 #include "windowstr.h"
61 #include "inputstr.h"
62 #include "scrnintstr.h"
63 #include "cursorstr.h"
64 #include "dixstruct.h"
65 #include "site.h"
66 #ifndef XKB_IN_SERVER
67 #define XKB_IN_SERVER
68 #endif
69 #ifdef XKB
70 #include <xkbsrv.h>
71 #endif
72 #include "xace.h"
74 #include "dispatch.h"
75 #include "swaprep.h"
76 #include "dixevents.h"
78 #include <X11/extensions/XI.h>
79 #include <X11/extensions/XIproto.h>
80 #include "exglobals.h"
81 #include "exevents.h"
83 /** @file
84 * This file handles input device-related stuff.
87 int CoreDevicePrivatesIndex = 0;
88 static int CoreDevicePrivatesGeneration = -1;
90 /**
91 * Create a new input device and init it to sane values. The device is added
92 * to the server's off_devices list.
94 * @param deviceProc Callback for device control function (switch dev on/off).
95 * @return The newly created device.
97 DeviceIntPtr
98 AddInputDevice(DeviceProc deviceProc, Bool autoStart)
100 DeviceIntPtr dev, *prev; /* not a typo */
101 DeviceIntPtr devtmp;
102 int devid;
103 char devind[MAX_DEVICES];
105 /* Find next available id */
106 memset(devind, 0, sizeof(char)*MAX_DEVICES);
107 for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next)
108 devind[devtmp->id]++;
109 for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next)
110 devind[devtmp->id]++;
111 for (devid = 0; devid < MAX_DEVICES && devind[devid]; devid++)
114 if (devid >= MAX_DEVICES)
115 return (DeviceIntPtr)NULL;
116 dev = (DeviceIntPtr) xcalloc(sizeof(DeviceIntRec), 1);
117 if (!dev)
118 return (DeviceIntPtr)NULL;
119 dev->name = (char *)NULL;
120 dev->type = 0;
121 dev->id = devid;
122 inputInfo.numDevices++;
123 dev->public.on = FALSE;
124 dev->public.processInputProc = (ProcessInputProc)NoopDDA;
125 dev->public.realInputProc = (ProcessInputProc)NoopDDA;
126 dev->public.enqueueInputProc = EnqueueEvent;
127 dev->deviceProc = deviceProc;
128 dev->startup = autoStart;
129 dev->sync.frozen = FALSE;
130 dev->sync.other = NullGrab;
131 dev->sync.state = NOT_GRABBED;
132 dev->sync.event = (xEvent *) NULL;
133 dev->sync.evcount = 0;
134 dev->grab = NullGrab;
135 dev->grabTime = currentTime;
136 dev->fromPassiveGrab = FALSE;
137 dev->key = (KeyClassPtr)NULL;
138 dev->valuator = (ValuatorClassPtr)NULL;
139 dev->button = (ButtonClassPtr)NULL;
140 dev->focus = (FocusClassPtr)NULL;
141 dev->proximity = (ProximityClassPtr)NULL;
142 dev->absolute = (AbsoluteClassPtr)NULL;
143 dev->kbdfeed = (KbdFeedbackPtr)NULL;
144 dev->ptrfeed = (PtrFeedbackPtr)NULL;
145 dev->intfeed = (IntegerFeedbackPtr)NULL;
146 dev->stringfeed = (StringFeedbackPtr)NULL;
147 dev->bell = (BellFeedbackPtr)NULL;
148 dev->leds = (LedFeedbackPtr)NULL;
149 #ifdef XKB
150 dev->xkb_interest = NULL;
151 #endif
152 dev->config_info = NULL;
153 dev->nPrivates = 0;
154 dev->devPrivates = NULL;
155 dev->unwrapProc = NULL;
156 dev->coreEvents = TRUE;
157 dev->inited = FALSE;
158 dev->enabled = FALSE;
160 for (prev = &inputInfo.off_devices; *prev; prev = &(*prev)->next)
162 *prev = dev;
163 dev->next = NULL;
165 return dev;
169 * Switch device ON through the driver and push it onto the global device
170 * list. All clients are notified about the device being enabled.
172 * A device will send events once enabled.
174 * @param The device to be enabled.
175 * @return TRUE on success or FALSE otherwise.
177 Bool
178 EnableDevice(DeviceIntPtr dev)
180 DeviceIntPtr *prev;
181 int ret;
182 DeviceIntRec dummyDev;
183 devicePresenceNotify ev;
185 for (prev = &inputInfo.off_devices;
186 *prev && (*prev != dev);
187 prev = &(*prev)->next)
189 if ((*prev != dev) || !dev->inited ||
190 ((ret = (*dev->deviceProc)(dev, DEVICE_ON)) != Success)) {
191 ErrorF("couldn't enable device %d\n", dev->id);
192 return FALSE;
194 dev->enabled = TRUE;
195 *prev = dev->next;
197 for (prev = &inputInfo.devices; *prev; prev = &(*prev)->next)
199 *prev = dev;
200 dev->next = NULL;
202 ev.type = DevicePresenceNotify;
203 ev.time = currentTime.milliseconds;
204 ev.devchange = DeviceEnabled;
205 ev.deviceid = dev->id;
206 dummyDev.id = 0;
207 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
208 (xEvent *) &ev, 1);
210 return TRUE;
214 * Switch a device off through the driver and push it onto the off_devices
215 * list. A device will not send events while disabled. All clients are
216 * notified about the device being disabled.
218 * @return TRUE on success or FALSE otherwise.
220 Bool
221 DisableDevice(DeviceIntPtr dev)
223 DeviceIntPtr *prev;
224 DeviceIntRec dummyDev;
225 devicePresenceNotify ev;
227 for (prev = &inputInfo.devices;
228 *prev && (*prev != dev);
229 prev = &(*prev)->next)
231 if (*prev != dev)
232 return FALSE;
233 (void)(*dev->deviceProc)(dev, DEVICE_OFF);
234 dev->enabled = FALSE;
235 *prev = dev->next;
236 dev->next = inputInfo.off_devices;
237 inputInfo.off_devices = dev;
239 ev.type = DevicePresenceNotify;
240 ev.time = currentTime.milliseconds;
241 ev.devchange = DeviceDisabled;
242 ev.deviceid = dev->id;
243 dummyDev.id = 0;
244 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
245 (xEvent *) &ev, 1);
247 return TRUE;
251 * Initialise a new device through the driver and tell all clients about the
252 * new device.
254 * The device will NOT send events until it is enabled!
256 * @return Success or an error code on failure.
259 ActivateDevice(DeviceIntPtr dev)
261 int ret = Success;
262 devicePresenceNotify ev;
263 DeviceIntRec dummyDev;
265 if (!dev || !dev->deviceProc)
266 return BadImplementation;
268 ret = (*dev->deviceProc) (dev, DEVICE_INIT);
269 dev->inited = (ret == Success);
271 ev.type = DevicePresenceNotify;
272 ev.time = currentTime.milliseconds;
273 ev.devchange = DeviceAdded;
274 ev.deviceid = dev->id;
275 dummyDev.id = 0;
276 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
277 (xEvent *) &ev, 1);
279 return ret;
283 * Ring the bell.
284 * The actual task of ringing the bell is the job of the DDX.
286 static void
287 CoreKeyboardBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
289 KeybdCtrl *ctrl = arg;
291 DDXRingBell(volume, ctrl->bell_pitch, ctrl->bell_duration);
294 static void
295 CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
297 return;
301 * Device control function for the Virtual Core Keyboard.
303 static int
304 CoreKeyboardProc(DeviceIntPtr pDev, int what)
306 CARD8 *modMap;
307 KeySymsRec keySyms;
308 #ifdef XKB
309 XkbComponentNamesRec names;
310 #endif
312 switch (what) {
313 case DEVICE_INIT:
314 keySyms.minKeyCode = 8;
315 keySyms.maxKeyCode = 255;
316 keySyms.mapWidth = 4;
317 keySyms.map = (KeySym *)xcalloc(sizeof(KeySym),
318 (keySyms.maxKeyCode -
319 keySyms.minKeyCode + 1) *
320 keySyms.mapWidth);
321 if (!keySyms.map) {
322 ErrorF("Couldn't allocate core keymap\n");
323 return BadAlloc;
326 modMap = (CARD8 *)xalloc(MAP_LENGTH);
327 if (!modMap) {
328 ErrorF("Couldn't allocate core modifier map\n");
329 return BadAlloc;
331 bzero((char *)modMap, MAP_LENGTH);
333 #ifdef XKB
334 if (!noXkbExtension) {
335 bzero(&names, sizeof(names));
336 XkbSetRulesDflts("base", "pc105", "us", NULL, NULL);
337 XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap,
338 CoreKeyboardBell, CoreKeyboardCtl);
340 else
341 #endif
343 /* FIXME Our keymap here isn't exactly useful. */
344 InitKeyboardDeviceStruct((DevicePtr)pDev, &keySyms, modMap,
345 CoreKeyboardBell, CoreKeyboardCtl);
348 xfree(keySyms.map);
349 xfree(modMap);
351 break;
353 case DEVICE_CLOSE:
354 pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
355 break;
357 default:
358 break;
360 return Success;
364 * Device control function for the Virtual Core Pointer.
366 static int
367 CorePointerProc(DeviceIntPtr pDev, int what)
369 BYTE map[33];
370 int i = 0;
372 switch (what) {
373 case DEVICE_INIT:
374 for (i = 1; i <= 32; i++)
375 map[i] = i;
376 InitPointerDeviceStruct((DevicePtr)pDev, map, 32,
377 GetMotionHistory, (PtrCtrlProcPtr)NoopDDA,
378 GetMotionHistorySize(), 2);
379 pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
380 pDev->valuator->lastx = pDev->valuator->axisVal[0];
381 pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
382 pDev->valuator->lasty = pDev->valuator->axisVal[1];
383 break;
385 case DEVICE_CLOSE:
386 pDev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
387 break;
389 default:
390 break;
393 return Success;
397 * Initialise the two core devices, VCP and VCK (see events.c).
398 * The devices are activated but not enabled.
399 * Note that the server MUST have two core devices at all times, even if there
400 * is no physical device connected.
402 void
403 InitCoreDevices(void)
405 DeviceIntPtr dev;
407 if (CoreDevicePrivatesGeneration != serverGeneration) {
408 CoreDevicePrivatesIndex = AllocateDevicePrivateIndex();
409 CoreDevicePrivatesGeneration = serverGeneration;
412 if (!inputInfo.keyboard) {
413 dev = AddInputDevice(CoreKeyboardProc, TRUE);
414 if (!dev)
415 FatalError("Failed to allocate core keyboard");
416 dev->name = strdup("Virtual core keyboard");
417 #ifdef XKB
418 dev->public.processInputProc = CoreProcessKeyboardEvent;
419 dev->public.realInputProc = CoreProcessKeyboardEvent;
420 if (!noXkbExtension)
421 XkbSetExtension(dev, ProcessKeyboardEvent);
422 #else
423 dev->public.processInputProc = ProcessKeyboardEvent;
424 dev->public.realInputProc = ProcessKeyboardEvent;
425 #endif
426 dev->ActivateGrab = ActivateKeyboardGrab;
427 dev->DeactivateGrab = DeactivateKeyboardGrab;
428 dev->coreEvents = FALSE;
429 if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
430 FatalError("Couldn't allocate keyboard devPrivates\n");
431 dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
432 (void)ActivateDevice(dev);
433 inputInfo.keyboard = dev;
436 if (!inputInfo.pointer) {
437 dev = AddInputDevice(CorePointerProc, TRUE);
438 if (!dev)
439 FatalError("Failed to allocate core pointer");
440 dev->name = strdup("Virtual core pointer");
441 #ifdef XKB
442 dev->public.processInputProc = CoreProcessPointerEvent;
443 dev->public.realInputProc = CoreProcessPointerEvent;
444 if (!noXkbExtension)
445 XkbSetExtension(dev, ProcessPointerEvent);
446 #else
447 dev->public.processInputProc = ProcessPointerEvent;
448 dev->public.realInputProc = ProcessPointerEvent;
449 #endif
450 dev->ActivateGrab = ActivatePointerGrab;
451 dev->DeactivateGrab = DeactivatePointerGrab;
452 dev->coreEvents = FALSE;
453 if (!AllocateDevicePrivate(dev, CoreDevicePrivatesIndex))
454 FatalError("Couldn't allocate pointer devPrivates\n");
455 dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
456 (void)ActivateDevice(dev);
457 inputInfo.pointer = dev;
462 * Activate all switched-off devices and then enable all those devices.
464 * Will return an error if no core keyboard or core pointer is present.
465 * In theory this should never happen if you call InitCoreDevices() first.
467 * @return Success or error code on failure.
470 InitAndStartDevices(void)
472 DeviceIntPtr dev, next;
474 for (dev = inputInfo.off_devices; dev; dev = dev->next) {
475 DebugF("(dix) initialising device %d\n", dev->id);
476 ActivateDevice(dev);
478 for (dev = inputInfo.off_devices; dev; dev = next)
480 DebugF("(dix) enabling device %d\n", dev->id);
481 next = dev->next;
482 if (dev->inited && dev->startup)
483 (void)EnableDevice(dev);
485 for (dev = inputInfo.devices;
486 dev && (dev != inputInfo.keyboard);
487 dev = dev->next)
489 if (!dev || (dev != inputInfo.keyboard)) {
490 ErrorF("No core keyboard\n");
491 return BadImplementation;
493 for (dev = inputInfo.devices;
494 dev && (dev != inputInfo.pointer);
495 dev = dev->next)
497 if (!dev || (dev != inputInfo.pointer)) {
498 ErrorF("No core pointer\n");
499 return BadImplementation;
501 return Success;
505 * Close down a device and free all resources.
506 * Once closed down, the driver will probably not expect you that you'll ever
507 * enable it again and free associated structs. If you want the device to just
508 * be disabled, DisableDevice().
509 * Don't call this function directly, use RemoveDevice() instead.
511 static void
512 CloseDevice(DeviceIntPtr dev)
514 KbdFeedbackPtr k, knext;
515 PtrFeedbackPtr p, pnext;
516 IntegerFeedbackPtr i, inext;
517 StringFeedbackPtr s, snext;
518 BellFeedbackPtr b, bnext;
519 LedFeedbackPtr l, lnext;
521 if (dev->inited)
522 (void)(*dev->deviceProc)(dev, DEVICE_CLOSE);
524 xfree(dev->name);
526 if (dev->key) {
527 #ifdef XKB
528 if (dev->key->xkbInfo)
529 XkbFreeInfo(dev->key->xkbInfo);
530 #endif
531 xfree(dev->key->curKeySyms.map);
532 xfree(dev->key->modifierKeyMap);
533 xfree(dev->key);
536 if (dev->valuator) {
537 /* Counterpart to 'biggest hack ever' in init. */
538 if (dev->valuator->motion &&
539 dev->valuator->GetMotionProc == GetMotionHistory)
540 xfree(dev->valuator->motion);
541 xfree(dev->valuator);
544 if (dev->button) {
545 #ifdef XKB
546 if (dev->button->xkb_acts)
547 xfree(dev->button->xkb_acts);
548 #endif
549 xfree(dev->button);
552 if (dev->focus) {
553 xfree(dev->focus->trace);
554 xfree(dev->focus);
557 if (dev->proximity)
558 xfree(dev->proximity);
560 for (k = dev->kbdfeed; k; k = knext) {
561 knext = k->next;
562 #ifdef XKB
563 if (k->xkb_sli)
564 XkbFreeSrvLedInfo(k->xkb_sli);
565 #endif
566 xfree(k);
569 for (p = dev->ptrfeed; p; p = pnext) {
570 pnext = p->next;
571 xfree(p);
574 for (i = dev->intfeed; i; i = inext) {
575 inext = i->next;
576 xfree(i);
579 for (s = dev->stringfeed; s; s = snext) {
580 snext = s->next;
581 xfree(s->ctrl.symbols_supported);
582 xfree(s->ctrl.symbols_displayed);
583 xfree(s);
586 for (b = dev->bell; b; b = bnext) {
587 bnext = b->next;
588 xfree(b);
591 for (l = dev->leds; l; l = lnext) {
592 lnext = l->next;
593 #ifdef XKB
594 if (l->xkb_sli)
595 XkbFreeSrvLedInfo(l->xkb_sli);
596 #endif
597 xfree(l);
600 #ifdef XKB
601 while (dev->xkb_interest)
602 XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource);
603 #endif
605 if (dev->devPrivates)
606 xfree(dev->devPrivates);
608 xfree(dev->sync.event);
609 xfree(dev);
613 * Shut down all devices, free all resources, etc.
614 * Only useful if you're shutting down the server!
616 void
617 CloseDownDevices(void)
619 DeviceIntPtr dev, next;
621 for (dev = inputInfo.devices; dev; dev = next)
623 next = dev->next;
624 CloseDevice(dev);
626 for (dev = inputInfo.off_devices; dev; dev = next)
628 next = dev->next;
629 CloseDevice(dev);
631 inputInfo.devices = NULL;
632 inputInfo.off_devices = NULL;
633 inputInfo.keyboard = NULL;
634 inputInfo.pointer = NULL;
638 * Remove a device from the device list, closes it and thus frees all
639 * resources.
640 * Removes both enabled and disabled devices and notifies all devices about
641 * the removal of the device.
644 RemoveDevice(DeviceIntPtr dev)
646 DeviceIntPtr prev,tmp,next;
647 int ret = BadMatch;
648 devicePresenceNotify ev;
649 DeviceIntRec dummyDev;
650 int deviceid;
652 DebugF("(dix) removing device %d\n", dev->id);
654 if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
655 return BadImplementation;
657 deviceid = dev->id;
658 DisableDevice(dev);
660 prev = NULL;
661 for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
662 next = tmp->next;
663 if (tmp == dev) {
664 CloseDevice(tmp);
666 if (prev==NULL)
667 inputInfo.devices = next;
668 else
669 prev->next = next;
671 ret = Success;
675 prev = NULL;
676 for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
677 next = tmp->next;
678 if (tmp == dev) {
679 CloseDevice(tmp);
681 if (prev == NULL)
682 inputInfo.off_devices = next;
683 else
684 prev->next = next;
686 ret = Success;
690 if (ret == Success) {
691 inputInfo.numDevices--;
692 ev.type = DevicePresenceNotify;
693 ev.time = currentTime.milliseconds;
694 ev.devchange = DeviceRemoved;
695 ev.deviceid = deviceid;
696 dummyDev.id = 0;
697 SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
698 (xEvent *) &ev, 1);
701 return ret;
705 NumMotionEvents(void)
707 return inputInfo.pointer->valuator->numMotionEvents;
710 void
711 RegisterPointerDevice(DeviceIntPtr device)
713 RegisterOtherDevice(device);
716 void
717 RegisterKeyboardDevice(DeviceIntPtr device)
719 RegisterOtherDevice(device);
722 _X_EXPORT DevicePtr
723 LookupKeyboardDevice(void)
725 return inputInfo.keyboard ? &inputInfo.keyboard->public : NULL;
728 _X_EXPORT DevicePtr
729 LookupPointerDevice(void)
731 return inputInfo.pointer ? &inputInfo.pointer->public : NULL;
734 DevicePtr
735 LookupDevice(int id)
737 DeviceIntPtr dev;
739 for (dev=inputInfo.devices; dev; dev=dev->next) {
740 if (dev->id == (CARD8)id)
741 return (DevicePtr)dev;
743 for (dev=inputInfo.off_devices; dev; dev=dev->next) {
744 if (dev->id == (CARD8)id)
745 return (DevicePtr)dev;
747 return NULL;
750 void
751 QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode)
753 if (inputInfo.keyboard) {
754 *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode;
755 *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode;
759 Bool
760 SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src)
762 int i, j;
763 int rowDif = src->minKeyCode - dst->minKeyCode;
765 /* if keysym map size changes, grow map first */
766 if (src->mapWidth < dst->mapWidth)
768 for (i = src->minKeyCode; i <= src->maxKeyCode; i++)
770 #define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c))
771 #define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c))
772 for (j = 0; j < src->mapWidth; j++)
773 dst->map[DI(i, j)] = src->map[SI(i, j)];
774 for (j = src->mapWidth; j < dst->mapWidth; j++)
775 dst->map[DI(i, j)] = NoSymbol;
776 #undef SI
777 #undef DI
779 return TRUE;
781 else if (src->mapWidth > dst->mapWidth)
783 KeySym *map;
784 int bytes = sizeof(KeySym) * src->mapWidth *
785 (dst->maxKeyCode - dst->minKeyCode + 1);
786 map = (KeySym *)xalloc(bytes);
787 if (!map)
788 return FALSE;
789 bzero((char *)map, bytes);
790 if (dst->map)
792 for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++)
793 memmove((char *)&map[i*src->mapWidth],
794 (char *)&dst->map[i*dst->mapWidth],
795 dst->mapWidth * sizeof(KeySym));
796 xfree(dst->map);
798 dst->mapWidth = src->mapWidth;
799 dst->map = map;
801 memmove((char *)&dst->map[rowDif * dst->mapWidth],
802 (char *)src->map,
803 (int)(src->maxKeyCode - src->minKeyCode + 1) *
804 dst->mapWidth * sizeof(KeySym));
805 return TRUE;
808 static Bool
809 InitModMap(KeyClassPtr keyc)
811 int i, j;
812 CARD8 keysPerModifier[8];
813 CARD8 mask;
815 keyc->maxKeysPerModifier = 0;
816 for (i = 0; i < 8; i++)
817 keysPerModifier[i] = 0;
818 for (i = 8; i < MAP_LENGTH; i++)
820 for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
822 if (mask & keyc->modifierMap[i])
824 if (++keysPerModifier[j] > keyc->maxKeysPerModifier)
825 keyc->maxKeysPerModifier = keysPerModifier[j];
829 keyc->modifierKeyMap = (KeyCode *)xalloc(8*keyc->maxKeysPerModifier);
830 if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier)
831 return (FALSE);
832 bzero((char *)keyc->modifierKeyMap, 8*(int)keyc->maxKeysPerModifier);
833 for (i = 0; i < 8; i++)
834 keysPerModifier[i] = 0;
835 for (i = 8; i < MAP_LENGTH; i++)
837 for (j = 0, mask = 1; j < 8; j++, mask <<= 1)
839 if (mask & keyc->modifierMap[i])
841 keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) +
842 keysPerModifier[j]] = i;
843 keysPerModifier[j]++;
847 return TRUE;
850 _X_EXPORT Bool
851 InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[])
853 int i;
854 KeyClassPtr keyc;
856 keyc = (KeyClassPtr)xalloc(sizeof(KeyClassRec));
857 if (!keyc)
858 return FALSE;
859 keyc->curKeySyms.map = (KeySym *)NULL;
860 keyc->curKeySyms.mapWidth = 0;
861 keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode;
862 keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode;
863 keyc->modifierKeyMap = (KeyCode *)NULL;
864 keyc->state = 0;
865 keyc->prev_state = 0;
866 if (pModifiers)
867 memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH);
868 else
869 bzero((char *)keyc->modifierMap, MAP_LENGTH);
870 bzero((char *)keyc->down, DOWN_LENGTH);
871 bzero((char *)keyc->postdown, DOWN_LENGTH);
872 for (i = 0; i < 8; i++)
873 keyc->modifierKeyCount[i] = 0;
874 if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc))
876 xfree(keyc->curKeySyms.map);
877 xfree(keyc->modifierKeyMap);
878 xfree(keyc);
879 return FALSE;
881 dev->key = keyc;
882 #ifdef XKB
883 dev->key->xkbInfo= NULL;
884 if (!noXkbExtension) XkbInitDevice(dev);
885 #endif
886 return TRUE;
889 _X_EXPORT Bool
890 InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons,
891 CARD8 *map)
893 ButtonClassPtr butc;
894 int i;
896 butc = (ButtonClassPtr)xalloc(sizeof(ButtonClassRec));
897 if (!butc)
898 return FALSE;
899 butc->numButtons = numButtons;
900 for (i = 1; i <= numButtons; i++)
901 butc->map[i] = map[i];
902 butc->buttonsDown = 0;
903 butc->state = 0;
904 butc->motionMask = 0;
905 bzero((char *)butc->down, DOWN_LENGTH);
906 #ifdef XKB
907 butc->xkb_acts= NULL;
908 #endif
909 dev->button = butc;
910 return TRUE;
913 _X_EXPORT Bool
914 InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes,
915 ValuatorMotionProcPtr motionProc,
916 int numMotionEvents, int mode)
918 int i;
919 ValuatorClassPtr valc;
921 if (!dev)
922 return FALSE;
924 valc = (ValuatorClassPtr)xalloc(sizeof(ValuatorClassRec) +
925 numAxes * sizeof(AxisInfo) +
926 numAxes * sizeof(unsigned int));
927 if (!valc)
928 return FALSE;
930 valc->motion = NULL;
931 valc->first_motion = 0;
932 valc->last_motion = 0;
933 valc->GetMotionProc = motionProc;
935 valc->numMotionEvents = numMotionEvents;
936 valc->motionHintWindow = NullWindow;
937 valc->numAxes = numAxes;
938 valc->mode = mode;
939 valc->axes = (AxisInfoPtr)(valc + 1);
940 valc->axisVal = (int *)(valc->axes + numAxes);
941 valc->lastx = 0;
942 valc->lasty = 0;
943 valc->dxremaind = 0;
944 valc->dyremaind = 0;
945 dev->valuator = valc;
947 /* biggest hack ever. */
948 if (motionProc == GetMotionHistory)
949 AllocateMotionHistory(dev);
951 for (i=0; i<numAxes; i++) {
952 InitValuatorAxisStruct(dev, i, 0, -1, 0, 0, 0);
953 valc->axisVal[i]=0;
955 return TRUE;
958 _X_EXPORT Bool
959 InitAbsoluteClassDeviceStruct(DeviceIntPtr dev)
961 AbsoluteClassPtr abs;
963 abs = (AbsoluteClassPtr)xalloc(sizeof(AbsoluteClassRec));
964 if (!abs)
965 return FALSE;
967 /* we don't do anything sensible with these, but should */
968 abs->min_x = -1;
969 abs->min_y = -1;
970 abs->max_x = -1;
971 abs->max_y = -1;
972 abs->flip_x = 0;
973 abs->flip_y = 0;
974 abs->rotation = 0;
975 abs->button_threshold = 0;
977 abs->offset_x = 0;
978 abs->offset_y = 0;
979 abs->width = -1;
980 abs->height = -1;
981 abs->following = 0;
982 abs->screen = 0;
984 dev->absolute = abs;
986 return TRUE;
989 _X_EXPORT Bool
990 InitFocusClassDeviceStruct(DeviceIntPtr dev)
992 FocusClassPtr focc;
994 focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec));
995 if (!focc)
996 return FALSE;
997 focc->win = PointerRootWin;
998 focc->revert = None;
999 focc->time = currentTime;
1000 focc->trace = (WindowPtr *)NULL;
1001 focc->traceSize = 0;
1002 focc->traceGood = 0;
1003 dev->focus = focc;
1004 return TRUE;
1007 _X_EXPORT Bool
1008 InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc,
1009 KbdCtrlProcPtr controlProc)
1011 KbdFeedbackPtr feedc;
1013 feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec));
1014 if (!feedc)
1015 return FALSE;
1016 feedc->BellProc = bellProc;
1017 feedc->CtrlProc = controlProc;
1018 #ifdef XKB
1019 defaultKeyboardControl.autoRepeat = TRUE;
1020 #endif
1021 feedc->ctrl = defaultKeyboardControl;
1022 feedc->ctrl.id = 0;
1023 if ((feedc->next = dev->kbdfeed) != 0)
1024 feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1;
1025 dev->kbdfeed = feedc;
1026 #ifdef XKB
1027 feedc->xkb_sli= NULL;
1028 if (!noXkbExtension)
1029 XkbFinishDeviceInit(dev);
1030 #endif
1031 (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl);
1032 return TRUE;
1035 _X_EXPORT Bool
1036 InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc)
1038 PtrFeedbackPtr feedc;
1040 feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec));
1041 if (!feedc)
1042 return FALSE;
1043 feedc->CtrlProc = controlProc;
1044 feedc->ctrl = defaultPointerControl;
1045 feedc->ctrl.id = 0;
1046 if ( (feedc->next = dev->ptrfeed) )
1047 feedc->ctrl.id = dev->ptrfeed->ctrl.id + 1;
1048 dev->ptrfeed = feedc;
1049 (*controlProc)(dev, &feedc->ctrl);
1050 return TRUE;
1054 static LedCtrl defaultLedControl = {
1055 DEFAULT_LEDS, DEFAULT_LEDS_MASK, 0};
1057 static BellCtrl defaultBellControl = {
1058 DEFAULT_BELL,
1059 DEFAULT_BELL_PITCH,
1060 DEFAULT_BELL_DURATION,
1063 static IntegerCtrl defaultIntegerControl = {
1064 DEFAULT_INT_RESOLUTION,
1065 DEFAULT_INT_MIN_VALUE,
1066 DEFAULT_INT_MAX_VALUE,
1067 DEFAULT_INT_DISPLAYED,
1070 _X_EXPORT Bool
1071 InitStringFeedbackClassDeviceStruct (
1072 DeviceIntPtr dev, StringCtrlProcPtr controlProc,
1073 int max_symbols, int num_symbols_supported, KeySym *symbols)
1075 int i;
1076 StringFeedbackPtr feedc;
1078 feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec));
1079 if (!feedc)
1080 return FALSE;
1081 feedc->CtrlProc = controlProc;
1082 feedc->ctrl.num_symbols_supported = num_symbols_supported;
1083 feedc->ctrl.num_symbols_displayed = 0;
1084 feedc->ctrl.max_symbols = max_symbols;
1085 feedc->ctrl.symbols_supported = (KeySym *)
1086 xalloc (sizeof (KeySym) * num_symbols_supported);
1087 feedc->ctrl.symbols_displayed = (KeySym *)
1088 xalloc (sizeof (KeySym) * max_symbols);
1089 if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed)
1091 if (feedc->ctrl.symbols_supported)
1092 xfree(feedc->ctrl.symbols_supported);
1093 if (feedc->ctrl.symbols_displayed)
1094 xfree(feedc->ctrl.symbols_displayed);
1095 xfree(feedc);
1096 return FALSE;
1098 for (i=0; i<num_symbols_supported; i++)
1099 *(feedc->ctrl.symbols_supported+i) = *symbols++;
1100 for (i=0; i<max_symbols; i++)
1101 *(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL;
1102 feedc->ctrl.id = 0;
1103 if ( (feedc->next = dev->stringfeed) )
1104 feedc->ctrl.id = dev->stringfeed->ctrl.id + 1;
1105 dev->stringfeed = feedc;
1106 (*controlProc)(dev, &feedc->ctrl);
1107 return TRUE;
1110 _X_EXPORT Bool
1111 InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc,
1112 BellCtrlProcPtr controlProc)
1114 BellFeedbackPtr feedc;
1116 feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec));
1117 if (!feedc)
1118 return FALSE;
1119 feedc->CtrlProc = controlProc;
1120 feedc->BellProc = bellProc;
1121 feedc->ctrl = defaultBellControl;
1122 feedc->ctrl.id = 0;
1123 if ( (feedc->next = dev->bell) )
1124 feedc->ctrl.id = dev->bell->ctrl.id + 1;
1125 dev->bell = feedc;
1126 (*controlProc)(dev, &feedc->ctrl);
1127 return TRUE;
1130 _X_EXPORT Bool
1131 InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc)
1133 LedFeedbackPtr feedc;
1135 feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec));
1136 if (!feedc)
1137 return FALSE;
1138 feedc->CtrlProc = controlProc;
1139 feedc->ctrl = defaultLedControl;
1140 feedc->ctrl.id = 0;
1141 if ( (feedc->next = dev->leds) )
1142 feedc->ctrl.id = dev->leds->ctrl.id + 1;
1143 #ifdef XKB
1144 feedc->xkb_sli= NULL;
1145 #endif
1146 dev->leds = feedc;
1147 (*controlProc)(dev, &feedc->ctrl);
1148 return TRUE;
1151 _X_EXPORT Bool
1152 InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc)
1154 IntegerFeedbackPtr feedc;
1156 feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec));
1157 if (!feedc)
1158 return FALSE;
1159 feedc->CtrlProc = controlProc;
1160 feedc->ctrl = defaultIntegerControl;
1161 feedc->ctrl.id = 0;
1162 if ( (feedc->next = dev->intfeed) )
1163 feedc->ctrl.id = dev->intfeed->ctrl.id + 1;
1164 dev->intfeed = feedc;
1165 (*controlProc)(dev, &feedc->ctrl);
1166 return TRUE;
1169 _X_EXPORT Bool
1170 InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons,
1171 ValuatorMotionProcPtr motionProc,
1172 PtrCtrlProcPtr controlProc, int numMotionEvents,
1173 int numAxes)
1175 DeviceIntPtr dev = (DeviceIntPtr)device;
1177 return(InitButtonClassDeviceStruct(dev, numButtons, map) &&
1178 InitValuatorClassDeviceStruct(dev, numAxes, motionProc,
1179 numMotionEvents, 0) &&
1180 InitPtrFeedbackClassDeviceStruct(dev, controlProc));
1183 _X_EXPORT Bool
1184 InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms,
1185 CARD8 pModifiers[], BellProcPtr bellProc,
1186 KbdCtrlProcPtr controlProc)
1188 DeviceIntPtr dev = (DeviceIntPtr)device;
1190 return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) &&
1191 InitFocusClassDeviceStruct(dev) &&
1192 InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc));
1195 _X_EXPORT void
1196 SendMappingNotify(unsigned request, unsigned firstKeyCode, unsigned count,
1197 ClientPtr client)
1199 int i;
1200 xEvent event;
1202 event.u.u.type = MappingNotify;
1203 event.u.mappingNotify.request = request;
1204 if (request == MappingKeyboard)
1206 event.u.mappingNotify.firstKeyCode = firstKeyCode;
1207 event.u.mappingNotify.count = count;
1209 #ifdef XKB
1210 if (!noXkbExtension &&
1211 ((request == MappingKeyboard) || (request == MappingModifier))) {
1212 XkbApplyMappingChange(inputInfo.keyboard,request,firstKeyCode,count,
1213 client);
1215 #endif
1217 /* 0 is the server client */
1218 for (i=1; i<currentMaxClients; i++)
1220 if (clients[i] && clients[i]->clientState == ClientStateRunning)
1222 #ifdef XKB
1223 if (!noXkbExtension &&
1224 (request == MappingKeyboard) &&
1225 (clients[i]->xkbClientFlags != 0) &&
1226 (clients[i]->mapNotifyMask&XkbKeySymsMask))
1227 continue;
1228 #endif
1229 event.u.u.sequenceNumber = clients[i]->sequence;
1230 WriteEventsToClient(clients[i], 1, &event);
1236 * n-squared algorithm. n < 255 and don't want to copy the whole thing and
1237 * sort it to do the checking. How often is it called? Just being lazy?
1239 Bool
1240 BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval)
1242 int i, j;
1244 for (i = 0; i < length; i++)
1245 if (buff[i]) /* only check non-zero elements */
1247 if ((low > buff[i]) || (high < buff[i]))
1249 *errval = buff[i];
1250 return TRUE;
1252 for (j = i + 1; j < length; j++)
1253 if (buff[i] == buff[j])
1255 *errval = buff[i];
1256 return TRUE;
1259 return FALSE;
1262 Bool
1263 AllModifierKeysAreUp(dev, map1, per1, map2, per2)
1264 DeviceIntPtr dev;
1265 CARD8 *map1, *map2;
1266 int per1, per2;
1268 int i, j, k;
1269 CARD8 *down = dev->key->down;
1271 for (i = 8; --i >= 0; map2 += per2)
1273 for (j = per1; --j >= 0; map1++)
1275 if (*map1 && BitIsOn(down, *map1))
1277 for (k = per2; (--k >= 0) && (*map1 != map2[k]);)
1279 if (k < 0)
1280 return FALSE;
1284 return TRUE;
1287 static int
1288 DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
1289 int numKeyPerModifier)
1291 DeviceIntPtr pDev = NULL;
1292 int i = 0, inputMapLen = numKeyPerModifier * 8;
1294 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1295 if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1296 for (i = 0; i < inputMapLen; i++) {
1297 /* Check that all the new modifiers fall within the advertised
1298 * keycode range, and are okay with the DDX. */
1299 if (inputMap[i] && ((inputMap[i] < pDev->key->curKeySyms.minKeyCode ||
1300 inputMap[i] > pDev->key->curKeySyms.maxKeyCode) ||
1301 !LegalModifier(inputMap[i], pDev))) {
1302 client->errorValue = inputMap[i];
1303 return BadValue;
1307 if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
1308 return BadAccess;
1310 /* None of the modifiers (old or new) may be down while we change
1311 * the map. */
1312 if (!AllModifierKeysAreUp(pDev, pDev->key->modifierKeyMap,
1313 pDev->key->maxKeysPerModifier,
1314 inputMap, numKeyPerModifier) ||
1315 !AllModifierKeysAreUp(pDev, inputMap, numKeyPerModifier,
1316 pDev->key->modifierKeyMap,
1317 pDev->key->maxKeysPerModifier)) {
1318 return MappingBusy;
1323 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1325 if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1326 bzero(pDev->key->modifierMap, MAP_LENGTH);
1328 /* Annoyingly, we lack a modifierKeyMap size, so we have to just free
1329 * and re-alloc it every time. */
1330 if (pDev->key->modifierKeyMap)
1331 xfree(pDev->key->modifierKeyMap);
1333 if (inputMapLen) {
1334 pDev->key->modifierKeyMap = (KeyCode *) xalloc(inputMapLen);
1335 if (!pDev->key->modifierKeyMap)
1336 return BadAlloc;
1338 memcpy(pDev->key->modifierKeyMap, inputMap, inputMapLen);
1339 pDev->key->maxKeysPerModifier = numKeyPerModifier;
1341 for (i = 0; i < inputMapLen; i++) {
1342 if (inputMap[i]) {
1343 pDev->key->modifierMap[inputMap[i]] |=
1344 (1 << (((unsigned int)i) / numKeyPerModifier));
1348 else {
1349 pDev->key->modifierKeyMap = NULL;
1350 pDev->key->maxKeysPerModifier = 0;
1355 return Success;
1358 int
1359 ProcSetModifierMapping(ClientPtr client)
1361 xSetModifierMappingReply rep;
1362 REQUEST(xSetModifierMappingReq);
1364 REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq);
1366 if (client->req_len != ((stuff->numKeyPerModifier << 1) +
1367 (sizeof (xSetModifierMappingReq) >> 2)))
1368 return BadLength;
1370 rep.type = X_Reply;
1371 rep.length = 0;
1372 rep.sequenceNumber = client->sequence;
1374 rep.success = DoSetModifierMapping(client, (KeyCode *)&stuff[1],
1375 stuff->numKeyPerModifier);
1377 /* FIXME: Send mapping notifies for all the extended devices as well. */
1378 SendMappingNotify(MappingModifier, 0, 0, client);
1379 WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep);
1380 return client->noClientException;
1384 ProcGetModifierMapping(ClientPtr client)
1386 xGetModifierMappingReply rep;
1387 KeyClassPtr keyc = inputInfo.keyboard->key;
1389 REQUEST_SIZE_MATCH(xReq);
1390 rep.type = X_Reply;
1391 rep.numKeyPerModifier = keyc->maxKeysPerModifier;
1392 rep.sequenceNumber = client->sequence;
1393 /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */
1394 rep.length = keyc->maxKeysPerModifier << 1;
1396 WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep);
1398 /* Use the (modified by DDX) map that SetModifierMapping passed in */
1399 (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3),
1400 (char *)keyc->modifierKeyMap);
1401 return client->noClientException;
1405 ProcChangeKeyboardMapping(ClientPtr client)
1407 REQUEST(xChangeKeyboardMappingReq);
1408 unsigned len;
1409 KeySymsRec keysyms;
1410 KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
1411 DeviceIntPtr pDev = NULL;
1412 REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq);
1414 len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2);
1415 if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode))
1416 return BadLength;
1418 if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
1419 (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
1420 client->errorValue = stuff->firstKeyCode;
1421 return BadValue;
1424 if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) >
1425 curKeySyms->maxKeyCode) || (stuff->keySymsPerKeyCode == 0)) {
1426 client->errorValue = stuff->keySymsPerKeyCode;
1427 return BadValue;
1430 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1431 if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1432 if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
1433 return BadAccess;
1437 keysyms.minKeyCode = stuff->firstKeyCode;
1438 keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1;
1439 keysyms.mapWidth = stuff->keySymsPerKeyCode;
1440 keysyms.map = (KeySym *)&stuff[1];
1441 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1442 if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) {
1443 if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms))
1444 return BadAlloc;
1448 /* FIXME: Send mapping notifies for all the extended devices as well. */
1449 SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, stuff->keyCodes,
1450 client);
1451 return client->noClientException;
1454 static int
1455 DoSetPointerMapping(DeviceIntPtr device, BYTE *map, int n)
1457 int i = 0;
1458 DeviceIntPtr dev = NULL;
1460 if (!device || !device->button)
1461 return BadDevice;
1463 for (dev = inputInfo.devices; dev; dev = dev->next) {
1464 if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
1465 for (i = 0; i < n; i++) {
1466 if ((device->button->map[i + 1] != map[i]) &&
1467 BitIsOn(device->button->down, i + 1)) {
1468 return MappingBusy;
1474 for (dev = inputInfo.devices; dev; dev = dev->next) {
1475 if ((dev->coreEvents || dev == inputInfo.pointer) && dev->button) {
1476 for (i = 0; i < n; i++)
1477 dev->button->map[i + 1] = map[i];
1481 return Success;
1485 ProcSetPointerMapping(ClientPtr client)
1487 REQUEST(xSetPointerMappingReq);
1488 BYTE *map;
1489 int ret;
1490 xSetPointerMappingReply rep;
1492 REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq);
1493 if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2)
1494 return BadLength;
1495 rep.type = X_Reply;
1496 rep.length = 0;
1497 rep.sequenceNumber = client->sequence;
1498 rep.success = MappingSuccess;
1499 map = (BYTE *)&stuff[1];
1501 /* So we're bounded here by the number of core buttons. This check
1502 * probably wants disabling through XFixes. */
1503 if (stuff->nElts != inputInfo.pointer->button->numButtons) {
1504 client->errorValue = stuff->nElts;
1505 return BadValue;
1507 if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue))
1508 return BadValue;
1510 ret = DoSetPointerMapping(inputInfo.pointer, map, stuff->nElts);
1511 if (ret != Success) {
1512 rep.success = ret;
1513 WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
1514 return Success;
1517 /* FIXME: Send mapping notifies for all the extended devices as well. */
1518 SendMappingNotify(MappingPointer, 0, 0, client);
1519 WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep);
1520 return Success;
1524 ProcGetKeyboardMapping(ClientPtr client)
1526 xGetKeyboardMappingReply rep;
1527 REQUEST(xGetKeyboardMappingReq);
1528 KeySymsPtr curKeySyms = &inputInfo.keyboard->key->curKeySyms;
1530 REQUEST_SIZE_MATCH(xGetKeyboardMappingReq);
1532 if ((stuff->firstKeyCode < curKeySyms->minKeyCode) ||
1533 (stuff->firstKeyCode > curKeySyms->maxKeyCode)) {
1534 client->errorValue = stuff->firstKeyCode;
1535 return BadValue;
1537 if (stuff->firstKeyCode + stuff->count >
1538 (unsigned)(curKeySyms->maxKeyCode + 1)) {
1539 client->errorValue = stuff->count;
1540 return BadValue;
1543 rep.type = X_Reply;
1544 rep.sequenceNumber = client->sequence;
1545 rep.keySymsPerKeyCode = curKeySyms->mapWidth;
1546 /* length is a count of 4 byte quantities and KeySyms are 4 bytes */
1547 rep.length = (curKeySyms->mapWidth * stuff->count);
1548 WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep);
1549 client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write;
1550 WriteSwappedDataToClient(
1551 client,
1552 curKeySyms->mapWidth * stuff->count * sizeof(KeySym),
1553 &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) *
1554 curKeySyms->mapWidth]);
1556 return client->noClientException;
1560 ProcGetPointerMapping(ClientPtr client)
1562 xGetPointerMappingReply rep;
1563 ButtonClassPtr butc = inputInfo.pointer->button;
1565 REQUEST_SIZE_MATCH(xReq);
1566 rep.type = X_Reply;
1567 rep.sequenceNumber = client->sequence;
1568 rep.nElts = butc->numButtons;
1569 rep.length = ((unsigned)rep.nElts + (4-1))/4;
1570 WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep);
1571 (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]);
1572 return Success;
1575 void
1576 NoteLedState(DeviceIntPtr keybd, int led, Bool on)
1578 KeybdCtrl *ctrl = &keybd->kbdfeed->ctrl;
1579 if (on)
1580 ctrl->leds |= ((Leds)1 << (led - 1));
1581 else
1582 ctrl->leds &= ~((Leds)1 << (led - 1));
1585 _X_EXPORT int
1586 Ones(unsigned long mask) /* HACKMEM 169 */
1588 unsigned long y;
1590 y = (mask >> 1) &033333333333;
1591 y = mask - y - ((y >>1) & 033333333333);
1592 return (((y + (y >> 3)) & 030707070707) % 077);
1595 static int
1596 DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist,
1597 BITS32 vmask)
1599 #define DO_ALL (-1)
1600 KeybdCtrl ctrl;
1601 int t;
1602 int led = DO_ALL;
1603 int key = DO_ALL;
1604 BITS32 index2;
1605 int mask = vmask, i;
1607 ctrl = keybd->kbdfeed->ctrl;
1608 while (vmask) {
1609 index2 = (BITS32) lowbit (vmask);
1610 vmask &= ~index2;
1611 switch (index2) {
1612 case KBKeyClickPercent:
1613 t = (INT8)*vlist;
1614 vlist++;
1615 if (t == -1) {
1616 t = defaultKeyboardControl.click;
1618 else if (t < 0 || t > 100) {
1619 client->errorValue = t;
1620 return BadValue;
1622 ctrl.click = t;
1623 break;
1624 case KBBellPercent:
1625 t = (INT8)*vlist;
1626 vlist++;
1627 if (t == -1) {
1628 t = defaultKeyboardControl.bell;
1630 else if (t < 0 || t > 100) {
1631 client->errorValue = t;
1632 return BadValue;
1634 ctrl.bell = t;
1635 break;
1636 case KBBellPitch:
1637 t = (INT16)*vlist;
1638 vlist++;
1639 if (t == -1) {
1640 t = defaultKeyboardControl.bell_pitch;
1642 else if (t < 0) {
1643 client->errorValue = t;
1644 return BadValue;
1646 ctrl.bell_pitch = t;
1647 break;
1648 case KBBellDuration:
1649 t = (INT16)*vlist;
1650 vlist++;
1651 if (t == -1)
1652 t = defaultKeyboardControl.bell_duration;
1653 else if (t < 0) {
1654 client->errorValue = t;
1655 return BadValue;
1657 ctrl.bell_duration = t;
1658 break;
1659 case KBLed:
1660 led = (CARD8)*vlist;
1661 vlist++;
1662 if (led < 1 || led > 32) {
1663 client->errorValue = led;
1664 return BadValue;
1666 if (!(mask & KBLedMode))
1667 return BadMatch;
1668 break;
1669 case KBLedMode:
1670 t = (CARD8)*vlist;
1671 vlist++;
1672 if (t == LedModeOff) {
1673 if (led == DO_ALL)
1674 ctrl.leds = 0x0;
1675 else
1676 ctrl.leds &= ~(((Leds)(1)) << (led - 1));
1678 else if (t == LedModeOn) {
1679 if (led == DO_ALL)
1680 ctrl.leds = ~0L;
1681 else
1682 ctrl.leds |= (((Leds)(1)) << (led - 1));
1684 else {
1685 client->errorValue = t;
1686 return BadValue;
1688 #ifdef XKB
1689 if (!noXkbExtension) {
1690 XkbEventCauseRec cause;
1691 XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client);
1692 XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))),
1693 ctrl.leds, &cause);
1694 ctrl.leds = keybd->kbdfeed->ctrl.leds;
1696 #endif
1697 break;
1698 case KBKey:
1699 key = (KeyCode)*vlist;
1700 vlist++;
1701 if ((KeyCode)key < inputInfo.keyboard->key->curKeySyms.minKeyCode ||
1702 (KeyCode)key > inputInfo.keyboard->key->curKeySyms.maxKeyCode) {
1703 client->errorValue = key;
1704 return BadValue;
1706 if (!(mask & KBAutoRepeatMode))
1707 return BadMatch;
1708 break;
1709 case KBAutoRepeatMode:
1710 i = (key >> 3);
1711 mask = (1 << (key & 7));
1712 t = (CARD8)*vlist;
1713 vlist++;
1714 #ifdef XKB
1715 if (!noXkbExtension && key != DO_ALL)
1716 XkbDisableComputedAutoRepeats(keybd,key);
1717 #endif
1718 if (t == AutoRepeatModeOff) {
1719 if (key == DO_ALL)
1720 ctrl.autoRepeat = FALSE;
1721 else
1722 ctrl.autoRepeats[i] &= ~mask;
1724 else if (t == AutoRepeatModeOn) {
1725 if (key == DO_ALL)
1726 ctrl.autoRepeat = TRUE;
1727 else
1728 ctrl.autoRepeats[i] |= mask;
1730 else if (t == AutoRepeatModeDefault) {
1731 if (key == DO_ALL)
1732 ctrl.autoRepeat = defaultKeyboardControl.autoRepeat;
1733 else
1734 ctrl.autoRepeats[i] =
1735 (ctrl.autoRepeats[i] & ~mask) |
1736 (defaultKeyboardControl.autoRepeats[i] & mask);
1738 else {
1739 client->errorValue = t;
1740 return BadValue;
1742 break;
1743 default:
1744 client->errorValue = mask;
1745 return BadValue;
1748 keybd->kbdfeed->ctrl = ctrl;
1750 #ifdef XKB
1751 /* The XKB RepeatKeys control and core protocol global autorepeat */
1752 /* value are linked */
1753 if (!noXkbExtension)
1754 XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat);
1755 else
1756 #endif
1757 (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl);
1759 return Success;
1761 #undef DO_ALL
1765 ProcChangeKeyboardControl (ClientPtr client)
1767 XID *vlist;
1768 BITS32 vmask;
1769 int ret = Success, error = Success;
1770 DeviceIntPtr pDev = NULL;
1771 REQUEST(xChangeKeyboardControlReq);
1773 REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq);
1775 vmask = stuff->mask;
1776 vlist = (XID *)&stuff[1];
1778 if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask))
1779 return BadLength;
1781 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1782 if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
1783 pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
1784 if (!XaceHook(XACE_DEVICE_ACCESS, client, pDev, TRUE))
1785 return BadAccess;
1789 for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
1790 if ((pDev->coreEvents || pDev == inputInfo.keyboard) &&
1791 pDev->kbdfeed && pDev->kbdfeed->CtrlProc) {
1792 ret = DoChangeKeyboardControl(client, pDev, vlist, vmask);
1793 if (ret != Success)
1794 error = ret;
1798 return error;
1802 ProcGetKeyboardControl (ClientPtr client)
1804 int i;
1805 KeybdCtrl *ctrl = &inputInfo.keyboard->kbdfeed->ctrl;
1806 xGetKeyboardControlReply rep;
1808 REQUEST_SIZE_MATCH(xReq);
1809 rep.type = X_Reply;
1810 rep.length = 5;
1811 rep.sequenceNumber = client->sequence;
1812 rep.globalAutoRepeat = ctrl->autoRepeat;
1813 rep.keyClickPercent = ctrl->click;
1814 rep.bellPercent = ctrl->bell;
1815 rep.bellPitch = ctrl->bell_pitch;
1816 rep.bellDuration = ctrl->bell_duration;
1817 rep.ledMask = ctrl->leds;
1818 for (i = 0; i < 32; i++)
1819 rep.map[i] = ctrl->autoRepeats[i];
1820 WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep);
1821 return Success;
1825 ProcBell(ClientPtr client)
1827 DeviceIntPtr keybd = inputInfo.keyboard;
1828 int base = keybd->kbdfeed->ctrl.bell;
1829 int newpercent;
1830 REQUEST(xBellReq);
1831 REQUEST_SIZE_MATCH(xBellReq);
1833 if (!keybd->kbdfeed->BellProc)
1834 return BadDevice;
1836 if (stuff->percent < -100 || stuff->percent > 100) {
1837 client->errorValue = stuff->percent;
1838 return BadValue;
1841 newpercent = (base * stuff->percent) / 100;
1842 if (stuff->percent < 0)
1843 newpercent = base + newpercent;
1844 else
1845 newpercent = base - newpercent + stuff->percent;
1847 for (keybd = inputInfo.devices; keybd; keybd = keybd->next) {
1848 if ((keybd->coreEvents || keybd == inputInfo.keyboard) &&
1849 keybd->kbdfeed && keybd->kbdfeed->BellProc) {
1850 #ifdef XKB
1851 if (!noXkbExtension)
1852 XkbHandleBell(FALSE, FALSE, keybd, newpercent,
1853 &keybd->kbdfeed->ctrl, 0, None, NULL, client);
1854 else
1855 #endif
1856 (*keybd->kbdfeed->BellProc)(newpercent, keybd,
1857 &keybd->kbdfeed->ctrl, 0);
1861 return Success;
1865 ProcChangePointerControl(ClientPtr client)
1867 DeviceIntPtr mouse = inputInfo.pointer;
1868 PtrCtrl ctrl; /* might get BadValue part way through */
1869 REQUEST(xChangePointerControlReq);
1871 REQUEST_SIZE_MATCH(xChangePointerControlReq);
1873 if (!mouse->ptrfeed->CtrlProc)
1874 return BadDevice;
1876 ctrl = mouse->ptrfeed->ctrl;
1877 if ((stuff->doAccel != xTrue) && (stuff->doAccel != xFalse)) {
1878 client->errorValue = stuff->doAccel;
1879 return(BadValue);
1881 if ((stuff->doThresh != xTrue) && (stuff->doThresh != xFalse)) {
1882 client->errorValue = stuff->doThresh;
1883 return(BadValue);
1885 if (stuff->doAccel) {
1886 if (stuff->accelNum == -1) {
1887 ctrl.num = defaultPointerControl.num;
1889 else if (stuff->accelNum < 0) {
1890 client->errorValue = stuff->accelNum;
1891 return BadValue;
1893 else {
1894 ctrl.num = stuff->accelNum;
1897 if (stuff->accelDenum == -1) {
1898 ctrl.den = defaultPointerControl.den;
1900 else if (stuff->accelDenum <= 0) {
1901 client->errorValue = stuff->accelDenum;
1902 return BadValue;
1904 else {
1905 ctrl.den = stuff->accelDenum;
1908 if (stuff->doThresh) {
1909 if (stuff->threshold == -1) {
1910 ctrl.threshold = defaultPointerControl.threshold;
1912 else if (stuff->threshold < 0) {
1913 client->errorValue = stuff->threshold;
1914 return BadValue;
1916 else {
1917 ctrl.threshold = stuff->threshold;
1922 for (mouse = inputInfo.devices; mouse; mouse = mouse->next) {
1923 if ((mouse->coreEvents || mouse == inputInfo.pointer) &&
1924 mouse->ptrfeed && mouse->ptrfeed->CtrlProc) {
1925 mouse->ptrfeed->ctrl = ctrl;
1926 (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl);
1930 return Success;
1934 ProcGetPointerControl(ClientPtr client)
1936 PtrCtrl *ctrl = &inputInfo.pointer->ptrfeed->ctrl;
1937 xGetPointerControlReply rep;
1939 REQUEST_SIZE_MATCH(xReq);
1940 rep.type = X_Reply;
1941 rep.length = 0;
1942 rep.sequenceNumber = client->sequence;
1943 rep.threshold = ctrl->threshold;
1944 rep.accelNumerator = ctrl->num;
1945 rep.accelDenominator = ctrl->den;
1946 WriteReplyToClient(client, sizeof(xGenericReply), &rep);
1947 return Success;
1950 void
1951 MaybeStopHint(DeviceIntPtr dev, ClientPtr client)
1953 GrabPtr grab = dev->grab;
1955 if ((grab && SameClient(grab, client) &&
1956 ((grab->eventMask & PointerMotionHintMask) ||
1957 (grab->ownerEvents &&
1958 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
1959 PointerMotionHintMask)))) ||
1960 (!grab &&
1961 (EventMaskForClient(dev->valuator->motionHintWindow, client) &
1962 PointerMotionHintMask)))
1963 dev->valuator->motionHintWindow = NullWindow;
1967 ProcGetMotionEvents(ClientPtr client)
1969 WindowPtr pWin;
1970 xTimecoord * coords = (xTimecoord *) NULL;
1971 xGetMotionEventsReply rep;
1972 int i, count, xmin, xmax, ymin, ymax, rc;
1973 unsigned long nEvents;
1974 DeviceIntPtr mouse = inputInfo.pointer;
1975 TimeStamp start, stop;
1976 REQUEST(xGetMotionEventsReq);
1978 REQUEST_SIZE_MATCH(xGetMotionEventsReq);
1979 rc = dixLookupWindow(&pWin, stuff->window, client, DixUnknownAccess);
1980 if (rc != Success)
1981 return rc;
1982 if (mouse->valuator->motionHintWindow)
1983 MaybeStopHint(mouse, client);
1984 rep.type = X_Reply;
1985 rep.sequenceNumber = client->sequence;
1986 nEvents = 0;
1987 start = ClientTimeToServerTime(stuff->start);
1988 stop = ClientTimeToServerTime(stuff->stop);
1989 if ((CompareTimeStamps(start, stop) != LATER) &&
1990 (CompareTimeStamps(start, currentTime) != LATER) &&
1991 mouse->valuator->numMotionEvents)
1993 if (CompareTimeStamps(stop, currentTime) == LATER)
1994 stop = currentTime;
1995 coords = (xTimecoord *)ALLOCATE_LOCAL(mouse->valuator->numMotionEvents
1996 * sizeof(xTimecoord));
1997 if (!coords)
1998 return BadAlloc;
1999 count = (*mouse->valuator->GetMotionProc) (mouse, coords,
2000 start.milliseconds,
2001 stop.milliseconds,
2002 pWin->drawable.pScreen);
2003 xmin = pWin->drawable.x - wBorderWidth (pWin);
2004 xmax = pWin->drawable.x + (int)pWin->drawable.width +
2005 wBorderWidth (pWin);
2006 ymin = pWin->drawable.y - wBorderWidth (pWin);
2007 ymax = pWin->drawable.y + (int)pWin->drawable.height +
2008 wBorderWidth (pWin);
2009 for (i = 0; i < count; i++)
2010 if ((xmin <= coords[i].x) && (coords[i].x < xmax) &&
2011 (ymin <= coords[i].y) && (coords[i].y < ymax))
2013 coords[nEvents].time = coords[i].time;
2014 coords[nEvents].x = coords[i].x - pWin->drawable.x;
2015 coords[nEvents].y = coords[i].y - pWin->drawable.y;
2016 nEvents++;
2019 rep.length = nEvents * (sizeof(xTimecoord) >> 2);
2020 rep.nEvents = nEvents;
2021 WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep);
2022 if (nEvents)
2024 client->pSwapReplyFunc = (ReplySwapPtr) SwapTimeCoordWrite;
2025 WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord),
2026 (char *)coords);
2028 if (coords)
2029 DEALLOCATE_LOCAL(coords);
2030 return Success;
2034 ProcQueryKeymap(ClientPtr client)
2036 xQueryKeymapReply rep;
2037 int i;
2038 CARD8 *down = inputInfo.keyboard->key->down;
2040 REQUEST_SIZE_MATCH(xReq);
2041 rep.type = X_Reply;
2042 rep.sequenceNumber = client->sequence;
2043 rep.length = 2;
2045 if (XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, TRUE))
2046 for (i = 0; i<32; i++)
2047 rep.map[i] = down[i];
2048 else
2049 bzero((char *)&rep.map[0], 32);
2051 WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
2052 return Success;