From d74767107df25507602f8e0461d2c26de2965ec5 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Wed, 16 Jul 2025 13:21:06 +0200 Subject: [PATCH] panoramiX: PanoramiXGetImage(): write out payload in one block Collect payload pieces into x_rpcbuf, so it can be written out once. Signed-off-by: Enrico Weigelt, metux IT consult --- Xext/panoramiXprocs.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/Xext/panoramiXprocs.c b/Xext/panoramiXprocs.c index 3119a0be19..61b6b41260 100644 --- a/Xext/panoramiXprocs.c +++ b/Xext/panoramiXprocs.c @@ -32,6 +32,7 @@ Equipment Corporation. #include #include "dix/dix_priv.h" +#include "dix/rpcbuf_priv.h" #include "os/osdep.h" #include "Xext/panoramiX.h" #include "Xext/panoramiXsrv.h" @@ -1968,11 +1969,10 @@ PanoramiXGetImage(ClientPtr client) DrawablePtr pDraw; PanoramiXRes *draw; Bool isRoot; - char *pBuf; int i, x, y, w, h, format, rc; Mask plane = 0, planemask; int linesDone, nlines, linesPerBuf; - long widthBytesLine, length; + long widthBytesLine; REQUEST(xGetImageReq); @@ -2040,18 +2040,16 @@ PanoramiXGetImage(ClientPtr client) IncludeInferiors); } - + size_t length; if (format == ZPixmap) { widthBytesLine = PixmapBytePad(w, pDraw->depth); length = widthBytesLine * h; - } else { widthBytesLine = BitmapBytePad(w); plane = ((Mask) 1) << (pDraw->depth - 1); /* only planes asked for */ length = widthBytesLine * h * Ones(planemask & (plane | (plane - 1))); - } xGetImageReply rep = { @@ -2071,15 +2069,18 @@ PanoramiXGetImage(ClientPtr client) if (linesPerBuf > h) linesPerBuf = h; } - if (!(pBuf = calloc(linesPerBuf, widthBytesLine))) - return BadAlloc; if (client->swapped) { swaps(&rep.sequenceNumber); swapl(&rep.length); swapl(&rep.visual); } - WriteToClient(client, sizeof(rep), &rep); + + x_rpcbuf_t rpcbuf = { .swapped = client->swapped, .err_clear = TRUE }; + + /* can become quite big, so make enough room so we don't need to relloc */ + if (!x_rpcbuf_makeroom(&rpcbuf, length)) + return BadAlloc; if (linesPerBuf == 0) { /* nothing to do */ @@ -2089,14 +2090,13 @@ PanoramiXGetImage(ClientPtr client) while (h - linesDone > 0) { nlines = min(linesPerBuf, h - linesDone); - if (pDraw->depth == 1) - memset(pBuf, 0, nlines * widthBytesLine); - + char *pBuf = x_rpcbuf_reserve(&rpcbuf, nlines * widthBytesLine); + if (!pBuf) + return BadAlloc; XineramaGetImageData(drawables, x, y + linesDone, w, nlines, format, planemask, pBuf, widthBytesLine, isRoot); - WriteToClient(client, (int) (nlines * widthBytesLine), pBuf); linesDone += nlines; } } @@ -2107,20 +2107,21 @@ PanoramiXGetImage(ClientPtr client) while (h - linesDone > 0) { nlines = min(linesPerBuf, h - linesDone); - memset(pBuf, 0, nlines * widthBytesLine); - + char *pBuf = x_rpcbuf_reserve(&rpcbuf, nlines * widthBytesLine); + if (!pBuf) + return BadAlloc; XineramaGetImageData(drawables, x, y + linesDone, w, nlines, format, plane, pBuf, widthBytesLine, isRoot); - WriteToClient(client, (int)(nlines * widthBytesLine), pBuf); - linesDone += nlines; } } } } - free(pBuf); + + WriteToClient(client, sizeof(rep), &rep); + WriteRpcbufToClient(client, &rpcbuf); return Success; }