aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix/devices.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-09-09 05:23:48 +0000
committermarha <marha@users.sourceforge.net>2009-09-09 05:23:48 +0000
commit81f91c615982e50bb62708201569c33a3cd3d973 (patch)
tree4f32ecc48a3b7b5e76642f3792338263c53879bd /xorg-server/dix/devices.c
parentb571a562410f565af2bdde52d9f7f9a23ffae04f (diff)
parenta915739887477b28d924ecc8417ee107d125bd6c (diff)
downloadvcxsrv-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.c1185
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;
}
+