diff options
author | Peter Hutterer <peter.hutterer@who-t.net> | 2009-05-07 10:05:29 +1000 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2009-05-08 14:33:23 +1000 |
commit | 83f32d3972b8bfb0a87069dfb3fcd64b6b7c6424 (patch) | |
tree | 2d4181068f89117c608b047ec7a4c7346355ea97 | |
parent | 9935bec6e860cba9a3cc5baadd372ddb89d72ef0 (diff) |
Xi: Add XI2 property requests.
-rw-r--r-- | Xi/extinit.c | 32 | ||||
-rw-r--r-- | Xi/xiproperty.c | 332 | ||||
-rw-r--r-- | Xi/xiproperty.h | 15 | ||||
-rw-r--r-- | test/input.c | 4 |
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 } |