summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-03-08 21:32:31 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-03-20 15:17:56 +1000
commit32f338263ff7de1a2e76d570c98f5be979c18d4e (patch)
tree9aeb5374d025da9ffee8178317bf3a222eb841a8
parent97e89a59572a4be6757510a317c142ec1d82e8f8 (diff)
Xi: Deliver XI2 HierarchyEvents when the hierarchy changes.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--Xi/chdevhier.c73
-rw-r--r--Xi/chdevhier.h2
-rw-r--r--Xi/extinit.c29
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;