Xi: Deliver XI2 HierarchyEvents when the hierarchy changes.

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2009-03-08 21:32:31 +10:00
parent 97e89a5957
commit 32f338263f
3 changed files with 85 additions and 19 deletions

View File

@ -1,5 +1,6 @@
/* /*
* Copyright 2007-2008 Peter Hutterer * Copyright 2007-2008 Peter Hutterer
* Copyright 2009 Red Hat, Inc.
* *
* Permission is hereby granted, free of charge, to any person obtaining a * Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"), * copy of this software and associated documentation files (the "Software"),
@ -47,11 +48,55 @@
#include "exglobals.h" #include "exglobals.h"
#include "geext.h" #include "geext.h"
#include "xace.h" #include "xace.h"
#include "querydev.h" /* for GetDeviceUse */
#include "xkbsrv.h" #include "xkbsrv.h"
#include "chdevhier.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) ProcXIChangeDeviceHierarchy(ClientPtr client)
{ {
DeviceIntPtr ptr, keybd; DeviceIntPtr ptr, keybd;
DeviceIntRec dummyDev;
xXIAnyHierarchyChangeInfo *any; xXIAnyHierarchyChangeInfo *any;
int required_len = sizeof(xXIChangeDeviceHierarchyReq); int required_len = sizeof(xXIChangeDeviceHierarchyReq);
char n; char n;
int rc = Success; int rc = Success;
int nchanges = 0; int flags = 0;
xXIDeviceHierarchyEvent ev;
REQUEST(xXIChangeDeviceHierarchyReq); REQUEST(xXIChangeDeviceHierarchyReq);
REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq); REQUEST_AT_LEAST_SIZE(xXIChangeDeviceHierarchyReq);
if (!stuff->num_changes)
return rc;
any = (xXIAnyHierarchyChangeInfo*)&stuff[1]; any = (xXIAnyHierarchyChangeInfo*)&stuff[1];
while(stuff->num_changes--) while(stuff->num_changes--)
{ {
@ -127,7 +173,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
EnableDevice(keybd); EnableDevice(keybd);
} }
xfree(name); xfree(name);
nchanges++; flags |= HF_MasterAdded;
} }
break; break;
case CH_RemoveMasterDevice: case CH_RemoveMasterDevice:
@ -233,7 +279,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
RemoveDevice(keybd); RemoveDevice(keybd);
RemoveDevice(ptr); RemoveDevice(ptr);
nchanges++; flags |= HF_MasterRemoved;
} }
break; break;
case CH_DetachSlave: case CH_DetachSlave:
@ -253,7 +299,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
} }
AttachDevice(client, ptr, NULL); AttachDevice(client, ptr, NULL);
nchanges++; flags |= HF_SlaveDetached;
} }
break; break;
case CH_AttachSlave: case CH_AttachSlave:
@ -293,7 +339,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
goto unwind; goto unwind;
} }
AttachDevice(client, ptr, newmaster); AttachDevice(client, ptr, newmaster);
nchanges++; flags |= HF_SlaveAttached;
} }
break; break;
} }
@ -303,18 +349,7 @@ ProcXIChangeDeviceHierarchy(ClientPtr client)
unwind: unwind:
if (nchanges > 0) /* even if an error occured, we need to send an event if XISendDeviceHierarchyEvent(flags);
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);
}
return rc; return rc;
} }

View File

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

View File

@ -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. */ /** Event swapping function for XI2 events. */
static void static void
XI2EventSwap(xGenericEvent *from, xGenericEvent *to) XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
@ -753,6 +779,9 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
SDeviceChangedEvent((xXIDeviceChangedEvent*)from, SDeviceChangedEvent((xXIDeviceChangedEvent*)from,
(xXIDeviceChangedEvent*)to); (xXIDeviceChangedEvent*)to);
break; break;
case XI_HierarchyChanged:
SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from,
(xXIDeviceHierarchyEvent*)to);
default: default:
SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to); SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
break; break;