summaryrefslogtreecommitdiff
path: root/xkb
diff options
context:
space:
mode:
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;
}