From 6458bfe7847614d3f0eba0d738dfb60795983d9c Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Fri, 1 Aug 2008 16:42:15 +0930 Subject: [PATCH] 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. --- xkb/xkb.c | 106 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file 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) + +static int +_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, + xkbSetDeviceInfoReq *stuff) { -DeviceIntPtr dev; -unsigned change; -char * wire; -xkbExtensionDeviceNotify ed; + unsigned change; + char *wire; - 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); + 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; }