From 6efd1a85e8cb75ca2eabd75a57ea488c1286ffb5 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Fri, 11 Jul 2025 14:08:56 +0200 Subject: [PATCH] Xi: ProcXIAllowEvents(): untwist request header handling The Xi protocol has some pretty unclean design aspect: instead of adding a new sub-request type, version 2.2 introduced a different request structure with some extra fields. So depending on which version the client has selected, we need to operate on separate structs. In the current implementation, there's a unclean hack by using the extended structure and only accessing the extra fields when using v2.2 or above. Even though this works, it's making the code unnecessarily complicated and blocking the use if canonical request parsing macros (which are coming with subsequent commits). Thus, it's time to clean it up and only use the exactly correct structs in the two different cases. The trick is just branching by version and pick out the the interesting values from the corresponding structs, so they can later be used in the (mostly) version independent part. Signed-off-by: Enrico Weigelt, metux IT consult --- Xi/xiallowev.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/Xi/xiallowev.c b/Xi/xiallowev.c index 1eb596935..d0ad9101b 100644 --- a/Xi/xiallowev.c +++ b/Xi/xiallowev.c @@ -68,32 +68,46 @@ SProcXIAllowEvents(ClientPtr client) int ProcXIAllowEvents(ClientPtr client) { - TimeStamp time; - DeviceIntPtr dev; - int ret = Success; - XIClientPtr xi_client; Bool have_xi22 = FALSE; + CARD32 clientTime; + int deviceId; + int mode; + Window grabWindow = 0; + uint32_t touchId = 0; - REQUEST(xXI2_2AllowEventsReq); - - xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); + XIClientPtr xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); + if (!xi_client) + return BadImplementation; if (version_compare(xi_client->major_version, xi_client->minor_version, 2, 2) >= 0) { + // Xi >= v2.2 request + REQUEST(xXI2_2AllowEventsReq); REQUEST_AT_LEAST_SIZE(xXI2_2AllowEventsReq); have_xi22 = TRUE; + clientTime = stuff->time; + deviceId = stuff->deviceid; + mode = stuff->mode; + grabWindow = stuff->grab_window; + touchId = stuff->touchid; } else { + // Xi < v2.2 request + REQUEST(xXIAllowEventsReq); REQUEST_AT_LEAST_SIZE(xXIAllowEventsReq); + clientTime = stuff->time; + deviceId = stuff->deviceid; + mode = stuff->mode; } - ret = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess); + DeviceIntPtr dev; + int ret = dixLookupDevice(&dev, deviceId, client, DixGetAttrAccess); if (ret != Success) return ret; - time = ClientTimeToServerTime(stuff->time); + TimeStamp time = ClientTimeToServerTime(clientTime); - switch (stuff->mode) { + switch (mode) { case XIReplayDevice: AllowSome(client, time, dev, GRAB_STATE_NOT_GRABBED); break; @@ -124,16 +138,16 @@ ProcXIAllowEvents(ClientPtr client) if (!have_xi22) return BadValue; - rc = dixLookupWindow(&win, stuff->grab_window, client, DixReadAccess); + rc = dixLookupWindow(&win, grabWindow, client, DixReadAccess); if (rc != Success) return rc; - ret = TouchAcceptReject(client, dev, stuff->mode, stuff->touchid, - stuff->grab_window, &client->errorValue); + ret = TouchAcceptReject(client, dev, mode, touchId, + grabWindow, &client->errorValue); } break; default: - client->errorValue = stuff->mode; + client->errorValue = mode; ret = BadValue; }