From b5004722a208479a4bc762ff428bf4cbeb430d53 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 28 Apr 2008 10:26:01 +0930 Subject: [PATCH] Xi: Only return VCP, VCK and floating SDs to Xi 1.x clients. This is better than the approach implemented with 8973a3f7983240407dd6da59b3643f40e6a3d83a which disabled XI altogether for 1.x. Instead, return a device list that resembles a traditional XI setup on pre XI 2.0 servers. If the client tries to open a device other than a floating SD, return a BadDevice error. --- Xi/listdev.c | 91 ++++++++++++++++++++++++++++++---------------------- Xi/opendev.c | 11 +++++++ 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/Xi/listdev.c b/Xi/listdev.c index b588c247d8..c484dcca76 100644 --- a/Xi/listdev.c +++ b/Xi/listdev.c @@ -315,9 +315,9 @@ CopySwapClasses(ClientPtr client, DeviceIntPtr dev, CARD8 *num_classes, * This procedure lists the input devices available to the server. * * If this request is called by a client that has not issued a - * GetExtensionVersion request with major/minor version set, we pretend no - * devices are available. It's the only thing we can do to stop pre-XI 2 - * clients. + * GetExtensionVersion request with major/minor version set, we don't send the + * complete device list. Instead, we only send the VCP, the VCK and floating + * SDs. This resembles the setup found on XI 1.x machines. */ int @@ -347,34 +347,35 @@ ProcXListInputDevices(ClientPtr client) AddOtherInputDevices(); - if (pXIClient->major_version >= XI_2_Major) { - for (d = inputInfo.devices; d; d = d->next) { - 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) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); - if (rc != Success) - return rc; - SizeDeviceInfo(d, &namesize, &size); - numdevs++; - } - } else - { - /* Pretend we don't have XI devices connected */ - rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.pointer, DixGetAttrAccess); - if (rc != Success) - return rc; - rc = XaceHook(XACE_DEVICE_ACCESS, client, inputInfo.keyboard, DixGetAttrAccess); - if (rc != Success) - return rc; + for (d = inputInfo.devices; d; d = d->next) { + if (pXIClient->major_version < XI_2_Major) + { + if (d->isMaster && + d != inputInfo.pointer && + d != inputInfo.keyboard) + continue; /* don't send master devices other than VCP/VCK */ - SizeDeviceInfo(inputInfo.pointer, &namesize, &size); - SizeDeviceInfo(inputInfo.keyboard, &namesize, &size); - numdevs = 2; + if (!d->isMaster && d->u.master) + continue; /* don't send attached SDs */ + } + 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 (pXIClient->major_version < XI_2_Major && + !d->isMaster && + d->u.master) /* XXX can off_devices be attached? */ + continue; /* don't send attached SDs */ + + rc = XaceHook(XACE_DEVICE_ACCESS, client, d, DixGetAttrAccess); + if (rc != Success) + return rc; + SizeDeviceInfo(d, &namesize, &size); + numdevs++; } total_length = numdevs * sizeof(xDeviceInfo) + size + namesize; @@ -384,18 +385,30 @@ ProcXListInputDevices(ClientPtr client) savbuf = devbuf; dev = (xDeviceInfoPtr) devbuf; - if (pXIClient->major_version >= XI_2_Major) + for (d = inputInfo.devices; d; d = d->next) { - for (d = inputInfo.devices; d; d = d->next, dev++) - ListDeviceInfo(client, d, dev, &devbuf, &classbuf, &namebuf); - for (d = inputInfo.off_devices; d; d = d->next, dev++) - ListDeviceInfo(client, d, dev, &devbuf, &classbuf, &namebuf); - } else - { - ListDeviceInfo(client, inputInfo.pointer, dev, &devbuf, &classbuf, &namebuf); - ListDeviceInfo(client, inputInfo.keyboard, dev, &devbuf, &classbuf, &namebuf); + if (pXIClient->major_version < XI_2_Major) + { + if (d->isMaster && + d != inputInfo.pointer && + d != inputInfo.keyboard) + continue; /* don't count master devices other than VCP/VCK */ + + if (!d->isMaster && d->u.master) + continue; /* don't count attached SDs */ + } + ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); } + for (d = inputInfo.off_devices; d; d = d->next) + { + if (pXIClient->major_version < XI_2_Major && + !d->isMaster && + d->u.master) /* XXX can off_devices be attached? */ + continue; /* don't send attached SDs */ + + ListDeviceInfo(client, d, dev++, &devbuf, &classbuf, &namebuf); + } rep.ndevices = numdevs; rep.length = (total_length + 3) >> 2; WriteReplyToClient(client, sizeof(xListInputDevicesReply), &rep); diff --git a/Xi/opendev.c b/Xi/opendev.c index f14f848bfc..c51bb7e3f5 100644 --- a/Xi/opendev.c +++ b/Xi/opendev.c @@ -62,6 +62,7 @@ SOFTWARE. #include "XIstubs.h" #include "windowstr.h" /* window structure */ #include "exglobals.h" +#include "exevents.h" #include "opendev.h" @@ -98,6 +99,7 @@ ProcXOpenDevice(ClientPtr client) int status = Success; xOpenDeviceReply rep; DeviceIntPtr dev; + XIClientPtr pXIClient; REQUEST(xOpenDeviceReq); REQUEST_SIZE_MATCH(xOpenDeviceReq); @@ -113,6 +115,15 @@ ProcXOpenDevice(ClientPtr client) } else if (status != Success) return status; + /* Don't let XI 1.x clients open devices other than floating SDs. */ + pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); + if (pXIClient->major_version < XI_2_Major) + { + if (dev->isMaster || (!dev->isMaster && dev->u.master)) + return BadDevice; + } + + OpenInputDevice(dev, client, &status); if (status != Success) return status;