diff options
author | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-10-16 11:30:32 +0930 |
---|---|---|
committer | Peter Hutterer <peter@cs.unisa.edu.au> | 2007-10-16 11:30:32 +0930 |
commit | 70efd3d06a15093661933bda4ec21e306dece4a4 (patch) | |
tree | ac92c430aee87b61ca2d28628cc2b6bb0f43d802 | |
parent | 204f2dc89ef662b57400b128c30c15e8cf32f323 (diff) |
dix: fix up Activate/Enable/Disable device.
Set isMaster for VCP/VCK.
Init sprites for master pointer devices.
Pair master kbds with master pointers (1:1 pairing!).
Attach other devices to VCP/VCK.
-rw-r--r-- | dix/devices.c | 84 | ||||
-rw-r--r-- | include/input.h | 1 |
2 files changed, 65 insertions, 20 deletions
diff --git a/dix/devices.c b/dix/devices.c index c41fa0c69..2dd3f9e5e 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -189,8 +189,9 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart) * list. Initialize the DIX sprite or pair the device. All clients are * notified about the device being enabled. * - * A device will send events once enabled. - * + * A master pointer device needs to be enabled before a master keyboard + * device. + * * @param The device to be enabled. * @return TRUE on success or FALSE otherwise. */ @@ -200,6 +201,7 @@ EnableDevice(DeviceIntPtr dev) DeviceIntPtr *prev; int ret; DeviceIntRec dummyDev; + DeviceIntPtr other; devicePresenceNotify ev; for (prev = &inputInfo.off_devices; @@ -207,15 +209,26 @@ EnableDevice(DeviceIntPtr dev) prev = &(*prev)->next) ; - /* Sprites pop up on the first root window, so we can supply it directly - * here. - */ if (!dev->spriteInfo->sprite) { - if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner) - InitializeSprite(dev, WindowTable[0]); - else - PairDevices(NULL, inputInfo.pointer, dev); + if (dev->isMaster) + { + /* Sprites appear on first root window, so we can hardcode it */ + if (dev->spriteInfo->spriteOwner) + InitializeSprite(dev, WindowTable[0]); + else if ((other = NextFreePointerDevice()) == NULL) + { + ErrorF("[dix] cannot find pointer to pair with. " + "This is a bug.\n"); + return FALSE; + } else + PairDevices(NULL, other, dev); + } else + { + other = (IsPointerDevice(dev)) ? inputInfo.pointer : + inputInfo.keyboard; + AttachDevice(NULL, dev, other); + } } if ((*prev != dev) || !dev->inited || @@ -247,12 +260,15 @@ EnableDevice(DeviceIntPtr dev) * list. A device will not send events while disabled. All clients are * notified about the device being disabled. * + * Master keyboard devices have to be disabled before master pointer devices + * otherwise things turn bad. + * * @return TRUE on success or FALSE otherwise. */ Bool DisableDevice(DeviceIntPtr dev) { - DeviceIntPtr *prev, paired; + DeviceIntPtr *prev, other; DeviceIntRec dummyDev; devicePresenceNotify ev; @@ -262,20 +278,34 @@ DisableDevice(DeviceIntPtr dev) ; if (*prev != dev) return FALSE; + + if (dev->isMaster && dev->spriteInfo->sprite) + { + for (other = inputInfo.devices; other; other = other->next) + { + if (other->spriteInfo->paired == dev) + { + ErrorF("[dix] cannot disable device, still paired. " + "This is a bug. \n"); + return FALSE; + } + } + } + (void)(*dev->deviceProc)(dev, DEVICE_OFF); dev->enabled = FALSE; *prev = dev->next; dev->next = inputInfo.off_devices; inputInfo.off_devices = dev; - /* Some other device may have been paired with this device. - Re-pair with VCP. We don't repair with a real device, as this - may cause somebody suddenly typing where they shouldn't. - */ - for (paired = inputInfo.devices; paired; paired = paired->next) + /* float attached devices */ + if (dev->isMaster) { - if (paired->spriteInfo->paired == dev) - PairDevices(NULL, inputInfo.pointer, paired); + for (other = inputInfo.devices; other; other = other->next) + { + if (other->master == dev) + AttachDevice(NULL, dev, NULL); + } } ev.type = DevicePresenceNotify; @@ -313,7 +343,7 @@ ActivateDevice(DeviceIntPtr dev) dev->inited = (ret == Success); /* Initialize memory for sprites. */ - if (IsPointerDevice(dev)) + if (dev->isMaster && dev->spriteInfo->spriteOwner) pScreen->DeviceCursorInitialize(dev, pScreen); ev.type = DevicePresenceNotify; @@ -485,6 +515,7 @@ InitCoreDevices(void) FatalError("Couldn't allocate keyboard devPrivates\n"); dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; dev->master = NULL; + dev->isMaster = TRUE; (void)ActivateDevice(dev); inputInfo.keyboard = dev; @@ -512,6 +543,7 @@ InitCoreDevices(void) FatalError("Couldn't allocate pointer devPrivates\n"); dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; dev->master = NULL; + dev->isMaster = TRUE; (void)ActivateDevice(dev); inputInfo.pointer = dev; @@ -550,10 +582,10 @@ InitAndStartDevices(WindowPtr root) } /* Now enable all devices */ - if (inputInfo.keyboard->inited && inputInfo.keyboard->startup) - EnableDevice(inputInfo.keyboard); if (inputInfo.pointer->inited && inputInfo.pointer->startup) EnableDevice(inputInfo.pointer); + if (inputInfo.keyboard->inited && inputInfo.keyboard->startup) + EnableDevice(inputInfo.keyboard); /* enable real devices */ for (dev = inputInfo.off_devices; dev; dev = next) @@ -2367,3 +2399,15 @@ GuessFreePointerDevice() return (lastRealPtr) ? lastRealPtr : inputInfo.pointer; } + +DeviceIntPtr +NextFreePointerDevice() +{ + DeviceIntPtr dev; + for (dev = inputInfo.devices; dev; dev = dev->next) + if (dev->isMaster && + dev->spriteInfo->spriteOwner && + !dev->spriteInfo->paired) + return dev; + return NULL; +} diff --git a/include/input.h b/include/input.h index 1ef36b8d8..f41514a43 100644 --- a/include/input.h +++ b/include/input.h @@ -476,6 +476,7 @@ extern Bool RegisterPairingClient(ClientPtr client); extern Bool UnregisterPairingClient(ClientPtr client); extern DeviceIntPtr GuessFreePointerDevice(void); +extern DeviceIntPtr NextFreePointerDevice(void); /* Window/device based access control */ extern Bool ACRegisterClient(ClientPtr client); |