From 033a2b12fcd02fa9a2c2f20a352bec0a43074512 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 12 May 2009 14:50:57 +1000 Subject: [PATCH] Xi: set per-device hierarchy changed flags. Rather than have one field per hierarchy change, XI2 has two fields - one generic one and one per-device that include the device-specific flags. This requires some funky handling for removed devices, but oh well. --- Xi/chdevhier.c | 65 ++++++++++++++++++++++++++++++++++++++++++-------- Xi/chdevhier.h | 2 +- dix/devices.c | 21 ++++++++++++---- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c index 96b515df4..1aaa3717f 100644 --- a/Xi/chdevhier.c +++ b/Xi/chdevhier.c @@ -59,25 +59,25 @@ extern DevPrivateKey XTstDevicePrivateKey; /** * Send the current state of the device hierarchy to all clients. */ -void XISendDeviceHierarchyEvent(int flags) +void XISendDeviceHierarchyEvent(int flags[MAXDEVICES]) { xXIDeviceHierarchyEvent *ev; xXIHierarchyInfo *info; DeviceIntRec dummyDev; DeviceIntPtr dev; + int i; if (!flags) return; - ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + inputInfo.numDevices * - sizeof(xXIHierarchyInfo)); + ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + + MAXDEVICES * sizeof(xXIHierarchyInfo)); ev->type = GenericEvent; ev->extension = IReqCode; ev->evtype = XI_HierarchyChanged; ev->time = GetTimeInMillis(); - ev->flags = flags; + ev->flags = 0; ev->num_devices = inputInfo.numDevices; - ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4; info = (xXIHierarchyInfo*)&ev[1]; for (dev = inputInfo.devices; dev; dev = dev->next) @@ -85,6 +85,8 @@ void XISendDeviceHierarchyEvent(int flags) info->deviceid = dev->id; info->enabled = dev->enabled; info->use = GetDeviceUse(dev, &info->attachment); + info->flags = flags[dev->id]; + ev->flags |= info->flags; info++; } for (dev = inputInfo.off_devices; dev; dev = dev->next) @@ -92,9 +94,28 @@ void XISendDeviceHierarchyEvent(int flags) info->deviceid = dev->id; info->enabled = dev->enabled; info->use = GetDeviceUse(dev, &info->attachment); + info->flags = flags[dev->id]; + ev->flags |= info->flags; info++; } + + for (i = 0; i < MAXDEVICES; i++) + { + if (flags[i] & (XIMasterRemoved | XISlaveRemoved)) + { + info->deviceid = i; + info->enabled = FALSE; + info->flags = flags[i]; + info->use = 0; + ev->flags |= info->flags; + ev->num_devices++; + info++; + } + } + + ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4; + dummyDev.id = XIAllDevices; SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1); } @@ -126,7 +147,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) int required_len = sizeof(xXIChangeDeviceHierarchyReq); char n; int rc = Success; - int flags = 0; + int flags[MAXDEVICES] = {0}; REQUEST(xXIChangeDeviceHierarchyReq); REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq); @@ -177,24 +198,35 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) ActivateDevice(ptr); ActivateDevice(keybd); + flags[ptr->id] |= XIMasterAdded; + flags[keybd->id] |= XIMasterAdded; + ActivateDevice(xtstptr); ActivateDevice(xtstkeybd); + flags[xtstptr->id] |= XISlaveAdded; + flags[xtstkeybd->id] |= XISlaveAdded; if (c->enable) { EnableDevice(ptr); EnableDevice(keybd); + flags[ptr->id] |= XIDeviceEnabled; + flags[keybd->id] |= XIDeviceEnabled; + EnableDevice(xtstptr); EnableDevice(xtstkeybd); + flags[xtstptr->id] |= XIDeviceEnabled; + flags[xtstkeybd->id] |= XIDeviceEnabled; } /* Attach the XTest virtual devices to the newly created master device */ AttachDevice(NULL, xtstptr, ptr); AttachDevice(NULL, xtstkeybd, keybd); + flags[xtstptr->id] |= XISlaveAttached; + flags[xtstkeybd->id] |= XISlaveAttached; xfree(name); - flags |= XIMasterAdded; } break; case XIRemoveMasterDevice: @@ -336,9 +368,15 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) { if (!attached->isMaster) { if (attached->u.master == ptr) + { AttachDevice(client, attached, newptr); + flags[attached->id] |= XISlaveAttached; + } if (attached->u.master == keybd) + { AttachDevice(client, attached, newkeybd); + flags[attached->id] |= XISlaveAttached; + } } } } @@ -355,12 +393,19 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) DisableDevice(xtstkeybd); DisableDevice(keybd); DisableDevice(ptr); + flags[xtstptr->id] |= XIDeviceDisabled | XISlaveDetached; + flags[xtstkeybd->id] |= XIDeviceDisabled | XISlaveDetached; + flags[keybd->id] |= XIDeviceDisabled; + flags[ptr->id] |= XIDeviceDisabled; RemoveDevice(xtstptr); RemoveDevice(xtstkeybd); RemoveDevice(keybd); RemoveDevice(ptr); - flags |= XIMasterRemoved; + flags[xtstptr->id] |= XISlaveRemoved; + flags[xtstkeybd->id] |= XISlaveRemoved; + flags[keybd->id] |= XIMasterRemoved; + flags[ptr->id] |= XIMasterRemoved; } break; case XIDetachSlave: @@ -392,7 +437,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) } AttachDevice(client, ptr, NULL); - flags |= XISlaveDetached; + flags[ptr->id] |= XISlaveDetached; } break; case XIAttachSlave: @@ -444,7 +489,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) goto unwind; } AttachDevice(client, ptr, newmaster); - flags |= XISlaveAttached; + flags[ptr->id] |= XISlaveAttached; } break; } diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h index d2d100120..d4ce517c1 100644 --- a/Xi/chdevhier.h +++ b/Xi/chdevhier.h @@ -39,6 +39,6 @@ int SProcXIChangeDeviceHierarchy(ClientPtr /* client */); int ProcXIChangeDeviceHierarchy(ClientPtr /* client */); -void XISendDeviceHierarchyEvent(int flags); +void XISendDeviceHierarchyEvent(int flags[]); #endif diff --git a/dix/devices.c b/dix/devices.c index dc5de0526..c59457f1d 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -296,6 +296,7 @@ EnableDevice(DeviceIntPtr dev) int listlen; EventListPtr evlist; BOOL enabled; + int flags[MAXDEVICES] = {0}; for (prev = &inputInfo.off_devices; *prev && (*prev != dev); @@ -361,7 +362,8 @@ EnableDevice(DeviceIntPtr dev) TRUE); SendDevicePresenceEvent(dev->id, DeviceEnabled); - XISendDeviceHierarchyEvent(XIDeviceEnabled); + flags[dev->id] |= XIDeviceEnabled; + XISendDeviceHierarchyEvent(flags); return TRUE; } @@ -381,6 +383,7 @@ DisableDevice(DeviceIntPtr dev) { DeviceIntPtr *prev, other; BOOL enabled; + int flags[MAXDEVICES] = {0}; for (prev = &inputInfo.devices; *prev && (*prev != dev); @@ -395,7 +398,10 @@ DisableDevice(DeviceIntPtr dev) for (other = inputInfo.devices; other; other = other->next) { if (other->u.master == dev) + { AttachDevice(NULL, other, NULL); + flags[other->id] |= XISlaveDetached; + } } } else @@ -432,7 +438,8 @@ DisableDevice(DeviceIntPtr dev) TRUE); SendDevicePresenceEvent(dev->id, DeviceDisabled); - XISendDeviceHierarchyEvent(XIDeviceDisabled); + flags[dev->id] = XIDeviceDisabled; + XISendDeviceHierarchyEvent(flags); return TRUE; } @@ -450,6 +457,7 @@ ActivateDevice(DeviceIntPtr dev) { int ret = Success; ScreenPtr pScreen = screenInfo.screens[0]; + int flags[MAXDEVICES]; if (!dev || !dev->deviceProc) return BadImplementation; @@ -464,7 +472,8 @@ ActivateDevice(DeviceIntPtr dev) pScreen->DeviceCursorInitialize(dev, pScreen); SendDevicePresenceEvent(dev->id, DeviceAdded); - XISendDeviceHierarchyEvent(XISlaveAdded); + flags[dev->id] = XISlaveAdded; + XISendDeviceHierarchyEvent(flags); return ret; } @@ -929,6 +938,7 @@ RemoveDevice(DeviceIntPtr dev) ScreenPtr screen = screenInfo.screens[0]; int deviceid; int initialized; + int flags[MAXDEVICES] = {0}; DebugF("(dix) removing device %d\n", dev->id); @@ -944,6 +954,7 @@ RemoveDevice(DeviceIntPtr dev) screen->DisplayCursor(dev, screen, NullCursor); DisableDevice(dev); + flags[dev->id] = XIDeviceDisabled; } prev = NULL; @@ -956,6 +967,7 @@ RemoveDevice(DeviceIntPtr dev) else prev->next = next; + flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); ret = Success; } @@ -965,6 +977,7 @@ RemoveDevice(DeviceIntPtr dev) for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { next = tmp->next; if (tmp == dev) { + flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved; CloseDevice(tmp); if (prev == NULL) @@ -979,7 +992,7 @@ RemoveDevice(DeviceIntPtr dev) if (ret == Success && initialized) { inputInfo.numDevices--; SendDevicePresenceEvent(deviceid, DeviceRemoved); - XISendDeviceHierarchyEvent(XISlaveRemoved); + XISendDeviceHierarchyEvent(flags); } return ret;