diff options
author | marha <marha@users.sourceforge.net> | 2009-09-09 05:23:48 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2009-09-09 05:23:48 +0000 |
commit | 81f91c615982e50bb62708201569c33a3cd3d973 (patch) | |
tree | 4f32ecc48a3b7b5e76642f3792338263c53879bd /xorg-server/dix/devices.c | |
parent | b571a562410f565af2bdde52d9f7f9a23ffae04f (diff) | |
parent | a915739887477b28d924ecc8417ee107d125bd6c (diff) | |
download | vcxsrv-81f91c615982e50bb62708201569c33a3cd3d973.tar.gz vcxsrv-81f91c615982e50bb62708201569c33a3cd3d973.tar.bz2 vcxsrv-81f91c615982e50bb62708201569c33a3cd3d973.zip |
svn merge https://vcxsrv.svn.sourceforge.net/svnroot/vcxsrv/branches/released .
Diffstat (limited to 'xorg-server/dix/devices.c')
-rw-r--r-- | xorg-server/dix/devices.c | 1185 |
1 files changed, 529 insertions, 656 deletions
diff --git a/xorg-server/dix/devices.c b/xorg-server/dix/devices.c index 3b8d544da..0be3d58ab 100644 --- a/xorg-server/dix/devices.c +++ b/xorg-server/dix/devices.c @@ -54,8 +54,6 @@ SOFTWARE. #include <X11/X.h> #include "misc.h" #include "resource.h" -#define NEED_EVENTS -#define NEED_REPLIES #include <X11/Xproto.h> #include <X11/Xatom.h> #include "windowstr.h" @@ -65,12 +63,7 @@ SOFTWARE. #include "dixstruct.h" #include "ptrveloc.h" #include "site.h" -#ifndef XKB_IN_SERVER -#define XKB_IN_SERVER -#endif -#ifdef XKB -#include <xkbsrv.h> -#endif +#include "xkbsrv.h" #include "privates.h" #include "xace.h" #include "mi.h" @@ -79,15 +72,18 @@ SOFTWARE. #include "swaprep.h" #include "dixevents.h" #include "mipointer.h" +#include "eventstr.h" #include <X11/extensions/XI.h> +#include <X11/extensions/XI2.h> #include <X11/extensions/XIproto.h> #include "exglobals.h" #include "exevents.h" -#include "listdev.h" /* for CopySwapXXXClass */ +#include "xiquerydevice.h" /* for SizeDeviceClasses */ #include "xiproperty.h" #include "enterleave.h" /* for EnterWindow() */ #include "xserver-properties.h" +#include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ /** @file * This file handles input device-related stuff. @@ -95,11 +91,13 @@ SOFTWARE. static int CoreDevicePrivateKeyIndex; DevPrivateKey CoreDevicePrivateKey = &CoreDevicePrivateKeyIndex; -/* Used to sture classes currently not in use by an MD */ +/* Used to store classes currently not in use by an MD */ static int UnusedClassesPrivateKeyIndex; DevPrivateKey UnusedClassesPrivateKey = &UnusedClassesPrivateKeyIndex; +static void RecalculateMasterButtons(DeviceIntPtr slave); + /** * DIX property handler. */ @@ -120,9 +118,9 @@ DeviceSetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop, if (!checkonly) { if ((*((CARD8*)prop->data)) && !dev->enabled) - EnableDevice(dev); + EnableDevice(dev, TRUE); else if (!(*((CARD8*)prop->data)) && dev->enabled) - DisableDevice(dev); + DisableDevice(dev, TRUE); } } @@ -142,7 +140,7 @@ PairDevices(ClientPtr client, DeviceIntPtr ptr, DeviceIntPtr kbd) return BadDevice; /* Don't allow pairing for slave devices */ - if (!ptr->isMaster || !kbd->isMaster) + if (!IsMaster(ptr) || !IsMaster(kbd)) return BadDevice; if (ptr->spriteInfo->paired) @@ -170,7 +168,7 @@ NextFreePointerDevice(void) { DeviceIntPtr dev; for (dev = inputInfo.devices; dev; dev = dev->next) - if (dev->isMaster && + if (IsMaster(dev) && dev->spriteInfo->spriteOwner && !dev->spriteInfo->paired) return dev; @@ -193,13 +191,13 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) char devind[MAXDEVICES]; BOOL enabled; - /* Find next available id */ + /* Find next available id, 0 and 1 are reserved */ memset(devind, 0, sizeof(char)*MAXDEVICES); for (devtmp = inputInfo.devices; devtmp; devtmp = devtmp->next) devind[devtmp->id]++; for (devtmp = inputInfo.off_devices; devtmp; devtmp = devtmp->next) devind[devtmp->id]++; - for (devid = 0; devid < MAXDEVICES && devind[devid]; devid++) + for (devid = 2; devid < MAXDEVICES && devind[devid]; devid++) ; if (devid >= MAXDEVICES) @@ -248,6 +246,22 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) return dev; } +static void +SendDevicePresenceEvent(int deviceid, int type) +{ + DeviceIntRec dummyDev; + devicePresenceNotify ev; + + memset(&dummyDev, 0, sizeof(DeviceIntRec)); + ev.type = DevicePresenceNotify; + ev.time = currentTime.milliseconds; + ev.devchange = type; + ev.deviceid = deviceid; + dummyDev.id = XIAllDevices; + SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, + (xEvent*)&ev, 1); +} + /** * Enable the device through the driver, add the device to the device list. * Switch device ON through the driver and push it onto the global device @@ -258,21 +272,20 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart) * device. * * @param The device to be enabled. + * @param sendevent True if an XI2 event should be sent. * @return TRUE on success or FALSE otherwise. */ Bool -EnableDevice(DeviceIntPtr dev) +EnableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev; int ret; - DeviceIntRec dummyDev; DeviceIntPtr other; - devicePresenceNotify ev; - int namelen = 0; /* dummy */ int evsize = sizeof(xEvent); int listlen; EventListPtr evlist; BOOL enabled; + int flags[MAXDEVICES] = {0}; for (prev = &inputInfo.off_devices; *prev && (*prev != dev); @@ -281,7 +294,7 @@ EnableDevice(DeviceIntPtr dev) if (!dev->spriteInfo->sprite) { - if (dev->isMaster) + if (IsMaster(dev)) { /* Sprites appear on first root window, so we can hardcode it */ if (dev->spriteInfo->spriteOwner) @@ -310,7 +323,7 @@ EnableDevice(DeviceIntPtr dev) * device */ - SizeDeviceInfo(dev, &namelen, &evsize); + evsize += SizeDeviceClasses(dev); listlen = GetEventList(&evlist); OsBlockSignals(); @@ -337,13 +350,14 @@ EnableDevice(DeviceIntPtr dev) XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceEnabled; - ev.deviceid = dev->id; - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); + SendDevicePresenceEvent(dev->id, DeviceEnabled); + if (sendevent) + { + flags[dev->id] |= XIDeviceEnabled; + XISendDeviceHierarchyEvent(flags); + } + + RecalculateMasterButtons(dev); return TRUE; } @@ -356,15 +370,15 @@ EnableDevice(DeviceIntPtr dev) * Master keyboard devices have to be disabled before master pointer devices * otherwise things turn bad. * + * @param sendevent True if an XI2 event should be sent. * @return TRUE on success or FALSE otherwise. */ Bool -DisableDevice(DeviceIntPtr dev) +DisableDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr *prev, other; - DeviceIntRec dummyDev; - devicePresenceNotify ev; BOOL enabled; + int flags[MAXDEVICES] = {0}; for (prev = &inputInfo.devices; *prev && (*prev != dev); @@ -374,24 +388,27 @@ DisableDevice(DeviceIntPtr dev) return FALSE; /* float attached devices */ - if (dev->isMaster) + if (IsMaster(dev)) { for (other = inputInfo.devices; other; other = other->next) { if (other->u.master == dev) + { AttachDevice(NULL, other, NULL); + flags[other->id] |= XISlaveDetached; + } } } else { for (other = inputInfo.devices; other; other = other->next) { - if (other->isMaster && other->u.lastSlave == dev) + if (IsMaster(other) && other->u.lastSlave == dev) other->u.lastSlave = NULL; } } - if (dev->isMaster && dev->spriteInfo->sprite) + if (IsMaster(dev) && dev->spriteInfo->sprite) { for (other = inputInfo.devices; other; other = other->next) { @@ -406,6 +423,20 @@ DisableDevice(DeviceIntPtr dev) (void)(*dev->deviceProc)(dev, DEVICE_OFF); dev->enabled = FALSE; + + /* now that the device is disabled, we can reset the signal handler's + * last.slave */ + OsBlockSignals(); + for (other = inputInfo.devices; other; other = other->next) + { + if (other->last.slave == dev) + other->last.slave = NULL; + } + OsReleaseSignals(); + + LeaveWindow(dev); + SetFocusOut(dev); + *prev = dev->next; dev->next = inputInfo.off_devices; inputInfo.off_devices = dev; @@ -415,13 +446,14 @@ DisableDevice(DeviceIntPtr dev) XA_INTEGER, 8, PropModeReplace, 1, &enabled, TRUE); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceDisabled; - ev.deviceid = dev->id; - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); + SendDevicePresenceEvent(dev->id, DeviceDisabled); + if (sendevent) + { + flags[dev->id] = XIDeviceDisabled; + XISendDeviceHierarchyEvent(flags); + } + + RecalculateMasterButtons(dev); return TRUE; } @@ -433,14 +465,13 @@ DisableDevice(DeviceIntPtr dev) * Must be called before EnableDevice. * The device will NOT send events until it is enabled! * + * @param sendevent True if an XI2 event should be sent. * @return Success or an error code on failure. */ int -ActivateDevice(DeviceIntPtr dev) +ActivateDevice(DeviceIntPtr dev, BOOL sendevent) { int ret = Success; - devicePresenceNotify ev; - DeviceIntRec dummyDev; ScreenPtr pScreen = screenInfo.screens[0]; if (!dev || !dev->deviceProc) @@ -452,19 +483,16 @@ ActivateDevice(DeviceIntPtr dev) return ret; /* Initialize memory for sprites. */ - if (dev->isMaster && dev->spriteInfo->spriteOwner) + if (IsMaster(dev) && dev->spriteInfo->spriteOwner) pScreen->DeviceCursorInitialize(dev, pScreen); - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceAdded; - ev.deviceid = dev->id; - - memset(&dummyDev, 0, sizeof(DeviceIntRec)); - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); - + SendDevicePresenceEvent(dev->id, DeviceAdded); + if (sendevent) + { + int flags[MAXDEVICES] = {0}; + flags[dev->id] = XISlaveAdded; + XISendDeviceHierarchyEvent(flags); + } return ret; } @@ -489,94 +517,70 @@ CoreKeyboardCtl(DeviceIntPtr pDev, KeybdCtrl *ctrl) /** * Device control function for the Virtual Core Keyboard. */ -static int +int CoreKeyboardProc(DeviceIntPtr pDev, int what) { - CARD8 *modMap; - KeySymsRec keySyms; -#ifdef XKB - XkbComponentNamesRec names; -#endif - ClassesPtr classes; switch (what) { case DEVICE_INIT: - if (!(classes = xcalloc(1, sizeof(ClassesRec)))) + if (!InitKeyboardDeviceStruct(pDev, NULL, CoreKeyboardBell, + CoreKeyboardCtl)) { - ErrorF("[dix] Could not allocate device classes.\n"); - return BadAlloc; - } - - keySyms.minKeyCode = 8; - keySyms.maxKeyCode = 255; - keySyms.mapWidth = 4; - keySyms.map = (KeySym *)xcalloc(sizeof(KeySym), - (keySyms.maxKeyCode - - keySyms.minKeyCode + 1) * - keySyms.mapWidth); - if (!keySyms.map) { - ErrorF("[dix] Couldn't allocate core keymap\n"); - xfree(classes); - return BadAlloc; - } - - modMap = xcalloc(1, MAP_LENGTH); - if (!modMap) { - ErrorF("[dix] Couldn't allocate core modifier map\n"); - xfree(classes); - return BadAlloc; - } - -#ifdef XKB - if (!noXkbExtension) { - bzero(&names, sizeof(names)); - XkbInitKeyboardDeviceStruct(pDev, &names, &keySyms, modMap, - CoreKeyboardBell, CoreKeyboardCtl); - } - else -#endif - { - /* FIXME Our keymap here isn't exactly useful. */ - InitKeyboardDeviceStruct((DevicePtr)pDev, &keySyms, modMap, - CoreKeyboardBell, CoreKeyboardCtl); + ErrorF("Keyboard initialization failed. This could be a missing " + "or incorrect setup of xkeyboard-config.\n"); + return BadValue; } + return Success; - xfree(keySyms.map); - xfree(modMap); - break; + case DEVICE_ON: + case DEVICE_OFF: + return Success; case DEVICE_CLOSE: - break; - - default: - break; + return Success; } - return Success; + + return BadMatch; } /** * Device control function for the Virtual Core Pointer. - * - * Aside from initialisation, it backs up the original device classes into the - * devicePrivates. This only needs to be done for master devices. */ -static int +int CorePointerProc(DeviceIntPtr pDev, int what) { - BYTE map[33]; +#define NBUTTONS 7 +#define NAXES 2 + BYTE map[NBUTTONS + 1]; int i = 0; - ClassesPtr classes; + Atom btn_labels[NBUTTONS] = {0}; + Atom axes_labels[NAXES] = {0}; switch (what) { case DEVICE_INIT: - if (!(classes = xcalloc(1, sizeof(ClassesRec)))) - return BadAlloc; - - for (i = 1; i <= 32; i++) + for (i = 1; i <= NBUTTONS; i++) map[i] = i; - InitPointerDeviceStruct((DevicePtr)pDev, map, 32, + + btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); + btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); + btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); + btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); + btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); + btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); + btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); + /* don't know about the rest */ + + axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); + axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); + + if (!InitPointerDeviceStruct((DevicePtr)pDev, map, NBUTTONS, btn_labels, (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), 2); + GetMotionHistorySize(), NAXES, axes_labels)) + { + ErrorF("Could not initialize device '%s'. Out of memory.\n", + pDev->name); + return BadAlloc; /* IPDS only fails on allocs */ + } pDev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2; pDev->last.valuators[0] = pDev->valuator->axisVal[0]; pDev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2; @@ -591,6 +595,9 @@ CorePointerProc(DeviceIntPtr pDev, int what) } return Success; + +#undef NBUTTONS +#undef NAXES } /** @@ -604,16 +611,20 @@ CorePointerProc(DeviceIntPtr pDev, int what) void InitCoreDevices(void) { - if (AllocMasterDevice(serverClient, "Virtual core", - &inputInfo.pointer, - &inputInfo.keyboard) != Success) + if (AllocDevicePair(serverClient, "Virtual core", + &inputInfo.pointer, &inputInfo.keyboard, + CorePointerProc, CoreKeyboardProc, + TRUE) != Success) FatalError("Failed to allocate core devices"); - ActivateDevice(inputInfo.pointer); - ActivateDevice(inputInfo.keyboard); - EnableDevice(inputInfo.pointer); - EnableDevice(inputInfo.keyboard); + if (ActivateDevice(inputInfo.pointer, TRUE) != Success || + ActivateDevice(inputInfo.keyboard, TRUE) != Success) + FatalError("Failed to activate core devices."); + if (!EnableDevice(inputInfo.pointer, TRUE) || + !EnableDevice(inputInfo.keyboard, TRUE)) + FatalError("Failed to enable core devices."); + InitXTestDevices(); } /** @@ -629,14 +640,14 @@ InitCoreDevices(void) * @return Success or error code on failure. */ int -InitAndStartDevices() +InitAndStartDevices(void) { DeviceIntPtr dev, next; for (dev = inputInfo.off_devices; dev; dev = dev->next) { DebugF("(dix) initialising device %d\n", dev->id); if (!dev->inited) - ActivateDevice(dev); + ActivateDevice(dev, TRUE); } /* enable real devices */ @@ -645,7 +656,7 @@ InitAndStartDevices() DebugF("(dix) enabling device %d\n", dev->id); next = dev->next; if (dev->inited && dev->startup) - (void)EnableDevice(dev); + EnableDevice(dev, TRUE); } return Success; @@ -665,25 +676,19 @@ FreeDeviceClass(int type, pointer *class) case KeyClass: { KeyClassPtr* k = (KeyClassPtr*)class; -#ifdef XKB if ((*k)->xkbInfo) { XkbFreeInfo((*k)->xkbInfo); (*k)->xkbInfo = NULL; } -#endif - xfree((*k)->curKeySyms.map); - xfree((*k)->modifierKeyMap); xfree((*k)); break; } case ButtonClass: { ButtonClassPtr *b = (ButtonClassPtr*)class; -#ifdef XKB if ((*b)->xkb_acts) xfree((*b)->xkb_acts); -#endif xfree((*b)); break; } @@ -728,10 +733,8 @@ FreeFeedbackClass(int type, pointer *class) KbdFeedbackPtr k, knext; for (k = (*kbdfeed); k; k = knext) { knext = k->next; -#ifdef XKB if (k->xkb_sli) XkbFreeSrvLedInfo(k->xkb_sli); -#endif xfree(k); } break; @@ -789,10 +792,8 @@ FreeFeedbackClass(int type, pointer *class) for (l = (*leds); l; l = lnext) { lnext = l->next; -#ifdef XKB if (l->xkb_sli) XkbFreeSrvLedInfo(l->xkb_sli); -#endif xfree(l); } break; @@ -845,7 +846,7 @@ CloseDevice(DeviceIntPtr dev) (void)(*dev->deviceProc)(dev, DEVICE_CLOSE); /* free sprite memory */ - if (dev->isMaster && dev->spriteInfo->sprite) + if (IsMaster(dev) && dev->spriteInfo->sprite) screen->DeviceCursorCleanup(dev, screen); /* free acceleration info */ @@ -857,17 +858,14 @@ CloseDevice(DeviceIntPtr dev) classes = (ClassesPtr)&dev->key; FreeAllDeviceClasses(classes); - if (dev->isMaster) + if (IsMaster(dev)) { classes = dixLookupPrivate(&dev->devPrivates, UnusedClassesPrivateKey); FreeAllDeviceClasses(classes); } - -#ifdef XKB while (dev->xkb_interest) XkbRemoveResourceClient((DevicePtr)dev,dev->xkb_interest->resource); -#endif if (DevHasCursor(dev) && dev->spriteInfo->sprite) { xfree(dev->spriteInfo->sprite->spriteTrace); @@ -905,7 +903,7 @@ CloseDownDevices(void) */ for (dev = inputInfo.devices; dev; dev = dev->next) { - if (!dev->isMaster && dev->u.master) + if (!IsMaster(dev) && dev->u.master) dev->u.master = NULL; } @@ -924,9 +922,7 @@ CloseDownDevices(void) inputInfo.off_devices = NULL; inputInfo.keyboard = NULL; inputInfo.pointer = NULL; -#ifdef XKB XkbDeleteRulesDflts(); -#endif } /** @@ -934,7 +930,7 @@ CloseDownDevices(void) * resources are freed or any device is deleted. */ void -UndisplayDevices() +UndisplayDevices(void) { DeviceIntPtr dev; ScreenPtr screen = screenInfo.screens[0]; @@ -953,17 +949,18 @@ UndisplayDevices() * happen if a malloc fails during the addition of master devices. If * dev->init is FALSE it means the client never received a DeviceAdded event, * so let's not send a DeviceRemoved event either. + * + * @param sendevent True if an XI2 event should be sent. */ int -RemoveDevice(DeviceIntPtr dev) +RemoveDevice(DeviceIntPtr dev, BOOL sendevent) { DeviceIntPtr prev,tmp,next; int ret = BadMatch; - devicePresenceNotify ev; - DeviceIntRec dummyDev; ScreenPtr screen = screenInfo.screens[0]; int deviceid; int initialized; + int flags[MAXDEVICES] = {0}; DebugF("(dix) removing device %d\n", dev->id); @@ -971,11 +968,16 @@ RemoveDevice(DeviceIntPtr dev) return BadImplementation; initialized = dev->inited; - if (DevHasCursor(dev)) - screen->DisplayCursor(dev, screen, NullCursor); - deviceid = dev->id; - DisableDevice(dev); + + if (initialized) + { + if (DevHasCursor(dev)) + screen->DisplayCursor(dev, screen, NullCursor); + + DisableDevice(dev, sendevent); + flags[dev->id] = XIDeviceDisabled; + } prev = NULL; for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { @@ -987,6 +989,7 @@ RemoveDevice(DeviceIntPtr dev) else prev->next = next; + flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); ret = Success; } @@ -996,6 +999,7 @@ RemoveDevice(DeviceIntPtr dev) for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { next = tmp->next; if (tmp == dev) { + flags[tmp->id] = IsMaster(tmp) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); if (prev == NULL) @@ -1009,13 +1013,9 @@ RemoveDevice(DeviceIntPtr dev) if (ret == Success && initialized) { inputInfo.numDevices--; - ev.type = DevicePresenceNotify; - ev.time = currentTime.milliseconds; - ev.devchange = DeviceRemoved; - ev.deviceid = deviceid; - dummyDev.id = MAXDEVICES; - SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, - (xEvent *) &ev, 1); + SendDevicePresenceEvent(deviceid, DeviceRemoved); + if (sendevent) + XISendDeviceHierarchyEvent(flags); } return ret; @@ -1049,11 +1049,11 @@ dixLookupDevice(DeviceIntPtr *pDev, int id, ClientPtr client, Mask access_mode) *pDev = NULL; for (dev=inputInfo.devices; dev; dev=dev->next) { - if (dev->id == (CARD8)id) + if (dev->id == id) goto found; } for (dev=inputInfo.off_devices; dev; dev=dev->next) { - if (dev->id == (CARD8)id) + if (dev->id == id) goto found; } return BadDevice; @@ -1069,24 +1069,25 @@ void QueryMinMaxKeyCodes(KeyCode *minCode, KeyCode *maxCode) { if (inputInfo.keyboard) { - *minCode = inputInfo.keyboard->key->curKeySyms.minKeyCode; - *maxCode = inputInfo.keyboard->key->curKeySyms.maxKeyCode; + *minCode = inputInfo.keyboard->key->xkbInfo->desc->min_key_code; + *maxCode = inputInfo.keyboard->key->xkbInfo->desc->max_key_code; } } +/* Notably, this function does not expand the destination's keycode range, or + * notify clients. */ Bool SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) { int i, j; + KeySym *tmp; int rowDif = src->minKeyCode - dst->minKeyCode; /* if keysym map size changes, grow map first */ - if (src->mapWidth < dst->mapWidth) - { - for (i = src->minKeyCode; i <= src->maxKeyCode; i++) - { -#define SI(r, c) (((r-src->minKeyCode)*src->mapWidth) + (c)) -#define DI(r, c) (((r - dst->minKeyCode)*dst->mapWidth) + (c)) + if (src->mapWidth < dst->mapWidth) { + for (i = src->minKeyCode; i <= src->maxKeyCode; i++) { +#define SI(r, c) (((r - src->minKeyCode) * src->mapWidth) + (c)) +#define DI(r, c) (((r - dst->minKeyCode) * dst->mapWidth) + (c)) for (j = 0; j < src->mapWidth; j++) dst->map[DI(i, j)] = src->map[SI(i, j)]; for (j = src->mapWidth; j < dst->mapWidth; j++) @@ -1096,112 +1097,42 @@ SetKeySymsMap(KeySymsPtr dst, KeySymsPtr src) } return TRUE; } - else if (src->mapWidth > dst->mapWidth) - { - KeySym *map; - int bytes = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - map = (KeySym *)xcalloc(1, bytes); - if (!map) - return FALSE; - if (dst->map) - { - for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) - memmove((char *)&map[i*src->mapWidth], - (char *)&dst->map[i*dst->mapWidth], - dst->mapWidth * sizeof(KeySym)); - xfree(dst->map); - } - dst->mapWidth = src->mapWidth; - dst->map = map; - } else if (!dst->map) - { - KeySym *map; - int bytes = sizeof(KeySym) * src->mapWidth * - (dst->maxKeyCode - dst->minKeyCode + 1); - map = (KeySym *)xcalloc(1, bytes); - if (!map) + else if (src->mapWidth > dst->mapWidth) { + i = sizeof(KeySym) * src->mapWidth * + (dst->maxKeyCode - dst->minKeyCode + 1); + tmp = xcalloc(sizeof(KeySym), i); + if (!tmp) return FALSE; - dst->map = map; + + if (dst->map) { + for (i = 0; i <= dst->maxKeyCode-dst->minKeyCode; i++) + memmove(&tmp[i * src->mapWidth], &dst->map[i * dst->mapWidth], + dst->mapWidth * sizeof(KeySym)); + xfree(dst->map); + } dst->mapWidth = src->mapWidth; + dst->map = tmp; } - memmove((char *)&dst->map[rowDif * dst->mapWidth], - (char *)src->map, - (int)(src->maxKeyCode - src->minKeyCode + 1) * - dst->mapWidth * sizeof(KeySym)); - return TRUE; -} - -static Bool -InitModMap(KeyClassPtr keyc) -{ - int i, j; - CARD8 keysPerModifier[8]; - CARD8 mask; + else if (!dst->map) { + i = sizeof(KeySym) * src->mapWidth * + (dst->maxKeyCode - dst->minKeyCode + 1); + tmp = xcalloc(sizeof(KeySym), i); + if (!tmp) + return FALSE; - keyc->maxKeysPerModifier = 0; - for (i = 0; i < 8; i++) - keysPerModifier[i] = 0; - for (i = 8; i < MAP_LENGTH; i++) - { - for (j = 0, mask = 1; j < 8; j++, mask <<= 1) - { - if (mask & keyc->modifierMap[i]) - { - if (++keysPerModifier[j] > keyc->maxKeysPerModifier) - keyc->maxKeysPerModifier = keysPerModifier[j]; - } - } - } - keyc->modifierKeyMap = xcalloc(8, keyc->maxKeysPerModifier); - if (!keyc->modifierKeyMap && keyc->maxKeysPerModifier) - return (FALSE); - for (i = 0; i < 8; i++) - keysPerModifier[i] = 0; - for (i = 8; i < MAP_LENGTH; i++) - { - for (j = 0, mask = 1; j < 8; j++, mask <<= 1) - { - if (mask & keyc->modifierMap[i]) - { - keyc->modifierKeyMap[(j*keyc->maxKeysPerModifier) + - keysPerModifier[j]] = i; - keysPerModifier[j]++; - } - } + dst->map = tmp; + dst->mapWidth = src->mapWidth; } - return TRUE; -} -_X_EXPORT Bool -InitKeyClassDeviceStruct(DeviceIntPtr dev, KeySymsPtr pKeySyms, CARD8 pModifiers[]) -{ - KeyClassPtr keyc; + memmove(&dst->map[rowDif * dst->mapWidth], src->map, + (src->maxKeyCode - src->minKeyCode + 1) * + dst->mapWidth * sizeof(KeySym)); - keyc = xcalloc(1, sizeof(KeyClassRec)); - if (!keyc) - return FALSE; - keyc->curKeySyms.minKeyCode = pKeySyms->minKeyCode; - keyc->curKeySyms.maxKeyCode = pKeySyms->maxKeyCode; - if (pModifiers) - memmove((char *)keyc->modifierMap, (char *)pModifiers, MAP_LENGTH); - if (!SetKeySymsMap(&keyc->curKeySyms, pKeySyms) || !InitModMap(keyc)) - { - xfree(keyc->curKeySyms.map); - xfree(keyc->modifierKeyMap); - xfree(keyc); - return FALSE; - } - dev->key = keyc; -#ifdef XKB - dev->key->xkbInfo= NULL; - if (!noXkbExtension) XkbInitDevice(dev); -#endif return TRUE; } _X_EXPORT Bool -InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, +InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, Atom* labels, CARD8 *map) { ButtonClassPtr butc; @@ -1211,14 +1142,18 @@ InitButtonClassDeviceStruct(DeviceIntPtr dev, int numButtons, if (!butc) return FALSE; butc->numButtons = numButtons; + butc->sourceid = dev->id; for (i = 1; i <= numButtons; i++) butc->map[i] = map[i]; + for (i = numButtons + 1; i < MAP_LENGTH; i++) + butc->map[i] = i; + memcpy(butc->labels, labels, numButtons * sizeof(Atom)); dev->button = butc; return TRUE; } -_X_EXPORT Bool -InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, +Bool +InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, Atom *labels, int numMotionEvents, int mode) { int i; @@ -1227,12 +1162,21 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, if (!dev) return FALSE; + if (numAxes >= MAX_VALUATORS) + { + LogMessage(X_WARNING, + "Device '%s' has %d axes, only using first %d.\n", + dev->name, numAxes, MAX_VALUATORS); + numAxes = MAX_VALUATORS; + } + valc = (ValuatorClassPtr)xcalloc(1, sizeof(ValuatorClassRec) + numAxes * sizeof(AxisInfo) + - numAxes * sizeof(unsigned int)); + numAxes * sizeof(double)); if (!valc) return FALSE; + valc->sourceid = dev->id; valc->motion = NULL; valc->first_motion = 0; valc->last_motion = 0; @@ -1242,19 +1186,21 @@ InitValuatorClassDeviceStruct(DeviceIntPtr dev, int numAxes, valc->numAxes = numAxes; valc->mode = mode; valc->axes = (AxisInfoPtr)(valc + 1); - valc->axisVal = (int *)(valc->axes + numAxes); + valc->axisVal = (double *)(valc->axes + numAxes); dev->valuator = valc; AllocateMotionHistory(dev); for (i=0; i<numAxes; i++) { - InitValuatorAxisStruct(dev, i, NO_AXIS_LIMITS, NO_AXIS_LIMITS, + InitValuatorAxisStruct(dev, i, labels[i], NO_AXIS_LIMITS, NO_AXIS_LIMITS, 0, 0, 0); valc->axisVal[i]=0; } dev->last.numValuators = numAxes; - if(dev->isMaster) /* master devs do not accelerate */ + + if (IsMaster(dev) || /* do not accelerate master or xtest devices */ + IsXTestDevice(dev, NULL)) InitPointerAccelerationScheme(dev, PtrAccelNoOp); else InitPointerAccelerationScheme(dev, PtrAccelDefault); @@ -1273,7 +1219,7 @@ ValuatorAccelerationRec pointerAccelerationScheme[] = { * install an acceleration scheme. returns TRUE on success, and should not * change anything if unsuccessful. */ -_X_EXPORT Bool +Bool InitPointerAccelerationScheme(DeviceIntPtr dev, int scheme) { @@ -1286,8 +1232,8 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, if(!val) return FALSE; - if(dev->isMaster && (scheme != PtrAccelNoOp)) - scheme = PtrAccelNoOp; /* no accel for master devices */ + if(IsMaster(dev) && scheme != PtrAccelNoOp) + return FALSE; for(x = 0; pointerAccelerationScheme[x].number >= 0; x++) { if(pointerAccelerationScheme[x].number == scheme){ @@ -1305,7 +1251,7 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, case PtrAccelPredictable: { DeviceVelocityPtr s; - s = (DeviceVelocityPtr)xalloc(sizeof(DeviceVelocityRec)); + s = xalloc(sizeof(DeviceVelocityRec)); if(!s) return FALSE; InitVelocityData(s); @@ -1319,15 +1265,25 @@ InitPointerAccelerationScheme(DeviceIntPtr dev, val->accelScheme = pointerAccelerationScheme[i]; val->accelScheme.accelData = data; + /* post-init scheme */ + switch(scheme){ + case PtrAccelPredictable: + InitializePredictableAccelerationProperties(dev); + break; + + default: + break; + } + return TRUE; } -_X_EXPORT Bool +Bool InitAbsoluteClassDeviceStruct(DeviceIntPtr dev) { AbsoluteClassPtr abs; - abs = (AbsoluteClassPtr)xalloc(sizeof(AbsoluteClassRec)); + abs = xalloc(sizeof(AbsoluteClassRec)); if (!abs) return FALSE; @@ -1348,17 +1304,19 @@ InitAbsoluteClassDeviceStruct(DeviceIntPtr dev) abs->following = 0; abs->screen = 0; + abs->sourceid = dev->id; + dev->absolute = abs; return TRUE; } -_X_EXPORT Bool +Bool InitFocusClassDeviceStruct(DeviceIntPtr dev) { FocusClassPtr focc; - focc = (FocusClassPtr)xalloc(sizeof(FocusClassRec)); + focc = xalloc(sizeof(FocusClassRec)); if (!focc) return FALSE; focc->win = PointerRootWin; @@ -1367,44 +1325,17 @@ InitFocusClassDeviceStruct(DeviceIntPtr dev) focc->trace = (WindowPtr *)NULL; focc->traceSize = 0; focc->traceGood = 0; + focc->sourceid = dev->id; dev->focus = focc; return TRUE; } _X_EXPORT Bool -InitKbdFeedbackClassDeviceStruct(DeviceIntPtr dev, BellProcPtr bellProc, - KbdCtrlProcPtr controlProc) -{ - KbdFeedbackPtr feedc; - - feedc = (KbdFeedbackPtr)xalloc(sizeof(KbdFeedbackClassRec)); - if (!feedc) - return FALSE; - feedc->BellProc = bellProc; - feedc->CtrlProc = controlProc; -#ifdef XKB - defaultKeyboardControl.autoRepeat = TRUE; -#endif - feedc->ctrl = defaultKeyboardControl; - feedc->ctrl.id = 0; - if ((feedc->next = dev->kbdfeed) != 0) - feedc->ctrl.id = dev->kbdfeed->ctrl.id + 1; - dev->kbdfeed = feedc; -#ifdef XKB - feedc->xkb_sli= NULL; - if (!noXkbExtension) - XkbFinishDeviceInit(dev); -#endif - (*dev->kbdfeed->CtrlProc)(dev,&dev->kbdfeed->ctrl); - return TRUE; -} - -_X_EXPORT Bool InitPtrFeedbackClassDeviceStruct(DeviceIntPtr dev, PtrCtrlProcPtr controlProc) { PtrFeedbackPtr feedc; - feedc = (PtrFeedbackPtr)xalloc(sizeof(PtrFeedbackClassRec)); + feedc = xalloc(sizeof(PtrFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1434,7 +1365,7 @@ static IntegerCtrl defaultIntegerControl = { DEFAULT_INT_DISPLAYED, 0}; -_X_EXPORT Bool +Bool InitStringFeedbackClassDeviceStruct ( DeviceIntPtr dev, StringCtrlProcPtr controlProc, int max_symbols, int num_symbols_supported, KeySym *symbols) @@ -1442,17 +1373,15 @@ InitStringFeedbackClassDeviceStruct ( int i; StringFeedbackPtr feedc; - feedc = (StringFeedbackPtr)xalloc(sizeof(StringFeedbackClassRec)); + feedc = xalloc(sizeof(StringFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; feedc->ctrl.num_symbols_supported = num_symbols_supported; feedc->ctrl.num_symbols_displayed = 0; feedc->ctrl.max_symbols = max_symbols; - feedc->ctrl.symbols_supported = (KeySym *) - xalloc (sizeof (KeySym) * num_symbols_supported); - feedc->ctrl.symbols_displayed = (KeySym *) - xalloc (sizeof (KeySym) * max_symbols); + feedc->ctrl.symbols_supported = xalloc (sizeof (KeySym) * num_symbols_supported); + feedc->ctrl.symbols_displayed = xalloc (sizeof (KeySym) * max_symbols); if (!feedc->ctrl.symbols_supported || !feedc->ctrl.symbols_displayed) { if (feedc->ctrl.symbols_supported) @@ -1465,7 +1394,7 @@ InitStringFeedbackClassDeviceStruct ( for (i=0; i<num_symbols_supported; i++) *(feedc->ctrl.symbols_supported+i) = *symbols++; for (i=0; i<max_symbols; i++) - *(feedc->ctrl.symbols_displayed+i) = (KeySym) NULL; + *(feedc->ctrl.symbols_displayed+i) = (KeySym) 0; feedc->ctrl.id = 0; if ( (feedc->next = dev->stringfeed) ) feedc->ctrl.id = dev->stringfeed->ctrl.id + 1; @@ -1474,13 +1403,13 @@ InitStringFeedbackClassDeviceStruct ( return TRUE; } -_X_EXPORT Bool +Bool InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, BellCtrlProcPtr controlProc) { BellFeedbackPtr feedc; - feedc = (BellFeedbackPtr)xalloc(sizeof(BellFeedbackClassRec)); + feedc = xalloc(sizeof(BellFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1494,12 +1423,12 @@ InitBellFeedbackClassDeviceStruct (DeviceIntPtr dev, BellProcPtr bellProc, return TRUE; } -_X_EXPORT Bool +Bool InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) { LedFeedbackPtr feedc; - feedc = (LedFeedbackPtr)xalloc(sizeof(LedFeedbackClassRec)); + feedc = xalloc(sizeof(LedFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1507,20 +1436,18 @@ InitLedFeedbackClassDeviceStruct (DeviceIntPtr dev, LedCtrlProcPtr controlProc) feedc->ctrl.id = 0; if ( (feedc->next = dev->leds) ) feedc->ctrl.id = dev->leds->ctrl.id + 1; -#ifdef XKB feedc->xkb_sli= NULL; -#endif dev->leds = feedc; (*controlProc)(dev, &feedc->ctrl); return TRUE; } -_X_EXPORT Bool +Bool InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr controlProc) { IntegerFeedbackPtr feedc; - feedc = (IntegerFeedbackPtr)xalloc(sizeof(IntegerFeedbackClassRec)); + feedc = xalloc(sizeof(IntegerFeedbackClassRec)); if (!feedc) return FALSE; feedc->CtrlProc = controlProc; @@ -1533,70 +1460,19 @@ InitIntegerFeedbackClassDeviceStruct (DeviceIntPtr dev, IntegerCtrlProcPtr contr return TRUE; } -_X_EXPORT Bool -InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, +Bool +InitPointerDeviceStruct(DevicePtr device, CARD8 *map, int numButtons, Atom* btn_labels, PtrCtrlProcPtr controlProc, int numMotionEvents, - int numAxes) + int numAxes, Atom *axes_labels) { DeviceIntPtr dev = (DeviceIntPtr)device; - return(InitButtonClassDeviceStruct(dev, numButtons, map) && - InitValuatorClassDeviceStruct(dev, numAxes, + return(InitButtonClassDeviceStruct(dev, numButtons, btn_labels, map) && + InitValuatorClassDeviceStruct(dev, numAxes, axes_labels, numMotionEvents, 0) && InitPtrFeedbackClassDeviceStruct(dev, controlProc)); } -_X_EXPORT Bool -InitKeyboardDeviceStruct(DevicePtr device, KeySymsPtr pKeySyms, - CARD8 pModifiers[], BellProcPtr bellProc, - KbdCtrlProcPtr controlProc) -{ - DeviceIntPtr dev = (DeviceIntPtr)device; - - return(InitKeyClassDeviceStruct(dev, pKeySyms, pModifiers) && - InitFocusClassDeviceStruct(dev) && - InitKbdFeedbackClassDeviceStruct(dev, bellProc, controlProc)); -} - -_X_EXPORT void -SendMappingNotify(DeviceIntPtr pDev, unsigned request, unsigned firstKeyCode, - unsigned count, ClientPtr client) -{ - int i; - xEvent event; - - event.u.u.type = MappingNotify; - event.u.mappingNotify.request = request; - if (request == MappingKeyboard) - { - event.u.mappingNotify.firstKeyCode = firstKeyCode; - event.u.mappingNotify.count = count; - } -#ifdef XKB - if (!noXkbExtension && - ((request == MappingKeyboard) || (request == MappingModifier))) { - XkbApplyMappingChange(pDev,request,firstKeyCode,count, client); - } -#endif - - /* 0 is the server client */ - for (i=1; i<currentMaxClients; i++) - { - if (clients[i] && clients[i]->clientState == ClientStateRunning) - { -#ifdef XKB - if (!noXkbExtension && - (request == MappingKeyboard) && - (clients[i]->xkbClientFlags != 0) && - (clients[i]->mapNotifyMask&XkbKeySymsMask)) - continue; -#endif - event.u.u.sequenceNumber = clients[i]->sequence; - WriteEventsToClient(clients[i], 1, &event); - } - } -} - /* * Check if the given buffer contains elements between low (inclusive) and * high (inclusive) only. @@ -1620,131 +1496,32 @@ BadDeviceMap(BYTE *buff, int length, unsigned low, unsigned high, XID *errval) return FALSE; } -Bool -AllModifierKeysAreUp(dev, map1, per1, map2, per2) - DeviceIntPtr dev; - CARD8 *map1, *map2; - int per1, per2; -{ - int i, j, k; - CARD8 *down = dev->key->down; - - for (i = 8; --i >= 0; map2 += per2) - { - for (j = per1; --j >= 0; map1++) - { - if (*map1 && BitIsOn(down, *map1)) - { - for (k = per2; (--k >= 0) && (*map1 != map2[k]);) - ; - if (k < 0) - return FALSE; - } - } - } - return TRUE; -} - -static int -DoSetModifierMapping(ClientPtr client, KeyCode *inputMap, - int numKeyPerModifier, xSetModifierMappingReply *rep) -{ - DeviceIntPtr pDev = NULL; - DeviceIntPtr cp = PickKeyboard(client); /* ClientPointer keyboard */ - int rc, i = 0, inputMapLen = numKeyPerModifier * 8; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if (pDev == cp || (!pDev->isMaster && (pDev->u.master == cp) && pDev->key)) { - for (i = 0; i < inputMapLen; i++) { - /* Check that all the new modifiers fall within the advertised - * keycode range, and are okay with the DDX. */ - if (inputMap[i] && ((inputMap[i] < pDev->key->curKeySyms.minKeyCode || - inputMap[i] > pDev->key->curKeySyms.maxKeyCode) || - !LegalModifier(inputMap[i], pDev))) { - client->errorValue = inputMap[i]; - return BadValue; - } - } - - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - return rc; - - /* None of the modifiers (old or new) may be down while we change - * the map. */ - if (!AllModifierKeysAreUp(pDev, pDev->key->modifierKeyMap, - pDev->key->maxKeysPerModifier, - inputMap, numKeyPerModifier) || - !AllModifierKeysAreUp(pDev, inputMap, numKeyPerModifier, - pDev->key->modifierKeyMap, - pDev->key->maxKeysPerModifier)) { - rep->success = MappingBusy; - return Success; - } - } - } - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { - bzero(pDev->key->modifierMap, MAP_LENGTH); - - /* Annoyingly, we lack a modifierKeyMap size, so we have to just free - * and re-alloc it every time. */ - if (pDev->key->modifierKeyMap) - xfree(pDev->key->modifierKeyMap); - - if (inputMapLen) { - pDev->key->modifierKeyMap = (KeyCode *) xalloc(inputMapLen); - if (!pDev->key->modifierKeyMap) - return BadAlloc; - - memcpy(pDev->key->modifierKeyMap, inputMap, inputMapLen); - pDev->key->maxKeysPerModifier = numKeyPerModifier; - - for (i = 0; i < inputMapLen; i++) { - if (inputMap[i]) { - pDev->key->modifierMap[inputMap[i]] |= - (1 << (((unsigned int)i) / numKeyPerModifier)); - } - } - } - else { - pDev->key->modifierKeyMap = NULL; - pDev->key->maxKeysPerModifier = 0; - } - } - } - - rep->success = Success; - return Success; -} - int ProcSetModifierMapping(ClientPtr client) { xSetModifierMappingReply rep; - DeviceIntPtr dev; int rc; REQUEST(xSetModifierMappingReq); REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); if (client->req_len != ((stuff->numKeyPerModifier << 1) + - (sizeof (xSetModifierMappingReq) >> 2))) + bytes_to_int32(sizeof(xSetModifierMappingReq)))) return BadLength; rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; - rc = DoSetModifierMapping(client, (KeyCode *)&stuff[1], - stuff->numKeyPerModifier, &rep); - if (rc != Success) + rc = change_modmap(client, PickKeyboard(client), (KeyCode *)&stuff[1], + stuff->numKeyPerModifier); + if (rc == MappingFailed || rc == -1) + return BadValue; + if (rc != Success && rc != MappingSuccess && rc != MappingFailed && + rc != MappingBusy) return rc; - for (dev = inputInfo.devices; dev; dev = dev->next) - if (dev->key && dev->coreEvents) - SendDeviceMappingNotify(client, MappingModifier, 0, 0, dev); + rep.success = rc; + WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); return client->noClientException; } @@ -1753,26 +1530,27 @@ int ProcGetModifierMapping(ClientPtr client) { xGetModifierMappingReply rep; - DeviceIntPtr dev = PickKeyboard(client); - KeyClassPtr keyc = dev->key; - int rc; + int ret, max_keys_per_mod = 0; + KeyCode *modkeymap = NULL; REQUEST_SIZE_MATCH(xReq); - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); - if (rc != Success) - return rc; + ret = generate_modkeymap(client, PickKeyboard(client), &modkeymap, + &max_keys_per_mod); + if (ret != Success) + return ret; + memset(&rep, 0, sizeof(xGetModifierMappingReply)); rep.type = X_Reply; - rep.numKeyPerModifier = keyc->maxKeysPerModifier; + rep.numKeyPerModifier = max_keys_per_mod; rep.sequenceNumber = client->sequence; /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ - rep.length = keyc->maxKeysPerModifier << 1; + rep.length = max_keys_per_mod << 1; WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); + (void)WriteToClient(client, max_keys_per_mod * 8, (char *) modkeymap); + + xfree(modkeymap); - /* Use the (modified by DDX) map that SetModifierMapping passed in */ - (void)WriteToClient(client, (int)(keyc->maxKeysPerModifier << 3), - (char *)keyc->modifierKeyMap); return client->noClientException; } @@ -1782,76 +1560,56 @@ ProcChangeKeyboardMapping(ClientPtr client) REQUEST(xChangeKeyboardMappingReq); unsigned len; KeySymsRec keysyms; - KeySymsPtr curKeySyms = &PickKeyboard(client)->key->curKeySyms; - DeviceIntPtr pDev = NULL; + DeviceIntPtr pDev, tmp; int rc; REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); - len = client->req_len - (sizeof(xChangeKeyboardMappingReq) >> 2); + len = client->req_len - bytes_to_int32(sizeof(xChangeKeyboardMappingReq)); if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) return BadLength; - if ((stuff->firstKeyCode < curKeySyms->minKeyCode) || - (stuff->firstKeyCode > curKeySyms->maxKeyCode)) { + pDev = PickKeyboard(client); + + if ((stuff->firstKeyCode < pDev->key->xkbInfo->desc->min_key_code) || + (stuff->firstKeyCode > pDev->key->xkbInfo->desc->max_key_code)) { client->errorValue = stuff->firstKeyCode; return BadValue; } if (((unsigned)(stuff->firstKeyCode + stuff->keyCodes - 1) > - curKeySyms->maxKeyCode) || (stuff->keySymsPerKeyCode == 0)) { + pDev->key->xkbInfo->desc->max_key_code) || + (stuff->keySymsPerKeyCode == 0)) { client->errorValue = stuff->keySymsPerKeyCode; return BadValue; } - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); - if (rc != Success) - return rc; - } - } - keysyms.minKeyCode = stuff->firstKeyCode; keysyms.maxKeyCode = stuff->firstKeyCode + stuff->keyCodes - 1; keysyms.mapWidth = stuff->keySymsPerKeyCode; - keysyms.map = (KeySym *)&stuff[1]; - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && pDev->key) - if (!SetKeySymsMap(&pDev->key->curKeySyms, &keysyms)) - return BadAlloc; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - if (pDev->key && pDev->coreEvents) - SendDeviceMappingNotify(client, MappingKeyboard, - stuff->firstKeyCode, stuff->keyCodes, - pDev); + keysyms.map = (KeySym *) &stuff[1]; - return client->noClientException; -} + rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); + if (rc != Success) + return rc; -static int -DoSetPointerMapping(ClientPtr client, DeviceIntPtr device, BYTE *map, int n) -{ - int rc, i = 0; + XkbApplyMappingChange(pDev, &keysyms, stuff->firstKeyCode, + stuff->keyCodes, NULL, client); - if (!device || !device->button) - return BadDevice; + for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { + if (IsMaster(tmp) || tmp->u.master != pDev) + continue; + if (!tmp->key) + continue; - rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixManageAccess); - if (rc != Success) - return rc; + rc = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); + if (rc != Success) + continue; - for (i = 0; i < n; i++) { - if ((device->button->map[i + 1] != map[i]) && - BitIsOn(device->button->down, i + 1)) { - return MappingBusy; - } + XkbApplyMappingChange(tmp, &keysyms, stuff->firstKeyCode, + stuff->keyCodes, NULL, client); } - for (i = 0; i < n; i++) - device->button->map[i + 1] = map[i]; - - return Success; + return client->noClientException; } int @@ -1865,7 +1623,8 @@ ProcSetPointerMapping(ClientPtr client) REQUEST(xSetPointerMappingReq); REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); - if (client->req_len != (sizeof(xSetPointerMappingReq)+stuff->nElts+3) >> 2) + if (client->req_len != + bytes_to_int32(sizeof(xSetPointerMappingReq) + stuff->nElts)) return BadLength; rep.type = X_Reply; rep.length = 0; @@ -1883,30 +1642,26 @@ ProcSetPointerMapping(ClientPtr client) client->errorValue = stuff->nElts; return BadValue; } - if (BadDeviceMap(&map[0], (int)stuff->nElts, 1, 255, &client->errorValue)) - return BadValue; - /* core protocol specs don't allow for duplicate mappings. */ - for (i = 0; i < stuff->nElts; i++) - { - for (j = i + 1; j < stuff->nElts; j++) - { - if (map[i] && map[i] == map[j]) - { + /* Core protocol specs don't allow for duplicate mappings; this check + * almost certainly wants disabling through XFixes too. */ + for (i = 0; i < stuff->nElts; i++) { + for (j = i + 1; j < stuff->nElts; j++) { + if (map[i] && map[i] == map[j]) { client->errorValue = map[i]; return BadValue; } } } - ret = DoSetPointerMapping(client, ptr, map, stuff->nElts); - if (ret != Success) { + ret = ApplyPointerMapping(ptr, map, stuff->nElts, client); + if (ret == MappingBusy) rep.success = ret; - WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); - return Success; - } + else if (ret == -1) + return BadValue; + else if (ret != Success) + return ret; - SendMappingNotify(ptr, MappingPointer, 0, 0, client); WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); return Success; } @@ -1916,7 +1671,8 @@ ProcGetKeyboardMapping(ClientPtr client) { xGetKeyboardMappingReply rep; DeviceIntPtr kbd = PickKeyboard(client); - KeySymsPtr curKeySyms = &kbd->key->curKeySyms; + XkbDescPtr xkb; + KeySymsPtr syms; int rc; REQUEST(xGetKeyboardMappingReq); REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); @@ -1925,29 +1681,36 @@ ProcGetKeyboardMapping(ClientPtr client) if (rc != Success) return rc; - if ((stuff->firstKeyCode < curKeySyms->minKeyCode) || - (stuff->firstKeyCode > curKeySyms->maxKeyCode)) { + xkb = kbd->key->xkbInfo->desc; + + if ((stuff->firstKeyCode < xkb->min_key_code) || + (stuff->firstKeyCode > xkb->max_key_code)) { client->errorValue = stuff->firstKeyCode; return BadValue; } - if (stuff->firstKeyCode + stuff->count > - (unsigned)(curKeySyms->maxKeyCode + 1)) { + if (stuff->firstKeyCode + stuff->count > xkb->max_key_code + 1) { client->errorValue = stuff->count; return BadValue; } + syms = XkbGetCoreMap(kbd); + if (!syms) + return BadAlloc; + + memset(&rep, 0, sizeof(xGetKeyboardMappingReply)); rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.keySymsPerKeyCode = curKeySyms->mapWidth; + rep.keySymsPerKeyCode = syms->mapWidth; /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ - rep.length = (curKeySyms->mapWidth * stuff->count); + rep.length = syms->mapWidth * stuff->count; WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); client->pSwapReplyFunc = (ReplySwapPtr) CopySwap32Write; - WriteSwappedDataToClient( - client, - curKeySyms->mapWidth * stuff->count * sizeof(KeySym), - &curKeySyms->map[(stuff->firstKeyCode - curKeySyms->minKeyCode) * - curKeySyms->mapWidth]); + WriteSwappedDataToClient(client, + syms->mapWidth * stuff->count * sizeof(KeySym), + &syms->map[syms->mapWidth * (stuff->firstKeyCode - + syms->minKeyCode)]); + xfree(syms->map); + xfree(syms); return client->noClientException; } @@ -1969,10 +1732,11 @@ ProcGetPointerMapping(ClientPtr client) rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.nElts = butc->numButtons; + rep.nElts = (butc) ? butc->numButtons : 0; rep.length = ((unsigned)rep.nElts + (4-1))/4; WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); - (void)WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); + if (butc) + WriteToClient(client, (int)rep.nElts, (char *)&butc->map[1]); return Success; } @@ -1986,7 +1750,7 @@ NoteLedState(DeviceIntPtr keybd, int led, Bool on) ctrl->leds &= ~((Leds)1 << (led - 1)); } -_X_EXPORT int +int Ones(unsigned long mask) /* HACKMEM 169 */ { unsigned long y; @@ -2007,6 +1771,7 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, int key = DO_ALL; BITS32 index2; int mask = vmask, i; + XkbEventCauseRec cause; ctrl = keybd->kbdfeed->ctrl; while (vmask) { @@ -2089,21 +1854,18 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, client->errorValue = t; return BadValue; } -#ifdef XKB - if (!noXkbExtension) { - XkbEventCauseRec cause; - XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); - XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), - ctrl.leds, &cause); - ctrl.leds = keybd->kbdfeed->ctrl.leds; - } -#endif + + XkbSetCauseCoreReq(&cause,X_ChangeKeyboardControl,client); + XkbSetIndicators(keybd,((led == DO_ALL) ? ~0L : (1L<<(led-1))), + ctrl.leds, &cause); + ctrl.leds = keybd->kbdfeed->ctrl.leds; + break; case KBKey: key = (KeyCode)*vlist; vlist++; - if ((KeyCode)key < keybd->key->curKeySyms.minKeyCode || - (KeyCode)key > keybd->key->curKeySyms.maxKeyCode) { + if ((KeyCode)key < keybd->key->xkbInfo->desc->min_key_code || + (KeyCode)key > keybd->key->xkbInfo->desc->max_key_code) { client->errorValue = key; return BadValue; } @@ -2115,10 +1877,8 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, mask = (1 << (key & 7)); t = (CARD8)*vlist; vlist++; -#ifdef XKB - if (!noXkbExtension && key != DO_ALL) + if (key != DO_ALL) XkbDisableComputedAutoRepeats(keybd,key); -#endif if (t == AutoRepeatModeOff) { if (key == DO_ALL) ctrl.autoRepeat = FALSE; @@ -2151,27 +1911,25 @@ DoChangeKeyboardControl (ClientPtr client, DeviceIntPtr keybd, XID *vlist, } keybd->kbdfeed->ctrl = ctrl; -#ifdef XKB /* The XKB RepeatKeys control and core protocol global autorepeat */ /* value are linked */ - if (!noXkbExtension) - XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); - else -#endif - (*keybd->kbdfeed->CtrlProc)(keybd, &keybd->kbdfeed->ctrl); + XkbSetRepeatKeys(keybd, key, keybd->kbdfeed->ctrl.autoRepeat); return Success; #undef DO_ALL } +/** + * Changes kbd control on the ClientPointer and all attached SDs. + */ int ProcChangeKeyboardControl (ClientPtr client) { XID *vlist; BITS32 vmask; int ret = Success, error = Success; - DeviceIntPtr pDev = NULL; + DeviceIntPtr pDev = NULL, keyboard; REQUEST(xChangeKeyboardControlReq); REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); @@ -2182,8 +1940,10 @@ ProcChangeKeyboardControl (ClientPtr client) if (client->req_len != (sizeof(xChangeKeyboardControlReq)>>2)+Ones(vmask)) return BadLength; + keyboard = PickKeyboard(client); + for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && + if ((pDev == keyboard || (!IsMaster(keyboard) && pDev->u.master == keyboard)) && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { ret = XaceHook(XACE_DEVICE_ACCESS, client, pDev, DixManageAccess); if (ret != Success) @@ -2192,7 +1952,7 @@ ProcChangeKeyboardControl (ClientPtr client) } for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { - if ((pDev->coreEvents || pDev == inputInfo.keyboard) && + if ((pDev == keyboard || (!IsMaster(keyboard) && pDev->u.master == keyboard)) && pDev->kbdfeed && pDev->kbdfeed->CtrlProc) { ret = DoChangeKeyboardControl(client, pDev, vlist, vmask); if (ret != Success) @@ -2234,13 +1994,18 @@ ProcGetKeyboardControl (ClientPtr client) int ProcBell(ClientPtr client) { - DeviceIntPtr keybd = PickKeyboard(client); + DeviceIntPtr dev, keybd = PickKeyboard(client); int base = keybd->kbdfeed->ctrl.bell; int newpercent; int rc; REQUEST(xBellReq); REQUEST_SIZE_MATCH(xBellReq); + if (stuff->percent < -100 || stuff->percent > 100) { + client->errorValue = stuff->percent; + return BadValue; + } + /* Seems like no keyboard actually has the BellProc set. Returning * BadDevice (previous code) will make apps crash badly. The man pages * doesn't say anything about a BadDevice being returned either. @@ -2249,32 +2014,21 @@ ProcBell(ClientPtr client) if (!keybd->kbdfeed->BellProc) return Success; - if (stuff->percent < -100 || stuff->percent > 100) { - client->errorValue = stuff->percent; - return BadValue; - } - newpercent = (base * stuff->percent) / 100; if (stuff->percent < 0) newpercent = base + newpercent; else newpercent = base - newpercent + stuff->percent; - for (keybd = inputInfo.devices; keybd; keybd = keybd->next) { - if ((keybd->coreEvents || keybd == inputInfo.keyboard) && - keybd->kbdfeed && keybd->kbdfeed->BellProc) { + for (dev = inputInfo.devices; dev; dev = dev->next) { + if ((dev == keybd || (!IsMaster(dev) && dev->u.master == keybd)) && + dev->kbdfeed && dev->kbdfeed->BellProc) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixBellAccess); + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixBellAccess); if (rc != Success) return rc; -#ifdef XKB - if (!noXkbExtension) - XkbHandleBell(FALSE, FALSE, keybd, newpercent, - &keybd->kbdfeed->ctrl, 0, None, NULL, client); - else -#endif - (*keybd->kbdfeed->BellProc)(newpercent, keybd, - &keybd->kbdfeed->ctrl, 0); + XkbHandleBell(FALSE, FALSE, dev, newpercent, + &dev->kbdfeed->ctrl, 0, None, NULL, client); } } @@ -2284,7 +2038,7 @@ ProcBell(ClientPtr client) int ProcChangePointerControl(ClientPtr client) { - DeviceIntPtr mouse = PickPointer(client); + DeviceIntPtr dev, mouse = PickPointer(client); PtrCtrl ctrl; /* might get BadValue part way through */ int rc; REQUEST(xChangePointerControlReq); @@ -2338,20 +2092,20 @@ ProcChangePointerControl(ClientPtr client) } } - for (mouse = inputInfo.devices; mouse; mouse = mouse->next) { - if ((mouse->coreEvents || mouse == inputInfo.pointer) && - mouse->ptrfeed && mouse->ptrfeed->CtrlProc) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixManageAccess); + for (dev = inputInfo.devices; dev; dev = dev->next) { + if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) && + dev->ptrfeed && dev->ptrfeed->CtrlProc) { + rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixManageAccess); if (rc != Success) return rc; } } - for (mouse = inputInfo.devices; mouse; mouse = mouse->next) { - if ((mouse->coreEvents || mouse == PickPointer(client)) && - mouse->ptrfeed && mouse->ptrfeed->CtrlProc) { - mouse->ptrfeed->ctrl = ctrl; - (*mouse->ptrfeed->CtrlProc)(mouse, &mouse->ptrfeed->ctrl); + for (dev = inputInfo.devices; dev; dev = dev->next) { + if ((dev == mouse || (!IsMaster(dev) && dev->u.master == mouse)) && + dev->ptrfeed && dev->ptrfeed->CtrlProc) { + dev->ptrfeed->ctrl = ctrl; + (*dev->ptrfeed->CtrlProc)(dev, &mouse->ptrfeed->ctrl); } } @@ -2449,7 +2203,7 @@ ProcGetMotionEvents(ClientPtr client) nEvents++; } } - rep.length = nEvents * (sizeof(xTimecoord) >> 2); + rep.length = nEvents * bytes_to_int32(sizeof(xTimecoord)); rep.nEvents = nEvents; WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); if (nEvents) @@ -2488,6 +2242,77 @@ ProcQueryKeymap(ClientPtr client) return Success; } + +/** + * Recalculate the number of buttons for the master device. The number of + * buttons on the master device is equal to the number of buttons on the + * slave device with the highest number of buttons. + */ +static void +RecalculateMasterButtons(DeviceIntPtr slave) +{ + DeviceIntPtr dev, master; + int maxbuttons = 0; + + if (!slave->button || IsMaster(slave)) + return; + + master = GetMaster(slave, MASTER_POINTER); + if (!master) + return; + + for (dev = inputInfo.devices; dev; dev = dev->next) + { + if (IsMaster(dev) || + dev->u.master != master || + !dev->button) + continue; + + maxbuttons = max(maxbuttons, dev->button->numButtons); + } + + if (master->button->numButtons != maxbuttons) + { + int i; + DeviceChangedEvent event; + + memset(&event, 0, sizeof(event)); + + master->button->numButtons = maxbuttons; + + event.header = ET_Internal; + event.type = ET_DeviceChanged; + event.time = CurrentTime; + event.deviceid = master->id; + event.flags = DEVCHANGE_POINTER_EVENT | DEVCHANGE_DEVICE_CHANGE; + event.buttons.num_buttons = maxbuttons; + memcpy(&event.buttons.names, master->button->labels, maxbuttons * + sizeof(Atom)); + + if (master->valuator) + { + event.num_valuators = master->valuator->numAxes; + for (i = 0; i < event.num_valuators; i++) + { + event.valuators[i].min = master->valuator->axes[i].min_value; + event.valuators[i].max = master->valuator->axes[i].max_value; + event.valuators[i].resolution = master->valuator->axes[i].resolution; + /* This should, eventually, be a per-axis mode */ + event.valuators[i].mode = master->valuator->mode; + event.valuators[i].name = master->valuator->axes[i].label; + } + } + + if (master->key) + { + event.keys.min_keycode = master->key->xkbInfo->desc->min_key_code; + event.keys.max_keycode = master->key->xkbInfo->desc->max_key_code; + } + + XISendDeviceChangedEvent(master, master, &event); + } +} + /** * Attach device 'dev' to device 'master'. * Client is set to the client that issued the request, or NULL if it comes @@ -2503,10 +2328,10 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { ScreenPtr screen; DeviceIntPtr oldmaster; - if (!dev || dev->isMaster) + if (!dev || IsMaster(dev)) return BadDevice; - if (master && !master->isMaster) /* can't attach to slaves */ + if (master && !IsMaster(master)) /* can't attach to slaves */ return BadDevice; /* set from floating to floating? */ @@ -2540,12 +2365,13 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) InitializeSprite(dev, currentRoot); dev->spriteInfo->spriteOwner = FALSE; dev->spriteInfo->paired = dev; - } else { dev->spriteInfo->sprite = master->spriteInfo->sprite; dev->spriteInfo->paired = master; dev->spriteInfo->spriteOwner = FALSE; + + RecalculateMasterButtons(master); } /* If we were connected to master device before, this MD may need to @@ -2555,8 +2381,22 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) { DeviceIntPtr it; for (it = inputInfo.devices; it; it = it->next) - if (!it->isMaster && it->u.master == oldmaster) + if (!IsMaster(it) && it->u.master == oldmaster) break; + + if (!it) /* no dev is paired with old master */ + { + EventListPtr event = NULL; + + /* XXX: reset master back to defaults */ + event = InitEventList(1); + SetMinimumEventSize(event, 1, sizeof(DeviceChangedEvent)); + CreateClassesChangedEvent(event, oldmaster, oldmaster, + DEVCHANGE_POINTER_EVENT | DEVCHANGE_KEYBOARD_EVENT); + XISendDeviceChangedEvent(oldmaster, oldmaster, + (DeviceChangedEvent*)event->event); + FreeEventList(event, 1); + } } return Success; @@ -2567,10 +2407,10 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master) * Returns the device paired with the parent master if the given device is a * slave device. */ -_X_EXPORT DeviceIntPtr +DeviceIntPtr GetPairedDevice(DeviceIntPtr dev) { - if (!dev->isMaster && dev->u.master) + if (!IsMaster(dev) && dev->u.master) dev = dev->u.master; return dev->spriteInfo->paired; @@ -2578,19 +2418,61 @@ GetPairedDevice(DeviceIntPtr dev) /** - * Create a new master device (== one pointer, one keyboard device). + * Returns the right master for the type of event needed. If the event is a + * keyboard event. + * This function may be called with a master device as argument. If so, the + * returned master is either the device itself or the paired master device. + * If dev is a floating slave device, NULL is returned. + * + * @type ::MASTER_KEYBOARD or ::MASTER_POINTER + */ +DeviceIntPtr +GetMaster(DeviceIntPtr dev, int which) +{ + DeviceIntPtr master; + + if (IsMaster(dev)) + master = dev; + else + master = dev->u.master; + + if (master) + { + if (which == MASTER_KEYBOARD) + { + if (master->type != MASTER_KEYBOARD) + master = GetPairedDevice(master); + } else + { + if (master->type != MASTER_POINTER) + master = GetPairedDevice(master); + } + } + + return master; +} + +/** + * Create a new device pair (== one pointer, one keyboard device). * Only allocates the devices, you will need to call ActivateDevice() and * EnableDevice() manually. + * Either a master or a slave device can be created depending on + * the value for master. */ int -AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* keybd) +AllocDevicePair (ClientPtr client, char* name, + DeviceIntPtr* ptr, + DeviceIntPtr* keybd, + DeviceProc ptr_proc, + DeviceProc keybd_proc, + Bool master) { DeviceIntPtr pointer; DeviceIntPtr keyboard; ClassesPtr classes; *ptr = *keybd = NULL; - pointer = AddInputDevice(client, CorePointerProc, TRUE); + pointer = AddInputDevice(client, ptr_proc, TRUE); if (!pointer) return BadAlloc; @@ -2598,27 +2480,22 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* strcpy(pointer->name, name); strcat(pointer->name, " pointer"); -#ifdef XKB pointer->public.processInputProc = ProcessOtherEvent; pointer->public.realInputProc = ProcessOtherEvent; - if (!noXkbExtension) - XkbSetExtension(pointer, ProcessPointerEvent); -#else - pointer->public.processInputProc = ProcessPointerEvent; - pointer->public.realInputProc = ProcessPointerEvent; -#endif + XkbSetExtension(pointer, ProcessPointerEvent); pointer->deviceGrab.ActivateGrab = ActivatePointerGrab; pointer->deviceGrab.DeactivateGrab = DeactivatePointerGrab; pointer->coreEvents = TRUE; pointer->spriteInfo->spriteOwner = TRUE; pointer->u.lastSlave = NULL; - pointer->isMaster = TRUE; + pointer->last.slave = NULL; + pointer->type = (master) ? MASTER_POINTER : SLAVE; - keyboard = AddInputDevice(client, CoreKeyboardProc, TRUE); + keyboard = AddInputDevice(client, keybd_proc, TRUE); if (!keyboard) { - RemoveDevice(pointer); + RemoveDevice(pointer, FALSE); return BadAlloc; } @@ -2626,22 +2503,17 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* strcpy(keyboard->name, name); strcat(keyboard->name, " keyboard"); -#ifdef XKB keyboard->public.processInputProc = ProcessOtherEvent; keyboard->public.realInputProc = ProcessOtherEvent; - if (!noXkbExtension) - XkbSetExtension(keyboard, ProcessKeyboardEvent); -#else - keyboard->public.processInputProc = ProcessKeyboardEvent; - keyboard->public.realInputProc = ProcessKeyboardEvent; -#endif + XkbSetExtension(keyboard, ProcessKeyboardEvent); keyboard->deviceGrab.ActivateGrab = ActivateKeyboardGrab; keyboard->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; keyboard->coreEvents = TRUE; keyboard->spriteInfo->spriteOwner = FALSE; keyboard->u.lastSlave = NULL; - keyboard->isMaster = TRUE; + keyboard->last.slave = NULL; + keyboard->type = (master) ? MASTER_KEYBOARD : SLAVE; /* The ClassesRec stores the device classes currently not used. */ @@ -2655,3 +2527,4 @@ AllocMasterDevice(ClientPtr client, char* name, DeviceIntPtr* ptr, DeviceIntPtr* return Success; } + |