randr: ProcRRGetOutputInfo (): simplify by using x_rpcbuf_t

* use x_rpcbuf_t for reply payload assembly and byte-swap
* do byte-swap of header fields explicitly instead of cryptic functions
* drop extra length computation

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult
2025-07-19 03:26:27 +02:00
committed by Enrico Weigelt
parent 946eb68ff3
commit d19cfbfa70

View File

@@ -441,20 +441,13 @@ RROutputInitErrorValue(void)
SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput); SetResourceTypeErrorValue(RROutputType, RRErrorBase + BadRROutput);
} }
#define OutputInfoExtra (SIZEOF(xRRGetOutputInfoReply) - 32)
int int
ProcRRGetOutputInfo(ClientPtr client) ProcRRGetOutputInfo(ClientPtr client)
{ {
REQUEST(xRRGetOutputInfoReq); REQUEST(xRRGetOutputInfoReq);
xRRGetOutputInfoReply rep;
RROutputPtr output; RROutputPtr output;
unsigned long extraLen;
ScreenPtr pScreen; ScreenPtr pScreen;
rrScrPrivPtr pScrPriv; rrScrPrivPtr pScrPriv;
RRCrtc *crtcs;
RRMode *modes;
RROutput *clones;
int i; int i;
Bool leased; Bool leased;
@@ -466,86 +459,49 @@ ProcRRGetOutputInfo(ClientPtr client)
pScreen = output->pScreen; pScreen = output->pScreen;
pScrPriv = rrGetScrPriv(pScreen); pScrPriv = rrGetScrPriv(pScreen);
CARD8 *extra = NULL; xRRGetOutputInfoReply rep = {
.type = X_Reply,
.status = RRSetConfigSuccess,
.sequenceNumber = client->sequence,
.length = bytes_to_int32(sizeof(xRRGetOutputInfoReply)-sizeof(xReply)),
.timestamp = pScrPriv->lastSetTime.milliseconds,
.nameLength = output->nameLength,
};
x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE };
if (leased) { if (leased) {
rep = (xRRGetOutputInfoReply) { rep.connection = RR_Disconnected;
.type = X_Reply, rep.subpixelOrder = SubPixelUnknown;
.status = RRSetConfigSuccess,
.sequenceNumber = client->sequence,
.length = bytes_to_int32(OutputInfoExtra),
.timestamp = pScrPriv->lastSetTime.milliseconds,
.connection = RR_Disconnected,
.subpixelOrder = SubPixelUnknown,
.nameLength = output->nameLength
};
extraLen = bytes_to_int32(rep.nameLength) << 2;
if (!extraLen)
goto sendout;
rep.length += bytes_to_int32(extraLen);
extra = calloc(1, extraLen);
if (!extra)
return BadAlloc;
memcpy(extra, output->name, output->nameLength);
} else { } else {
rep = (xRRGetOutputInfoReply) { rep.crtc = output->crtc ? output->crtc->id : None;
.type = X_Reply, rep.mmWidth = output->mmWidth;
.status = RRSetConfigSuccess, rep.mmHeight = output->mmHeight;
.sequenceNumber = client->sequence, rep.connection = output->nonDesktop ? RR_Disconnected : output->connection;
.length = bytes_to_int32(OutputInfoExtra), rep.subpixelOrder = output->subpixelOrder;
.timestamp = pScrPriv->lastSetTime.milliseconds, rep.nCrtcs = output->numCrtcs;
.crtc = output->crtc ? output->crtc->id : None, rep.nModes = output->numModes + output->numUserModes;
.mmWidth = output->mmWidth, rep.nPreferred = output->numPreferred;
.mmHeight = output->mmHeight, rep.nClones = output->numClones;
.connection = output->nonDesktop ? RR_Disconnected : output->connection,
.subpixelOrder = output->subpixelOrder,
.nCrtcs = output->numCrtcs,
.nModes = output->numModes + output->numUserModes,
.nPreferred = output->numPreferred,
.nClones = output->numClones,
.nameLength = output->nameLength
};
extraLen = ((output->numCrtcs +
output->numModes + output->numUserModes +
output->numClones + bytes_to_int32(rep.nameLength)) << 2);
if (!extraLen) for (i = 0; i < output->numCrtcs; i++)
goto sendout; x_rpcbuf_write_CARD32(&rpcbuf, output->crtcs[i]->id);
rep.length += bytes_to_int32(extraLen);
extra = calloc(1, extraLen);
if (!extra)
return BadAlloc;
crtcs = (RRCrtc *) extra;
modes = (RRMode *) (crtcs + output->numCrtcs);
clones = (RROutput *) (modes + output->numModes + output->numUserModes);
memcpy((clones + output->numClones), output->name, output->nameLength);
for (i = 0; i < output->numCrtcs; i++) {
crtcs[i] = output->crtcs[i]->id;
if (client->swapped)
swapl(&crtcs[i]);
}
for (i = 0; i < output->numModes + output->numUserModes; i++) { for (i = 0; i < output->numModes + output->numUserModes; i++) {
if (i < output->numModes) if (i < output->numModes)
modes[i] = output->modes[i]->mode.id; x_rpcbuf_write_CARD32(&rpcbuf, output->modes[i]->mode.id);
else else
modes[i] = output->userModes[i - output->numModes]->mode.id; x_rpcbuf_write_CARD32(&rpcbuf, output->userModes[i - output->numModes]->mode.id);
if (client->swapped)
swapl(&modes[i]);
}
for (i = 0; i < output->numClones; i++) {
clones[i] = output->clones[i]->id;
if (client->swapped)
swapl(&clones[i]);
} }
for (i = 0; i < output->numClones; i++)
x_rpcbuf_write_CARD32(&rpcbuf, output->clones[i]->id);
} }
sendout: x_rpcbuf_write_string_pad(&rpcbuf, output->name); /* indeed 0-terminated */
rep.length += x_rpcbuf_wsize_units(&rpcbuf);
if (client->swapped) { if (client->swapped) {
swaps(&rep.sequenceNumber); swaps(&rep.sequenceNumber);
swapl(&rep.length); swapl(&rep.length);
@@ -561,9 +517,7 @@ sendout:
} }
WriteToClient(client, sizeof(xRRGetOutputInfoReply), &rep); WriteToClient(client, sizeof(xRRGetOutputInfoReply), &rep);
WriteToClient(client, extraLen, extra); WriteRpcbufToClient(client, &rpcbuf);
free(extra);
return Success; return Success;
} }