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.
This commit is contained in:
Peter Hutterer 2008-08-01 16:42:15 +09:30
parent d9ca9819e9
commit c06e27b2f6

106
xkb/xkb.c
View File

@ -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;
}