Xi: Add XI2 property requests.
This commit is contained in:
parent
9935bec6e8
commit
83f32d3972
32
Xi/extinit.c
32
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;
|
||||
|
|
332
Xi/xiproperty.c
332
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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user