diff --git a/Xi/listdev.c b/Xi/listdev.c index 95c1532b4..1c847fbeb 100644 --- a/Xi/listdev.c +++ b/Xi/listdev.c @@ -306,6 +306,25 @@ ListDeviceInfo(ClientPtr client, DeviceIntPtr d, xDeviceInfoPtr dev, CopySwapClasses(client, d, &dev->num_classes, classbuf); } +/*********************************************************************** + * + * This procedure checks if a device should be left off the list. + * + */ + +static Bool +ShouldSkipDevice(ClientPtr client, DeviceIntPtr d) +{ + /* don't send master devices other than VCP/VCK */ + if (!IsMaster(d) || d == inputInfo.pointer || d == inputInfo.keyboard) + { + int rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); + if (rc == Success) + return FALSE; + } + return TRUE; +} + /*********************************************************************** * @@ -323,12 +342,10 @@ ProcXListInputDevices(ClientPtr client) xListInputDevicesReply rep; int numdevs = 0; int namesize = 1; /* need 1 extra byte for strcpy */ - int rc, size = 0; + int i = 0, size = 0; int total_length; - char *devbuf; - char *classbuf; - char *namebuf; - char *savbuf; + char *devbuf, *classbuf, *namebuf, *savbuf; + Bool *skip; xDeviceInfo *dev; DeviceIntPtr d; @@ -343,55 +360,51 @@ ProcXListInputDevices(ClientPtr client) AddOtherInputDevices(); - for (d = inputInfo.devices; d; d = d->next) { - if (IsMaster(d) && - d != inputInfo.pointer && - d != inputInfo.keyboard) - continue; /* don't send master devices other than VCP/VCK */ + /* allocate space for saving skip value */ + skip = xcalloc(sizeof(Bool), inputInfo.numDevices); + if (!skip) + return BadAlloc; + + /* figure out which devices to skip */ + numdevs = 0; + for (d = inputInfo.devices; d; d = d->next, i++) { + skip[i] = ShouldSkipDevice(client, d); + if (skip[i]) + continue; - rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); - if (rc != Success) - return rc; SizeDeviceInfo(d, &namesize, &size); numdevs++; } - for (d = inputInfo.off_devices; d; d = d->next) { - if (IsMaster(d) && - d != inputInfo.pointer && - d != inputInfo.keyboard) - continue; /* don't send master devices other than VCP/VCK */ + for (d = inputInfo.off_devices; d; d = d->next, i++) { + skip[i] = ShouldSkipDevice(client, d); + if (skip[i]) + continue; - rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); - if (rc != Success) - return rc; SizeDeviceInfo(d, &namesize, &size); numdevs++; } + /* allocate space for reply */ total_length = numdevs * sizeof(xDeviceInfo) + size + namesize; devbuf = (char *)xcalloc(1, total_length); classbuf = devbuf + (numdevs * sizeof(xDeviceInfo)); namebuf = classbuf + size; savbuf = devbuf; + /* fill in and send reply */ + i = 0; dev = (xDeviceInfoPtr) devbuf; - for (d = inputInfo.devices; d; d = d->next) - { - if (IsMaster(d) && - d != inputInfo.pointer && - d != inputInfo.keyboard) - continue; /* don't count master devices other than VCP/VCK */ + for (d = inputInfo.devices; d; d = d->next, i++) { + if (skip[i]) + continue; ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); } - for (d = inputInfo.off_devices; d; d = d->next) - { - if (IsMaster(d) && - d != inputInfo.pointer && - d != inputInfo.keyboard) - continue; /* don't count master devices other than VCP/VCK */ + for (d = inputInfo.off_devices; d; d = d->next, i++) { + if (skip[i]) + continue; ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); } @@ -400,6 +413,7 @@ ProcXListInputDevices(ClientPtr client) WriteReplyToClient(client, sizeof(xListInputDevicesReply), &rep); WriteToClient(client, total_length, savbuf); xfree(savbuf); + xfree(skip); return Success; } diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c index 6aa168521..33628a6ef 100644 --- a/Xi/xiquerydevice.c +++ b/Xi/xiquerydevice.c @@ -40,9 +40,11 @@ #include "xkbsrv.h" #include "xserver-properties.h" #include "exevents.h" +#include "xace.h" #include "xiquerydevice.h" +static Bool ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr d); static int ListDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); static int SizeDeviceInfo(DeviceIntPtr dev); static void SwapDeviceInfo(DeviceIntPtr dev, xXIDeviceInfo* info); @@ -65,8 +67,9 @@ ProcXIQueryDevice(ClientPtr client) xXIQueryDeviceReply rep; DeviceIntPtr dev = NULL; int rc = Success; - int len = 0; + int i = 0, len = 0; char *info, *ptr; + Bool *skip = NULL; REQUEST(xXIQueryDeviceReq); REQUEST_SIZE_MATCH(xXIQueryDeviceReq); @@ -79,28 +82,27 @@ ProcXIQueryDevice(ClientPtr client) client->errorValue = stuff->deviceid; return rc; } - } - - if (dev) len += SizeDeviceInfo(dev); + } else { - len = 0; - for (dev = inputInfo.devices; dev; dev = dev->next) + skip = xcalloc(sizeof(Bool), inputInfo.numDevices); + if (!skip) + return BadAlloc; + + for (dev = inputInfo.devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) len += SizeDeviceInfo(dev); } - for (dev = inputInfo.off_devices; dev; dev = dev->next) + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev); + if (!skip[i]) len += SizeDeviceInfo(dev); } - - dev = NULL; } info = xcalloc(1, len); @@ -124,10 +126,10 @@ ProcXIQueryDevice(ClientPtr client) rep.num_devices = 1; } else { - for (dev = inputInfo.devices; dev; dev = dev->next) + i = 0; + for (dev = inputInfo.devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + if (!skip[i]) { len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); if (client->swapped) @@ -137,10 +139,9 @@ ProcXIQueryDevice(ClientPtr client) } } - for (dev = inputInfo.off_devices; dev; dev = dev->next) + for (dev = inputInfo.off_devices; dev; dev = dev->next, i++) { - if (stuff->deviceid == XIAllDevices || - (stuff->deviceid == XIAllMasterDevices && IsMaster(dev))) + if (!skip[i]) { len = ListDeviceInfo(dev, (xXIDeviceInfo*)info); if (client->swapped) @@ -154,6 +155,7 @@ ProcXIQueryDevice(ClientPtr client) WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep); WriteToClient(client, rep.length * 4, ptr); xfree(ptr); + xfree(skip); return rc; } @@ -172,6 +174,21 @@ SRepXIQueryDevice(ClientPtr client, int size, xXIQueryDeviceReply *rep) } +/** + * @return Whether the device should be included in the returned list. + */ +static Bool +ShouldSkipDevice(ClientPtr client, int deviceid, DeviceIntPtr dev) +{ + /* if all devices are not being queried, only master devices are */ + if (deviceid == XIAllDevices || IsMaster(dev)) + { + int rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); + if (rc == Success) + return FALSE; + } + return TRUE; +} /** * @return The number of bytes needed to store this device's xXIDeviceInfo