summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2009-05-07 10:05:29 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2009-05-08 14:33:23 +1000
commit83f32d3972b8bfb0a87069dfb3fcd64b6b7c6424 (patch)
tree2d4181068f89117c608b047ec7a4c7346355ea97
parent9935bec6e860cba9a3cc5baadd372ddb89d72ef0 (diff)
Xi: Add XI2 property requests.
-rw-r--r--Xi/extinit.c32
-rw-r--r--Xi/xiproperty.c332
-rw-r--r--Xi/xiproperty.h15
-rw-r--r--test/input.c4
4 files changed, 331 insertions, 52 deletions
diff --git a/Xi/extinit.c b/Xi/extinit.c
index eb2a90108..4b82f622f 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -250,7 +250,11 @@ static int (*ProcIVector[])(ClientPtr) = {
ProcXIUngrabDevice, /* 52 */
ProcXIAllowEvents, /* 53 */
ProcXIPassiveGrabDevice, /* 54 */
- ProcXIPassiveUngrabDevice /* 55 */
+ ProcXIPassiveUngrabDevice, /* 55 */
+ ProcXIListProperties, /* 56 */
+ ProcXIChangeProperty, /* 57 */
+ ProcXIDeleteProperty, /* 58 */
+ ProcXIGetProperty /* 59 */
};
/* For swapped clients */
@@ -310,7 +314,11 @@ static int (*SProcIVector[])(ClientPtr) = {
SProcXIUngrabDevice, /* 52 */
SProcXIAllowEvents, /* 53 */
SProcXIPassiveGrabDevice, /* 54 */
- SProcXIPassiveUngrabDevice /* 55 */
+ SProcXIPassiveUngrabDevice, /* 55 */
+ SProcXIListProperties, /* 56 */
+ SProcXIChangeProperty, /* 57 */
+ SProcXIDeleteProperty, /* 58 */
+ SProcXIGetProperty /* 59 */
};
/*****************************************************************
@@ -505,6 +513,10 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
SRepXIGrabDevice(client, len, (xXIGrabDeviceReply *) rep);
else if (rep->RepType == X_XIGrabDevice)
SRepXIPassiveGrabDevice(client, len, (xXIPassiveGrabDeviceReply *) rep);
+ else if (rep->RepType == X_XIListProperties)
+ SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep);
+ else if (rep->RepType == X_XIGetProperty)
+ SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep);
else {
FatalError("XINPUT confused sending swapped reply");
}
@@ -777,6 +789,18 @@ static void SDeviceHierarchyEvent(xXIDeviceHierarchyEvent *from,
}
}
+static void SXIPropertyEvent(xXIPropertyEvent *from, xXIPropertyEvent *to)
+{
+ char n;
+
+ *to = *from;
+ swaps(&to->sequenceNumber, n);
+ swapl(&to->length, n);
+ swaps(&to->evtype, n);
+ swaps(&to->deviceid, n);
+ swapl(&to->property, n);
+}
+
/** Event swapping function for XI2 events. */
static void
XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
@@ -795,6 +819,10 @@ XI2EventSwap(xGenericEvent *from, xGenericEvent *to)
SDeviceHierarchyEvent((xXIDeviceHierarchyEvent*)from,
(xXIDeviceHierarchyEvent*)to);
break;
+ case XI_PropertyEvent:
+ SXIPropertyEvent((xXIPropertyEvent*)from,
+ (xXIPropertyEvent*)to);
+ break;
default:
SDeviceEvent((xXIDeviceEvent*)from, (xXIDeviceEvent*)to);
break;
diff --git a/Xi/xiproperty.c b/Xi/xiproperty.c
index 772571504..3cda82b6e 100644
--- a/Xi/xiproperty.c
+++ b/Xi/xiproperty.c
@@ -34,6 +34,7 @@
#include <X11/extensions/XI.h>
#include <X11/Xatom.h>
#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
#include "exglobals.h"
#include "exevents.h"
#include "swaprep.h"
@@ -169,6 +170,36 @@ static struct dev_properties
static long XIPropHandlerID = 1;
+static void send_property_event(DeviceIntPtr dev, Atom property, int what)
+{
+ devicePropertyNotify event;
+ xXIPropertyEvent xi2;
+ int state;
+
+ if (what == XIPropertyDeleted)
+ state = PropertyDelete;
+ else
+ state = PropertyNewValue;
+
+ event.type = DevicePropertyNotify;
+ event.deviceid = dev->id;
+ event.state = state;
+ event.atom = property;
+ event.time = currentTime.milliseconds;
+ SendEventToAllWindows(dev, DevicePropertyNotifyMask,
+ (xEvent*)&event, 1);
+
+ xi2.type = GenericEvent;
+ xi2.extension = IReqCode;
+ xi2.length = 0;
+ xi2.evtype = XI_PropertyEvent;
+ xi2.deviceid = dev->id;
+ xi2.time = currentTime.milliseconds;
+ xi2.property = property;
+ xi2.what = what;
+ SendEventToAllWindows(dev, GetEventFilter(dev, &xi2), (xEvent*)&xi2, 1);
+}
+
static int list_atoms(DeviceIntPtr dev, int *natoms, Atom **atoms_return)
{
XIPropertyPtr prop;
@@ -581,20 +612,11 @@ XIDeleteAllDeviceProperties (DeviceIntPtr device)
{
XIPropertyPtr prop, next;
XIPropertyHandlerPtr curr_handler, next_handler;
- devicePropertyNotify event;
for (prop = device->properties.properties; prop; prop = next)
{
next = prop->next;
-
- event.type = DevicePropertyNotify;
- event.deviceid = device->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(device, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
-
+ send_property_event(device, prop->propertyName, XIPropertyDeleted);
XIDestroyDeviceProperty(prop);
}
@@ -613,7 +635,6 @@ int
XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient)
{
XIPropertyPtr prop, *prev;
- devicePropertyNotify event;
int rc = Success;
for (prev = &device->properties.properties; (prop = *prev); prev = &(prop->next))
@@ -640,13 +661,7 @@ XIDeleteDeviceProperty (DeviceIntPtr device, Atom property, Bool fromClient)
if (prop)
{
*prev = prop->next;
- event.type = DevicePropertyNotify;
- event.deviceid = device->id;
- event.state = PropertyDelete;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(device, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
+ send_property_event(device, prop->propertyName, XIPropertyDeleted);
XIDestroyDeviceProperty (prop);
}
@@ -659,7 +674,6 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
pointer value, Bool sendevent)
{
XIPropertyPtr prop;
- devicePropertyNotify event;
int size_in_bytes;
int total_size;
unsigned long total_len;
@@ -778,15 +792,9 @@ XIChangeDeviceProperty (DeviceIntPtr dev, Atom property, Atom type,
}
if (sendevent)
- {
- event.type = DevicePropertyNotify;
- event.deviceid = dev->id;
- event.state = PropertyNewValue;
- event.atom = prop->propertyName;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(dev, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
- }
+ send_property_event(dev, prop->propertyName,
+ (add) ? XIPropertyCreated : XIPropertyModified);
+
return(Success);
}
@@ -965,28 +973,7 @@ ProcXGetDeviceProperty (ClientPtr client)
reply.length = (length + 3) >> 2;
if (stuff->delete && (reply.bytesAfter == 0))
- {
- devicePropertyNotify event;
- xXIPropertyEvent xi2;
-
- event.type = DevicePropertyNotify;
- event.deviceid = dev->id;
- event.state = PropertyDelete;
- event.atom = stuff->property;
- event.time = currentTime.milliseconds;
- SendEventToAllWindows(dev, DevicePropertyNotifyMask,
- (xEvent*)&event, 1);
-
- xi2.type = GenericEvent;
- xi2.extension = IReqCode;
- xi2.length = 0;
- xi2.evtype = XI_PropertyEvent;
- xi2.deviceid = dev->id;
- xi2.time = currentTime.milliseconds;
- xi2.property = stuff->property;
- xi2.what = XIPropertyDeleted;
- SendEventToAllWindows(dev, XI_PropertyEventMask, (xEvent*)&xi2, 1);
- }
+ send_property_event(dev, stuff->property, XIPropertyDeleted);
WriteReplyToClient(client, sizeof(xGenericReply), &reply);
@@ -1100,3 +1087,248 @@ SRepXGetDeviceProperty(ClientPtr client, int size,
/* data will be swapped, see ProcXGetDeviceProperty */
WriteToClient(client, size, (char*)rep);
}
+
+/* XI2 Request/reply handling */
+int
+ProcXIListProperties(ClientPtr client)
+{
+ Atom *atoms;
+ xXIListPropertiesReply rep;
+ int natoms;
+ DeviceIntPtr dev;
+ int rc = Success;
+
+ REQUEST(xXIListPropertiesReq);
+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = list_atoms(dev, &natoms, &atoms);
+ if (rc != Success)
+ return rc;
+
+ rep.repType = X_Reply;
+ rep.RepType = X_XIListProperties;
+ rep.length = natoms;
+ rep.sequenceNumber = client->sequence;
+ rep.num_properties = natoms;
+
+ WriteReplyToClient(client, sizeof(xXIListPropertiesReply), &rep);
+ if (natoms)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr)Swap32Write;
+ WriteSwappedDataToClient(client, natoms * sizeof(Atom), atoms);
+ xfree(atoms);
+ }
+ return rc;
+}
+
+int
+ProcXIChangeProperty(ClientPtr client)
+{
+ int rc;
+ DeviceIntPtr dev;
+ int totalSize;
+ unsigned long len;
+
+ REQUEST(xXIChangePropertyReq);
+ REQUEST_AT_LEAST_SIZE(xXIChangePropertyReq);
+ UpdateCurrentTime();
+
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = check_change_property(client, stuff->property, stuff->type,
+ stuff->format, stuff->mode, stuff->num_items);
+ len = stuff->num_items;
+ if (len > ((0xffffffff - sizeof(xXIChangePropertyReq)) >> 2))
+ return BadLength;
+
+ totalSize = len * (stuff->format/8);
+ REQUEST_FIXED_SIZE(xXIChangePropertyReq, totalSize);
+
+ rc = change_property(client, dev, stuff->property, stuff->type,
+ stuff->format, stuff->mode, len, (void*)&stuff[1]);
+ return rc;
+}
+
+int
+ProcXIDeleteProperty(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int rc;
+ REQUEST(xXIDeletePropertyReq);
+
+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
+ UpdateCurrentTime();
+ rc = dixLookupDevice (&dev, stuff->deviceid, client, DixWriteAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!ValidAtom(stuff->property))
+ {
+ client->errorValue = stuff->property;
+ return (BadAtom);
+ }
+
+ rc = XIDeleteDeviceProperty(dev, stuff->property, TRUE);
+ return rc;
+}
+
+
+int
+ProcXIGetProperty(ClientPtr client)
+{
+ REQUEST(xXIGetPropertyReq);
+ DeviceIntPtr dev;
+ xXIGetPropertyReply reply;
+ int length;
+ int rc, format, nitems, bytes_after;
+ char *data;
+ Atom type;
+
+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+ if (stuff->delete)
+ UpdateCurrentTime();
+ rc = dixLookupDevice (&dev, stuff->deviceid, client,
+ stuff->delete ? DixWriteAccess :
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = get_property(client, dev, stuff->property, stuff->type,
+ stuff->delete, stuff->offset, stuff->len,
+ &bytes_after, &type, &format, &nitems, &length, &data);
+
+ if (rc != Success)
+ return rc;
+
+ reply.repType = X_Reply;
+ reply.RepType = X_XIGetProperty;
+ reply.sequenceNumber = client->sequence;
+ reply.num_items = nitems;
+ reply.format = format;
+ reply.bytes_after = bytes_after;
+ reply.type = type;
+ reply.length = (length + 3)/4;
+
+ if (length && stuff->delete && (reply.bytes_after == 0))
+ send_property_event(dev, stuff->property, XIPropertyDeleted);
+
+ WriteReplyToClient(client, sizeof(xXIGetPropertyReply), &reply);
+
+ if (length)
+ {
+ switch (reply.format) {
+ case 32: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap32Write; break;
+ case 16: client->pSwapReplyFunc = (ReplySwapPtr)CopySwap16Write; break;
+ default: client->pSwapReplyFunc = (ReplySwapPtr)WriteToClient; break;
+ }
+ WriteSwappedDataToClient(client, length, data);
+ }
+
+ /* delete the Property */
+ if (stuff->delete && (reply.bytes_after == 0))
+ {
+ XIPropertyPtr prop, *prev;
+ for (prev = &dev->properties.properties; (prop = *prev); prev = &prop->next)
+ {
+ if (prop->propertyName == stuff->property)
+ {
+ *prev = prop->next;
+ XIDestroyDeviceProperty(prop);
+ break;
+ }
+ }
+ }
+
+ return Success;
+}
+
+int
+SProcXIListProperties(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIListPropertiesReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+
+ REQUEST_SIZE_MATCH(xXIListPropertiesReq);
+ return (ProcXIListProperties(client));
+}
+
+int
+SProcXIChangeProperty(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIChangePropertyReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->num_items, n);
+ REQUEST_SIZE_MATCH(xXIChangePropertyReq);
+ return (ProcXIChangeProperty(client));
+}
+
+int
+SProcXIDeleteProperty(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIDeletePropertyReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->property, n);
+ REQUEST_SIZE_MATCH(xXIDeletePropertyReq);
+ return (ProcXIDeleteProperty(client));
+}
+
+int
+SProcXIGetProperty(ClientPtr client)
+{
+ char n;
+ REQUEST(xXIGetPropertyReq);
+
+ swaps(&stuff->length, n);
+ swaps(&stuff->deviceid, n);
+ swapl(&stuff->property, n);
+ swapl(&stuff->type, n);
+ swapl(&stuff->offset, n);
+ swapl(&stuff->len, n);
+ REQUEST_SIZE_MATCH(xXIGetPropertyReq);
+ return (ProcXIGetProperty(client));
+}
+
+
+void
+SRepXIListProperties(ClientPtr client, int size,
+ xXIListPropertiesReply *rep)
+{
+ char n;
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swaps(&rep->num_properties, n);
+ /* properties will be swapped later, see ProcXIListProperties */
+ WriteToClient(client, size, (char*)rep);
+}
+
+void
+SRepXIGetProperty(ClientPtr client, int size,
+ xXIGetPropertyReply *rep)
+{
+ char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ swapl(&rep->type, n);
+ swapl(&rep->bytes_after, n);
+ swapl(&rep->num_items, n);
+ /* data will be swapped, see ProcXIGetProperty */
+ WriteToClient(client, size, (char*)rep);
+}
diff --git a/Xi/xiproperty.h b/Xi/xiproperty.h
index e66b447ea..bc4bbaed9 100644
--- a/Xi/xiproperty.h
+++ b/Xi/xiproperty.h
@@ -43,4 +43,19 @@ void SRepXListDeviceProperties(ClientPtr client, int size,
void SRepXGetDeviceProperty(ClientPtr client, int size,
xGetDevicePropertyReply *rep);
+/* XI2 request/reply handling */
+int ProcXIListProperties (ClientPtr client);
+int ProcXIChangeProperty (ClientPtr client);
+int ProcXIDeleteProperty (ClientPtr client);
+int ProcXIGetProperty (ClientPtr client);
+
+int SProcXIListProperties (ClientPtr client);
+int SProcXIChangeProperty (ClientPtr client);
+int SProcXIDeleteProperty (ClientPtr client);
+int SProcXIGetProperty (ClientPtr client);
+
+void SRepXIListProperties(ClientPtr client, int size,
+ xXIListPropertiesReply *rep);
+void SRepXIGetProperty(ClientPtr client, int size,
+ xXIGetPropertyReply *rep);
#endif /* XIPROPERTY_H */
diff --git a/test/input.c b/test/input.c
index e49cc8127..238cad339 100644
--- a/test/input.c
+++ b/test/input.c
@@ -299,6 +299,10 @@ static void xi2_struct_sizes(void)
compare(xXIAllowEventsReq);
compare(xXIPassiveGrabDeviceReq);
compare(xXIPassiveUngrabDeviceReq);
+ compare(xXIListPropertiesReq);
+ compare(xXIChangePropertyReq);
+ compare(xXIDeletePropertyReq);
+ compare(xXIGetPropertyReq);
#undef compare
}