diff --git a/Xi/extinit.c b/Xi/extinit.c index a8f8f1093..7e5111d78 100644 --- a/Xi/extinit.c +++ b/Xi/extinit.c @@ -254,7 +254,8 @@ static int (*ProcIVector[])(ClientPtr) = { ProcXIListProperties, /* 56 */ ProcXIChangeProperty, /* 57 */ ProcXIDeleteProperty, /* 58 */ - ProcXIGetProperty /* 59 */ + ProcXIGetProperty, /* 59 */ + ProcXIGetSelectedEvents /* 60 */ }; /* For swapped clients */ @@ -318,7 +319,8 @@ static int (*SProcIVector[])(ClientPtr) = { SProcXIListProperties, /* 56 */ SProcXIChangeProperty, /* 57 */ SProcXIDeleteProperty, /* 58 */ - SProcXIGetProperty /* 59 */ + SProcXIGetProperty, /* 59 */ + SProcXIGetSelectedEvents /* 60 */ }; /***************************************************************** @@ -516,6 +518,8 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep) SRepXIListProperties(client, len, (xXIListPropertiesReply *) rep); else if (rep->RepType == X_XIGetProperty) SRepXIGetProperty(client, len, (xXIGetPropertyReply *) rep); + else if (rep->RepType == X_XIGetSelectedEvents) + SRepXIGetSelectedEvents(client, len, (xXIGetSelectedEventsReply *) rep); else { FatalError("XINPUT confused sending swapped reply"); } diff --git a/Xi/xiselectev.c b/Xi/xiselectev.c index 561618244..31e6a77f5 100644 --- a/Xi/xiselectev.c +++ b/Xi/xiselectev.c @@ -128,3 +128,119 @@ ProcXISelectEvent(ClientPtr client) xfree(types); return Success; } + + +int +SProcXIGetSelectedEvents(ClientPtr client) +{ + char n; + + REQUEST(xXIGetSelectedEventsReq); + swaps(&stuff->length, n); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); + swapl(&stuff->window, n); + + return (ProcXIGetSelectedEvents(client)); +} + +int +ProcXIGetSelectedEvents(ClientPtr client) +{ + int rc, i; + WindowPtr win; + char n; + char *buffer = NULL; + xXIGetSelectedEventsReply reply; + OtherInputMasks *masks; + InputClientsPtr others = NULL; + xXIEventMask *evmask = NULL; + + REQUEST(xXIGetSelectedEventsReq); + REQUEST_SIZE_MATCH(xXIGetSelectedEventsReq); + + rc = dixLookupWindow(&win, stuff->window, client, DixReceiveAccess); + if (rc != Success) + return rc; + + reply.repType = X_Reply; + reply.RepType = X_XIGetSelectedEvents; + reply.length = 0; + reply.sequenceNumber = client->sequence; + reply.num_masks = 0; + + masks = wOtherInputMasks(win); + if (masks) + { + for (others = wOtherInputMasks(win)->inputClients; others; + others = others->next) { + if (SameClient(others, client)) { + break; + } + } + } + + if (!others) + { + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + return Success; + } + + buffer = xcalloc(MAXDEVICES, sizeof(xXIEventMask) + XI2MASKSIZE); + if (!buffer) + return BadAlloc; + + evmask = (xXIEventMask*)buffer; + for (i = 0; i < MAXDEVICES; i++) + { + int j; + unsigned char *devmask = others->xi2mask[i]; + + for (j = XI2MASKSIZE - 1; j >= 0; j--) + { + if (devmask[j] != 0) + { + evmask->deviceid = i; + evmask->mask_len = (j + 4)/4; /* j is an index, hence + 4, + not + 3 */ + + reply.num_masks++; + reply.length += sizeof(xXIEventMask)/4 + evmask->mask_len; + + if (client->swapped) + { + swaps(&evmask->deviceid, n); + swaps(&evmask->mask_len, n); + } + + memcpy(&evmask[1], devmask, j + 1); + evmask = (xXIEventMask*)((char*)evmask + + sizeof(xXIEventMask) + evmask->mask_len * 4); + break; + } + } + } + + WriteReplyToClient(client, sizeof(xXIGetSelectedEventsReply), &reply); + + if (reply.num_masks) + { + WriteSwappedDataToClient(client, reply.length * 4, buffer); + } + + + xfree(buffer); + return Success; +} + +void SRepXIGetSelectedEvents(ClientPtr client, + int len, xXIGetSelectedEventsReply *rep) +{ + char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + swaps(&rep->num_masks, n); + WriteToClient(client, len, (char *)rep); +} + + diff --git a/Xi/xiselectev.h b/Xi/xiselectev.h index dc527122b..5f5ffe305 100644 --- a/Xi/xiselectev.h +++ b/Xi/xiselectev.h @@ -29,3 +29,7 @@ int SProcXISelectEvent(ClientPtr client); int ProcXISelectEvent(ClientPtr client); +int SProcXIGetSelectedEvents(ClientPtr client); +int ProcXIGetSelectedEvents(ClientPtr client); +void SRepXIGetSelectedEvents(ClientPtr client, + int len, xXIGetSelectedEventsReply *rep);