randr: ProcRRGetMonitors(): collect reply payload in temporary buffer
Instead of arbitrary count of individual WriteToClient() calls on small chunks, collect the whole payload in a buffer and write it out all at once. This also makes possible to use generic macros for reply sending, as well as further simplifications in the write-out path. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/1794>
This commit is contained in:
parent
203f59c6d3
commit
1bc6ca30a9
|
@ -604,11 +604,13 @@ ProcRRGetMonitors(ClientPtr client)
|
||||||
noutputs += monitors[m].numOutputs;
|
noutputs += monitors[m].numOutputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int payload_len = noutputs * sizeof(CARD32) + nmonitors * sizeof(xRRMonitorInfo);
|
||||||
|
|
||||||
xRRGetMonitorsReply rep = {
|
xRRGetMonitorsReply rep = {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
.sequenceNumber = client->sequence,
|
.sequenceNumber = client->sequence,
|
||||||
.timestamp = RRMonitorTimestamp(screen),
|
.timestamp = RRMonitorTimestamp(screen),
|
||||||
.length = noutputs + nmonitors * bytes_to_int32(sizeof(xRRMonitorInfo)),
|
.length = bytes_to_int32(payload_len),
|
||||||
.nmonitors = nmonitors,
|
.nmonitors = nmonitors,
|
||||||
.noutputs = noutputs,
|
.noutputs = noutputs,
|
||||||
};
|
};
|
||||||
|
@ -622,9 +624,18 @@ ProcRRGetMonitors(ClientPtr client)
|
||||||
}
|
}
|
||||||
WriteToClient(client, sizeof(xRRGetMonitorsReply), &rep);
|
WriteToClient(client, sizeof(xRRGetMonitorsReply), &rep);
|
||||||
|
|
||||||
|
char *payload_buf = calloc(1, payload_len);
|
||||||
|
if (!payload_buf) {
|
||||||
|
RRMonitorFreeList(monitors, nmonitors);
|
||||||
|
return BadAlloc;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *walk = payload_buf;
|
||||||
|
|
||||||
for (m = 0; m < nmonitors; m++) {
|
for (m = 0; m < nmonitors; m++) {
|
||||||
RRMonitorPtr monitor = &monitors[m];
|
RRMonitorPtr monitor = &monitors[m];
|
||||||
xRRMonitorInfo info = {
|
xRRMonitorInfo *info = (xRRMonitorInfo*) walk;
|
||||||
|
*info = (xRRMonitorInfo) {
|
||||||
.name = monitor->name,
|
.name = monitor->name,
|
||||||
.primary = monitor->primary,
|
.primary = monitor->primary,
|
||||||
.automatic = monitor->automatic,
|
.automatic = monitor->automatic,
|
||||||
|
@ -637,26 +648,27 @@ ProcRRGetMonitors(ClientPtr client)
|
||||||
.heightInMillimeters = monitor->geometry.mmHeight,
|
.heightInMillimeters = monitor->geometry.mmHeight,
|
||||||
};
|
};
|
||||||
if (client->swapped) {
|
if (client->swapped) {
|
||||||
swapl(&info.name);
|
swapl(&info->name);
|
||||||
swaps(&info.noutput);
|
swaps(&info->noutput);
|
||||||
swaps(&info.x);
|
swaps(&info->x);
|
||||||
swaps(&info.y);
|
swaps(&info->y);
|
||||||
swaps(&info.width);
|
swaps(&info->width);
|
||||||
swaps(&info.height);
|
swaps(&info->height);
|
||||||
swapl(&info.widthInMillimeters);
|
swapl(&info->widthInMillimeters);
|
||||||
swapl(&info.heightInMillimeters);
|
swapl(&info->heightInMillimeters);
|
||||||
}
|
}
|
||||||
|
|
||||||
RROutput outputs[monitor->numOutputs];
|
walk += sizeof(xRRMonitorInfo);
|
||||||
memcpy(outputs, monitor->outputs, monitor->numOutputs * sizeof (RROutput));
|
memcpy(walk, monitor->outputs, monitor->numOutputs * sizeof (RROutput));
|
||||||
|
|
||||||
if (client->swapped)
|
if (client->swapped)
|
||||||
SwapLongs(outputs, monitor->numOutputs);
|
SwapLongs((CARD32*)walk, monitor->numOutputs);
|
||||||
|
|
||||||
WriteToClient(client, sizeof(xRRMonitorInfo), &info);
|
walk += monitor->numOutputs * sizeof (RROutput);
|
||||||
WriteToClient(client, sizeof(outputs), outputs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WriteToClient(client, payload_len, payload_buf);
|
||||||
|
|
||||||
|
free(payload_buf);
|
||||||
RRMonitorFreeList(monitors, nmonitors);
|
RRMonitorFreeList(monitors, nmonitors);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
|
|
Loading…
Reference in New Issue