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.
This commit is contained in:
Peter Hutterer 2009-05-12 14:50:57 +10:00
parent 8fb51feae2
commit 033a2b12fc
3 changed files with 73 additions and 15 deletions

View File

@ -59,25 +59,25 @@ extern DevPrivateKey XTstDevicePrivateKey;
/** /**
* Send the current state of the device hierarchy to all clients. * Send the current state of the device hierarchy to all clients.
*/ */
void XISendDeviceHierarchyEvent(int flags) void XISendDeviceHierarchyEvent(int flags[MAXDEVICES])
{ {
xXIDeviceHierarchyEvent *ev; xXIDeviceHierarchyEvent *ev;
xXIHierarchyInfo *info; xXIHierarchyInfo *info;
DeviceIntRec dummyDev; DeviceIntRec dummyDev;
DeviceIntPtr dev; DeviceIntPtr dev;
int i;
if (!flags) if (!flags)
return; return;
ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + inputInfo.numDevices * ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) +
sizeof(xXIHierarchyInfo)); MAXDEVICES * sizeof(xXIHierarchyInfo));
ev->type = GenericEvent; ev->type = GenericEvent;
ev->extension = IReqCode; ev->extension = IReqCode;
ev->evtype = XI_HierarchyChanged; ev->evtype = XI_HierarchyChanged;
ev->time = GetTimeInMillis(); ev->time = GetTimeInMillis();
ev->flags = flags; ev->flags = 0;
ev->num_devices = inputInfo.numDevices; ev->num_devices = inputInfo.numDevices;
ev->length = (ev->num_devices * sizeof(xXIHierarchyInfo))/4;
info = (xXIHierarchyInfo*)&ev[1]; info = (xXIHierarchyInfo*)&ev[1];
for (dev = inputInfo.devices; dev; dev = dev->next) for (dev = inputInfo.devices; dev; dev = dev->next)
@ -85,6 +85,8 @@ void XISendDeviceHierarchyEvent(int flags)
info->deviceid = dev->id; info->deviceid = dev->id;
info->enabled = dev->enabled; info->enabled = dev->enabled;
info->use = GetDeviceUse(dev, &info->attachment); info->use = GetDeviceUse(dev, &info->attachment);
info->flags = flags[dev->id];
ev->flags |= info->flags;
info++; info++;
} }
for (dev = inputInfo.off_devices; dev; dev = dev->next) for (dev = inputInfo.off_devices; dev; dev = dev->next)
@ -92,9 +94,28 @@ void XISendDeviceHierarchyEvent(int flags)
info->deviceid = dev->id; info->deviceid = dev->id;
info->enabled = dev->enabled; info->enabled = dev->enabled;
info->use = GetDeviceUse(dev, &info->attachment); info->use = GetDeviceUse(dev, &info->attachment);
info->flags = flags[dev->id];
ev->flags |= info->flags;
info++; 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; dummyDev.id = XIAllDevices;
SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1); SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1);
} }
@ -126,7 +147,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
int required_len = sizeof(xXIChangeDeviceHierarchyReq); int required_len = sizeof(xXIChangeDeviceHierarchyReq);
char n; char n;
int rc = Success; int rc = Success;
int flags = 0; int flags[MAXDEVICES] = {0};
REQUEST(xXIChangeDeviceHierarchyReq); REQUEST(xXIChangeDeviceHierarchyReq);
REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq); REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
@ -177,24 +198,35 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
ActivateDevice(ptr); ActivateDevice(ptr);
ActivateDevice(keybd); ActivateDevice(keybd);
flags[ptr->id] |= XIMasterAdded;
flags[keybd->id] |= XIMasterAdded;
ActivateDevice(xtstptr); ActivateDevice(xtstptr);
ActivateDevice(xtstkeybd); ActivateDevice(xtstkeybd);
flags[xtstptr->id] |= XISlaveAdded;
flags[xtstkeybd->id] |= XISlaveAdded;
if (c->enable) if (c->enable)
{ {
EnableDevice(ptr); EnableDevice(ptr);
EnableDevice(keybd); EnableDevice(keybd);
flags[ptr->id] |= XIDeviceEnabled;
flags[keybd->id] |= XIDeviceEnabled;
EnableDevice(xtstptr); EnableDevice(xtstptr);
EnableDevice(xtstkeybd); EnableDevice(xtstkeybd);
flags[xtstptr->id] |= XIDeviceEnabled;
flags[xtstkeybd->id] |= XIDeviceEnabled;
} }
/* Attach the XTest virtual devices to the newly /* Attach the XTest virtual devices to the newly
created master device */ created master device */
AttachDevice(NULL, xtstptr, ptr); AttachDevice(NULL, xtstptr, ptr);
AttachDevice(NULL, xtstkeybd, keybd); AttachDevice(NULL, xtstkeybd, keybd);
flags[xtstptr->id] |= XISlaveAttached;
flags[xtstkeybd->id] |= XISlaveAttached;
xfree(name); xfree(name);
flags |= XIMasterAdded;
} }
break; break;
case XIRemoveMasterDevice: case XIRemoveMasterDevice:
@ -336,9 +368,15 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
{ {
if (!attached->isMaster) { if (!attached->isMaster) {
if (attached->u.master == ptr) if (attached->u.master == ptr)
{
AttachDevice(client, attached, newptr); AttachDevice(client, attached, newptr);
flags[attached->id] |= XISlaveAttached;
}
if (attached->u.master == keybd) if (attached->u.master == keybd)
{
AttachDevice(client, attached, newkeybd); AttachDevice(client, attached, newkeybd);
flags[attached->id] |= XISlaveAttached;
}
} }
} }
} }
@ -355,12 +393,19 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
DisableDevice(xtstkeybd); DisableDevice(xtstkeybd);
DisableDevice(keybd); DisableDevice(keybd);
DisableDevice(ptr); DisableDevice(ptr);
flags[xtstptr->id] |= XIDeviceDisabled | XISlaveDetached;
flags[xtstkeybd->id] |= XIDeviceDisabled | XISlaveDetached;
flags[keybd->id] |= XIDeviceDisabled;
flags[ptr->id] |= XIDeviceDisabled;
RemoveDevice(xtstptr); RemoveDevice(xtstptr);
RemoveDevice(xtstkeybd); RemoveDevice(xtstkeybd);
RemoveDevice(keybd); RemoveDevice(keybd);
RemoveDevice(ptr); RemoveDevice(ptr);
flags |= XIMasterRemoved; flags[xtstptr->id] |= XISlaveRemoved;
flags[xtstkeybd->id] |= XISlaveRemoved;
flags[keybd->id] |= XIMasterRemoved;
flags[ptr->id] |= XIMasterRemoved;
} }
break; break;
case XIDetachSlave: case XIDetachSlave:
@ -392,7 +437,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
} }
AttachDevice(client, ptr, NULL); AttachDevice(client, ptr, NULL);
flags |= XISlaveDetached; flags[ptr->id] |= XISlaveDetached;
} }
break; break;
case XIAttachSlave: case XIAttachSlave:
@ -444,7 +489,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
goto unwind; goto unwind;
} }
AttachDevice(client, ptr, newmaster); AttachDevice(client, ptr, newmaster);
flags |= XISlaveAttached; flags[ptr->id] |= XISlaveAttached;
} }
break; break;
} }

