summaryrefslogtreecommitdiff
path: root/xkb
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2008-08-01 16:42:15 +0930
committerPeter Hutterer <peter.hutterer@who-t.net>2008-08-06 11:12:24 +0930
commitc06e27b2f6fd9f7b9f827623a48876a225264132 (patch)
tree5e6aa44b668375e82db47af255e66888fe838928 /xkb
parentd9ca9819e975e0f6832a320f8be5958e5d942f85 (diff)
xkb: ProcXkbSetDeviceInfo should work on all attached SDs.
If called with XkbUseCoreKbd, run through all attached SDs and replicate the call. This way, we keep the SDs in sync with the MD as long as core clients control the MDs.
Diffstat (limited to 'xkb')
-rw-r--r--xkb/xkb.c106
1 files changed, 89 insertions, 17 deletions
diff --git a/xkb/xkb.c b/xkb/xkb.c
index ff6a47128..56be6e2ab 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -6413,25 +6413,15 @@ DeviceIntPtr kbd;
return (char *)ledWire;
}
-/* FIXME: Needs to set info on all core-sending devices. */
-int
-ProcXkbSetDeviceInfo(ClientPtr client)
-{
-DeviceIntPtr dev;
-unsigned change;
-char * wire;
-xkbExtensionDeviceNotify ed;
-
- REQUEST(xkbSetDeviceInfoReq);
- REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
-
- if (!(client->xkbClientFlags&_XkbClientInitialized))
- return BadAccess;
- change= stuff->change;
+static int
+_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
+ xkbSetDeviceInfoReq *stuff)
+{
+ unsigned change;
+ char *wire;
- CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
- CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask);
+ change = stuff->change;
wire= (char *)&stuff[1];
if (change&XkbXI_ButtonActionsMask) {
@@ -6456,6 +6446,17 @@ xkbExtensionDeviceNotify ed;
if (((wire-((char *)stuff))/4)!=stuff->length)
return BadLength;
+ return Success;
+}
+
+static int
+_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
+ xkbSetDeviceInfoReq *stuff)
+{
+ unsigned change;
+ char *wire;
+ xkbExtensionDeviceNotify ed;
+
bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
ed.deviceID= dev->id;
wire= (char *)&stuff[1];
@@ -6496,6 +6497,77 @@ xkbExtensionDeviceNotify ed;
}
if ((stuff->change)&&(ed.reason))
XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return Success;
+}
+
+int
+ProcXkbSetDeviceInfo(ClientPtr client)
+{
+ unsigned int change;
+ DeviceIntPtr dev;
+ int rc;
+
+ REQUEST(xkbSetDeviceInfoReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ change = stuff->change;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,change,XkbXI_AllFeaturesMask);
+
+ rc = _XkbSetDeviceInfoCheck(client, dev, stuff);
+
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (((other != dev) && !other->isMaster && (other->u.master == dev)) &&
+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
+ (stuff->deviceSpec == XkbUseCorePtr && other->button)))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetDeviceInfoCheck(client, other, stuff);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* checks done, apply */
+ rc = _XkbSetDeviceInfo(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (((other != dev) && !other->isMaster && (other->u.master == dev)) &&
+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
+ (stuff->deviceSpec == XkbUseCorePtr && other->button)))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetDeviceInfo(client, other, stuff);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
return client->noClientException;
}