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.
This commit is contained in:
Peter Hutterer 2007-10-16 11:30:32 +09:30
parent 204f2dc89e
commit 70efd3d06a
2 changed files with 65 additions and 20 deletions

View File

@ -189,8 +189,9 @@ AddInputDevice(DeviceProc deviceProc, Bool autoStart)
* list. Initialize the DIX sprite or pair the device. All clients are * list. Initialize the DIX sprite or pair the device. All clients are
* notified about the device being enabled. * 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. * @param The device to be enabled.
* @return TRUE on success or FALSE otherwise. * @return TRUE on success or FALSE otherwise.
*/ */
@ -200,6 +201,7 @@ EnableDevice(DeviceIntPtr dev)
DeviceIntPtr *prev; DeviceIntPtr *prev;
int ret; int ret;
DeviceIntRec dummyDev; DeviceIntRec dummyDev;
DeviceIntPtr other;
devicePresenceNotify ev; devicePresenceNotify ev;
for (prev = &inputInfo.off_devices; for (prev = &inputInfo.off_devices;
@ -207,15 +209,26 @@ EnableDevice(DeviceIntPtr dev)
prev = &(*prev)->next) prev = &(*prev)->next)
; ;
/* Sprites pop up on the first root window, so we can supply it directly
* here.
*/
if (!dev->spriteInfo->sprite) if (!dev->spriteInfo->sprite)
{ {
if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner) if (dev->isMaster)
InitializeSprite(dev, WindowTable[0]); {
else /* Sprites appear on first root window, so we can hardcode it */
PairDevices(NULL, inputInfo.pointer, dev); 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 || if ((*prev != dev) || !dev->inited ||
@ -247,12 +260,15 @@ EnableDevice(DeviceIntPtr dev)
* list. A device will not send events while disabled. All clients are * list. A device will not send events while disabled. All clients are
* notified about the device being disabled. * 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. * @return TRUE on success or FALSE otherwise.
*/ */
Bool Bool
DisableDevice(DeviceIntPtr dev) DisableDevice(DeviceIntPtr dev)
{ {
DeviceIntPtr *prev, paired; DeviceIntPtr *prev, other;
DeviceIntRec dummyDev; DeviceIntRec dummyDev;
devicePresenceNotify ev; devicePresenceNotify ev;
@ -262,20 +278,34 @@ DisableDevice(DeviceIntPtr dev)
; ;
if (*prev != dev) if (*prev != dev)
return FALSE; 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); (void)(*dev->deviceProc)(dev, DEVICE_OFF);
dev->enabled = FALSE; dev->enabled = FALSE;
*prev = dev->next; *prev = dev->next;
dev->next = inputInfo.off_devices; dev->next = inputInfo.off_devices;
inputInfo.off_devices = dev; inputInfo.off_devices = dev;
/* Some other device may have been paired with this device. /* float attached devices */
Re-pair with VCP. We don't repair with a real device, as this if (dev->isMaster)
may cause somebody suddenly typing where they shouldn't.
*/
for (paired = inputInfo.devices; paired; paired = paired->next)
{ {
if (paired->spriteInfo->paired == dev) for (other = inputInfo.devices; other; other = other->next)
PairDevices(NULL, inputInfo.pointer, paired); {
if (other->master == dev)
AttachDevice(NULL, dev, NULL);
}
} }
ev.type = DevicePresenceNotify; ev.type = DevicePresenceNotify;
@ -313,7 +343,7 @@ ActivateDevice(DeviceIntPtr dev)
dev->inited = (ret == Success); dev->inited = (ret == Success);
/* Initialize memory for sprites. */ /* Initialize memory for sprites. */
if (IsPointerDevice(dev)) if (dev->isMaster && dev->spriteInfo->spriteOwner)
pScreen->DeviceCursorInitialize(dev, pScreen); pScreen->DeviceCursorInitialize(dev, pScreen);
ev.type = DevicePresenceNotify; ev.type = DevicePresenceNotify;
@ -485,6 +515,7 @@ InitCoreDevices(void)
FatalError("Couldn't allocate keyboard devPrivates\n"); FatalError("Couldn't allocate keyboard devPrivates\n");
dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
dev->master = NULL; dev->master = NULL;
dev->isMaster = TRUE;
(void)ActivateDevice(dev); (void)ActivateDevice(dev);
inputInfo.keyboard = dev; inputInfo.keyboard = dev;
@ -512,6 +543,7 @@ InitCoreDevices(void)
FatalError("Couldn't allocate pointer devPrivates\n"); FatalError("Couldn't allocate pointer devPrivates\n");
dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL; dev->devPrivates[CoreDevicePrivatesIndex].ptr = NULL;
dev->master = NULL; dev->master = NULL;
dev->isMaster = TRUE;
(void)ActivateDevice(dev); (void)ActivateDevice(dev);
inputInfo.pointer = dev; inputInfo.pointer = dev;
@ -550,10 +582,10 @@ InitAndStartDevices(WindowPtr root)
} }
/* Now enable all devices */ /* Now enable all devices */
if (inputInfo.keyboard->inited && inputInfo.keyboard->startup)
EnableDevice(inputInfo.keyboard);
if (inputInfo.pointer->inited && inputInfo.pointer->startup) if (inputInfo.pointer->inited && inputInfo.pointer->startup)
EnableDevice(inputInfo.pointer); EnableDevice(inputInfo.pointer);
if (inputInfo.keyboard->inited && inputInfo.keyboard->startup)
EnableDevice(inputInfo.keyboard);
/* enable real devices */ /* enable real devices */
for (dev = inputInfo.off_devices; dev; dev = next) for (dev = inputInfo.off_devices; dev; dev = next)
@ -2367,3 +2399,15 @@ GuessFreePointerDevice()
return (lastRealPtr) ? lastRealPtr : inputInfo.pointer; 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;
}

View File

@ -476,6 +476,7 @@ extern Bool RegisterPairingClient(ClientPtr client);
extern Bool UnregisterPairingClient(ClientPtr client); extern Bool UnregisterPairingClient(ClientPtr client);
extern DeviceIntPtr GuessFreePointerDevice(void); extern DeviceIntPtr GuessFreePointerDevice(void);
extern DeviceIntPtr NextFreePointerDevice(void);
/* Window/device based access control */ /* Window/device based access control */
extern Bool ACRegisterClient(ClientPtr client); extern Bool ACRegisterClient(ClientPtr client);