View File

@ -39,6 +39,6 @@
int SProcXIChangeDeviceHierarchy(ClientPtr /* client */); int SProcXIChangeDeviceHierarchy(ClientPtr /* client */);
int ProcXIChangeDeviceHierarchy(ClientPtr /* client */); int ProcXIChangeDeviceHierarchy(ClientPtr /* client */);
void XISendDeviceHierarchyEvent(int flags); void XISendDeviceHierarchyEvent(int flags[]);
#endif #endif

View File

@ -296,6 +296,7 @@ EnableDevice(DeviceIntPtr dev)
int listlen; int listlen;
EventListPtr evlist; EventListPtr evlist;
BOOL enabled; BOOL enabled;
int flags[MAXDEVICES] = {0};
for (prev = &inputInfo.off_devices; for (prev = &inputInfo.off_devices;
*prev && (*prev != dev); *prev && (*prev != dev);
@ -361,7 +362,8 @@ EnableDevice(DeviceIntPtr dev)
TRUE); TRUE);
SendDevicePresenceEvent(dev->id, DeviceEnabled); SendDevicePresenceEvent(dev->id, DeviceEnabled);
XISendDeviceHierarchyEvent(XIDeviceEnabled); flags[dev->id] |= XIDeviceEnabled;
XISendDeviceHierarchyEvent(flags);
return TRUE; return TRUE;
} }
@ -381,6 +383,7 @@ DisableDevice(DeviceIntPtr dev)
{ {
DeviceIntPtr *prev, other; DeviceIntPtr *prev, other;
BOOL enabled; BOOL enabled;
int flags[MAXDEVICES] = {0};
for (prev = &inputInfo.devices; for (prev = &inputInfo.devices;
*prev && (*prev != dev); *prev && (*prev != dev);
@ -395,7 +398,10 @@ DisableDevice(DeviceIntPtr dev)
for (other = inputInfo.devices; other; other = other->next) for (other = inputInfo.devices; other; other = other->next)
{ {
if (other->u.master == dev) if (other->u.master == dev)
{
AttachDevice(NULL, other, NULL); AttachDevice(NULL, other, NULL);
flags[other->id] |= XISlaveDetached;
}
} }
} }
else else
@ -432,7 +438,8 @@ DisableDevice(DeviceIntPtr dev)
TRUE); TRUE);
SendDevicePresenceEvent(dev->id, DeviceDisabled); SendDevicePresenceEvent(dev->id, DeviceDisabled);
XISendDeviceHierarchyEvent(XIDeviceDisabled); flags[dev->id] = XIDeviceDisabled;
XISendDeviceHierarchyEvent(flags);
return TRUE; return TRUE;
} }
@ -450,6 +457,7 @@ ActivateDevice(DeviceIntPtr dev)
{ {
int ret = Success; int ret = Success;
ScreenPtr pScreen = screenInfo.screens[0]; ScreenPtr pScreen = screenInfo.screens[0];
int flags[MAXDEVICES];
if (!dev || !dev->deviceProc) if (!dev || !dev->deviceProc)
return BadImplementation; return BadImplementation;
@ -464,7 +472,8 @@ ActivateDevice(DeviceIntPtr dev)
pScreen->DeviceCursorInitialize(dev, pScreen); pScreen->DeviceCursorInitialize(dev, pScreen);
SendDevicePresenceEvent(dev->id, DeviceAdded); SendDevicePresenceEvent(dev->id, DeviceAdded);
XISendDeviceHierarchyEvent(XISlaveAdded); flags[dev->id] = XISlaveAdded;
XISendDeviceHierarchyEvent(flags);
return ret; return ret;
} }
@ -929,6 +938,7 @@ RemoveDevice(DeviceIntPtr dev)
ScreenPtr screen = screenInfo.screens[0]; ScreenPtr screen = screenInfo.screens[0];
int deviceid; int deviceid;
int initialized; int initialized;
int flags[MAXDEVICES] = {0};
DebugF("(dix) removing device %d\n", dev->id); DebugF("(dix) removing device %d\n", dev->id);
@ -944,6 +954,7 @@ RemoveDevice(DeviceIntPtr dev)
screen->DisplayCursor(dev, screen, NullCursor); screen->DisplayCursor(dev, screen, NullCursor);
DisableDevice(dev); DisableDevice(dev);
flags[dev->id] = XIDeviceDisabled;
} }
prev = NULL; prev = NULL;
@ -956,6 +967,7 @@ RemoveDevice(DeviceIntPtr dev)
else else
prev->next = next; prev->next = next;
flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved;
CloseDevice(tmp); CloseDevice(tmp);
ret = Success; ret = Success;
} }
@ -965,6 +977,7 @@ RemoveDevice(DeviceIntPtr dev)
for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) { for (tmp = inputInfo.off_devices; tmp; (prev = tmp), (tmp = next)) {
next = tmp->next; next = tmp->next;
if (tmp == dev) { if (tmp == dev) {
flags[tmp->id] = (tmp->isMaster) ? XIMasterRemoved : XISlaveRemoved;
CloseDevice(tmp); CloseDevice(tmp);
if (prev == NULL) if (prev == NULL)
@ -979,7 +992,7 @@ RemoveDevice(DeviceIntPtr dev)
if (ret == Success && initialized) { if (ret == Success && initialized) {
inputInfo.numDevices--; inputInfo.numDevices--;
SendDevicePresenceEvent(deviceid, DeviceRemoved); SendDevicePresenceEvent(deviceid, DeviceRemoved);
XISendDeviceHierarchyEvent(XISlaveRemoved); XISendDeviceHierarchyEvent(flags);
} }
return ret; return ret;