From d90335b8f17757e12b2f1366063ce1c3a08e9a41 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Thu, 25 Jul 2024 16:28:48 +0200 Subject: [PATCH] xkb: split XkbSendCompatMap() This function is a funny beast: it assembles and writes out an xkbGetCompatMapReply, called in two different cases, ProcXkbGetCompatMap() as well as ProcXkbGetKbdByName(). In the latter case the whole reply is contained in another one. That's the reason why it's payload size is computed separately - the caller must know that in order to set up the container's reply size correctly. As preparation for upcoming simplifications of the reply send path, splitting off this function into pieces: XkbAssembleCompatMap() just assembles the reply payload, while it's callers now responsible for preparing the request header and writing out both pieces. Signed-off-by: Enrico Weigelt, metux IT consult --- xkb/xkb.c | 72 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 25 deletions(-) diff --git a/xkb/xkb.c b/xkb/xkb.c index df1dfbb0b..b5a32d09c 100644 --- a/xkb/xkb.c +++ b/xkb/xkb.c @@ -2798,16 +2798,13 @@ XkbComputeGetCompatMapReplySize(XkbCompatMapPtr compat, return Success; } -static int -XkbSendCompatMap(ClientPtr client, - XkbCompatMapPtr compat, xkbGetCompatMapReply rep) +static void +XkbAssembleCompatMap(ClientPtr client, + XkbCompatMapPtr compat, + xkbGetCompatMapReply rep, + char *buf) { - int sz = rep.length * sizeof(CARD32); - char *buf = calloc(1, sz); - if (sz && (!buf)) - return BadAlloc; - - if (sz) { + if (rep.length) { register unsigned i, bit; xkbModsWireDesc *grp; XkbSymInterpretPtr sym = &compat->sym_interpret[rep.firstSI]; @@ -2841,19 +2838,6 @@ XkbSendCompatMap(ClientPtr client, wire = (xkbSymInterpretWireDesc *) grp; } } - - if (client->swapped) { - swaps(&rep.sequenceNumber); - swapl(&rep.length); - swaps(&rep.firstSI); - swaps(&rep.nSI); - swaps(&rep.nTotalSI); - } - - WriteToClient(client, sizeof(xkbGetCompatMapReply), &rep); - WriteToClient(client, sz, buf); - free(buf); - return Success; } int @@ -2893,7 +2877,26 @@ ProcXkbGetCompatMap(ClientPtr client) return BadValue; } XkbComputeGetCompatMapReplySize(compat, &rep); - return XkbSendCompatMap(client, compat, rep); + + int sz = rep.length * sizeof(CARD32); + char *buf = calloc(1, sz); + if (rep.length && (!buf)) // rep.length = 0 is valid here + return BadAlloc; + + XkbAssembleCompatMap(client, compat, rep, buf); + + if (client->swapped) { + swaps(&rep.sequenceNumber); + swapl(&rep.length); + swaps(&rep.firstSI); + swaps(&rep.nSI); + swaps(&rep.nTotalSI); + } + + WriteToClient(client, sizeof(xkbGetCompatMapReply), &rep); + WriteToClient(client, sz, buf); + free(buf); + return Success; } /** @@ -6065,8 +6068,27 @@ ProcXkbGetKbdByName(ClientPtr client) free(buf); } - if (reported & XkbGBN_CompatMapMask) - XkbSendCompatMap(client, new->compat, crep); + if (reported & XkbGBN_CompatMapMask) { + int sz = crep.length * sizeof(CARD32); + char *buf = calloc(1, sz); + if (!buf) + return BadAlloc; + + XkbAssembleCompatMap(client, new->compat, crep, buf); + + if (client->swapped) { + swaps(&crep.sequenceNumber); + swapl(&crep.length); + swaps(&crep.firstSI); + swaps(&crep.nSI); + swaps(&crep.nTotalSI); + } + + WriteToClient(client, sizeof(crep), &crep); + WriteToClient(client, sz, buf); + free(buf); + } + if (reported & XkbGBN_IndicatorMapMask) XkbSendIndicatorMap(client, new->indicators, irep); if (reported & (XkbGBN_KeyNamesMask | XkbGBN_OtherNamesMask))