From 32f338263ff7de1a2e76d570c98f5be979c18d4e Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Sun, 8 Mar 2009 21:32:31 +1000 Subject: [PATCH] Xi: Deliver XI2 HierarchyEvents when the hierarchy changes. Signed-off-by: Peter Hutterer --- Xi/chdevhier.c | 73 +++++++++++++++++++++++++++++++++++++------------- Xi/chdevhier.h | 2 ++ Xi/extinit.c | 29 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 19 deletions(-) diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c index 3df9c8743..2b107e7fa 100644 --- a/Xi/chdevhier.c +++ b/Xi/chdevhier.c @@ -1,5 +1,6 @@ /* * Copyright 2007-2008 Peter Hutterer + * Copyright 2009 Red Hat, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -47,11 +48,55 @@ #include "exglobals.h" #include "geext.h" #include "xace.h" +#include "querydev.h" /* for GetDeviceUse */ #include "xkbsrv.h" #include "chdevhier.h" +/** + * Send the current state of the device hierarchy to all clients. + */ +void XISendDeviceHierarchyEvent(int flags) +{ + xXIDeviceHierarchyEvent *ev; + xXIHierarchyInfo *info; + DeviceIntRec dummyDev; + DeviceIntPtr dev; + + if (!flags) + return; + + ev = xcalloc(1, sizeof(xXIDeviceHierarchyEvent) + inputInfo.numDevices * + sizeof(xXIHierarchyInfo)); + ev->type = GenericEvent; + ev->extension = IReqCode; + ev->evtype = XI_HierarchyChanged; + ev->time = GetTimeInMillis(); + ev->flags = flags; + 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) + { + info->deviceid = dev->id; + info->enabled = dev->enabled; + info->use = GetDeviceUse(dev, &info->attachment); + info++; + } + for (dev = inputInfo.off_devices; dev; dev = dev->next) + { + info->deviceid = dev->id; + info->enabled = dev->enabled; + info->use = GetDeviceUse(dev, &info->attachment); + info++; + } + + dummyDev.id = AllDevices; + SendEventToAllWindows(&dummyDev, (XI_HierarchyChangedMask >> 8), (xEvent*)ev, 1); +} + /*********************************************************************** * @@ -75,17 +120,18 @@ int ProcXIChangeDeviceHierarchy(ClientPtr client) { DeviceIntPtr ptr, keybd; - DeviceIntRec dummyDev; xXIAnyHierarchyChangeInfo *any; int required_len = sizeof(xXIChangeDeviceHierarchyReq); char n; int rc = Success; - int nchanges = 0; - xXIDeviceHierarchyEvent ev; + int flags = 0; REQUEST(xXIChangeDeviceHierarchyReq); REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq); + if (!stuff->num_changes) + return rc; + any = (xXIAnyHierarchyChangeInfo*)&stuff[1]; while(stuff->num_changes--) { @@ -127,7 +173,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) EnableDevice(keybd); } xfree(name); - nchanges++; + flags |= HF_MasterAdded; } break; case CH_RemoveMasterDevice: @@ -233,7 +279,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) RemoveDevice(keybd); RemoveDevice(ptr); - nchanges++; + flags |= HF_MasterRemoved; } break; case CH_DetachSlave: @@ -253,7 +299,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) } AttachDevice(client, ptr, NULL); - nchanges++; + flags |= HF_SlaveDetached; } break; case CH_AttachSlave: @@ -293,7 +339,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) goto unwind; } AttachDevice(client, ptr, newmaster); - nchanges++; + flags |= HF_SlaveAttached; } break; } @@ -303,18 +349,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client) unwind: - if (nchanges > 0) /* even if an error occured, we need to send an event if - we changed anything in the hierarchy. */ - { - ev.type = GenericEvent; - ev.extension = IReqCode; - ev.length = 0; - ev.evtype = XI_HierarchyChanged; - ev.time = GetTimeInMillis(); - - SendEventToAllWindows(&dummyDev, XI_DeviceHierarchyChangedMask, - (xEvent*)&ev, 1); - } + XISendDeviceHierarchyEvent(flags); return rc; } diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h index 419053871..d2d100120 100644 --- a/Xi/chdevhier.h +++ b/Xi/chdevhier.h @@ -39,4 +39,6 @@ int SProcXIChangeDeviceHierarchy(ClientPtr /* client */); int ProcXIChangeDeviceHierarchy(ClientPtr /* client */); +void XISendDeviceHierarchyEvent(int flags); + #endif diff --git a/Xi/extinit.c b/Xi/extinit.c index f0aa9f672..8c9f9e111 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -739,6 +739,32 @@ static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to) } } +static void SDeviceHierarchyEvent(xXIDeviceHierarchyEvent *from, + xXIDeviceHierarchyEvent *to) +{ + int i; + char n; + xXIHierarchyInfo *info; + + *to = *from; + memcpy(&to[1], &from[1], from->length * 4); + swaps(&to->sequenceNumber, n); + swapl(&to->length, n); + swaps(&to->evtype, n); + swaps(&to->deviceid, n); + swapl(&to->time, n); + swapl(&to->flags, n); + swaps(&to->num_devices, n); + + info = (xXIHierarchyInfo*)&to[1]; + for (i = 0; i< from->num_devices; i++) + { + swaps(&info->deviceid, n); + swaps(&info->attachment, n); + info++; + } +} + /** Event swapping function for XI2 events. */ static void XI2EventSwap(xGenericEvent *from, xGenericEvent *to) @@ -753,6 +779,9 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to) SDeviceChangedEvent((xXIDeviceChangedEvent*)from, (xXIDeviceChangedEvent*)to); break; + case XI_HierarchyChanged: + SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from, + (xXIDeviceHierarchyEvent*)to); default: SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to); break;