mirror of
https://github.com/X11Libre/xserver.git
synced 2026-11-14 05:14:45 +00:00
Let PanoramiXCreateConnectionBlock() only return x_rpcbuf_t, not touching global structures anymore - it's caller will that now. Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
234 lines
7.2 KiB
C
234 lines
7.2 KiB
C
/* SPDX-License-Identifier: X11 OR MIT OR AGPL-3.0-or-later
|
|
*
|
|
* Copyright © 2026 Enrico Weigelt, metux IT consult <info@metux.net>
|
|
*/
|
|
#include <dix-config.h>
|
|
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <version-config.h>
|
|
|
|
#include <X11/Xproto.h>
|
|
|
|
#include "include/misc.h"
|
|
#include "include/windowstr.h"
|
|
#include "dix/client_priv.h"
|
|
#include "dix/dix_priv.h"
|
|
#include "dix/rpcbuf_priv.h"
|
|
#include "dix/screenint_priv.h"
|
|
#include "dix/server_priv.h"
|
|
#include "dix/window_priv.h"
|
|
#include "Xext/panoramiX/panoramiXsrv.h"
|
|
#include "Xext/panoramiX/panoramiX_priv.h"
|
|
|
|
size_t ConnectionInfoSize = 0;
|
|
|
|
void dixSendConnAbort(ClientPtr pClient, const char *reason)
|
|
{
|
|
xConnSetupPrefix csp = {
|
|
.success = xFalse,
|
|
.lengthReason = strlen(reason),
|
|
.length = bytes_to_int32(csp.lengthReason),
|
|
.majorVersion = X_PROTOCOL,
|
|
.minorVersion = X_PROTOCOL_REVISION,
|
|
};
|
|
|
|
if (pClient->swapped) {
|
|
swaps(&csp.majorVersion);
|
|
swaps(&csp.minorVersion);
|
|
swaps(&csp.length);
|
|
}
|
|
|
|
dixWriteToClient(pClient, sizeof(csp), &csp);
|
|
dixWriteToClient(pClient, (int) csp.lengthReason, reason);
|
|
pClient->noClientException = -1;
|
|
}
|
|
|
|
size_t dixConnBlockScreenStart(const char *connInfo)
|
|
{
|
|
const xConnSetup *setup = (const xConnSetup *)connInfo;
|
|
return (
|
|
sizeof(xConnSetup) +
|
|
pad_to_int32(setup->nbytesVendor) +
|
|
setup->numFormats * sizeof(xPixmapFormat));
|
|
}
|
|
|
|
void dixInitConnectionBlock(void)
|
|
{
|
|
free(ConnectionInfo);
|
|
ConnectionInfo = NULL;
|
|
ConnectionInfoSize = 0;
|
|
|
|
x_rpcbuf_t rpcbuf = { 0 };
|
|
|
|
#ifdef XINERAMA
|
|
if (PanoramiXIsEnabled()) {
|
|
screenInfo.numRoots = 1;
|
|
rpcbuf = PanoramiXCreateConnectionBlock();
|
|
} else
|
|
#endif /* XINERAMA */
|
|
{
|
|
screenInfo.numRoots = screenInfo.numScreens;
|
|
rpcbuf = dixBuildConnectionBlock(screenInfo.numScreens);
|
|
}
|
|
|
|
if (rpcbuf.error)
|
|
FatalError("could not create connection block info");
|
|
|
|
/* must not free the rpcbuf here, because we store the data elsewhere */
|
|
ConnectionInfo = rpcbuf.buffer;
|
|
ConnectionInfoSize = rpcbuf.wpos;
|
|
}
|
|
|
|
void x_rpcbuf_write_xWindowRoot(x_rpcbuf_t *rpcbuf, ScreenPtr pScreen)
|
|
{
|
|
xWindowRoot root = {
|
|
.windowId = pScreen->root->drawable.id,
|
|
.defaultColormap = pScreen->defColormap,
|
|
.whitePixel = pScreen->whitePixel,
|
|
.blackPixel = pScreen->blackPixel,
|
|
.currentInputMask = 0, /* filled in when sent */
|
|
.pixWidth = pScreen->width,
|
|
.pixHeight = pScreen->height,
|
|
.mmWidth = pScreen->mmWidth,
|
|
.mmHeight = pScreen->mmHeight,
|
|
.minInstalledMaps = pScreen->minInstalledCmaps,
|
|
.maxInstalledMaps = pScreen->maxInstalledCmaps,
|
|
.rootVisualID = pScreen->rootVisual,
|
|
.backingStore = pScreen->backingStoreSupport,
|
|
.saveUnders = FALSE,
|
|
.rootDepth = pScreen->rootDepth,
|
|
.nDepths = pScreen->numDepths,
|
|
};
|
|
x_rpcbuf_write_CARD8s(rpcbuf, (CARD8*)&root, sizeof(root));
|
|
};
|
|
|
|
void x_rpcbuf_write_xDepth(x_rpcbuf_t *rpcbuf, DepthPtr pDepth)
|
|
{
|
|
/* write the xDepth header */
|
|
xDepth depth = {
|
|
.depth = pDepth->depth,
|
|
.nVisuals = pDepth->numVids,
|
|
};
|
|
x_rpcbuf_write_CARD8s(rpcbuf, (CARD8*)&depth, sizeof(depth));
|
|
}
|
|
|
|
void x_rpcbuf_write_xVisualInfo(x_rpcbuf_t *rpcbuf, VisualPtr pVisual)
|
|
{
|
|
xVisualType visual = {
|
|
.visualID = pVisual->vid,
|
|
.class = pVisual->class,
|
|
.bitsPerRGB = pVisual->bitsPerRGBValue,
|
|
.colormapEntries = pVisual->ColormapEntries,
|
|
.redMask = pVisual->redMask,
|
|
.greenMask = pVisual->greenMask,
|
|
.blueMask = pVisual->blueMask,
|
|
};
|
|
x_rpcbuf_write_CARD8s(rpcbuf, (CARD8*)&visual, sizeof(visual));
|
|
}
|
|
|
|
void x_rpcbuf_write_xPixmapFormat(x_rpcbuf_t *rpcbuf, PixmapFormatPtr pPixmapFormat)
|
|
{
|
|
xPixmapFormat format = {
|
|
.depth = pPixmapFormat->depth,
|
|
.bitsPerPixel = pPixmapFormat->bitsPerPixel,
|
|
.scanLinePad = pPixmapFormat->scanlinePad,
|
|
};
|
|
x_rpcbuf_write_CARD8s(rpcbuf, (CARD8*)&format, sizeof(format));
|
|
}
|
|
|
|
x_rpcbuf_t dixBuildConnectionBlock(int maxscreens)
|
|
{
|
|
const char VendorString[] = "XLibre";
|
|
|
|
if (!maxscreens) {
|
|
maxscreens = screenInfo.numScreens;
|
|
}
|
|
|
|
x_rpcbuf_t rpcbuf = { 0 };
|
|
|
|
xConnSetup setup = {
|
|
/* Leave off the ridBase and ridMask, these must be sent with
|
|
connection */
|
|
.release = VENDOR_RELEASE,
|
|
/*
|
|
* per-server image and bitmap parameters are defined in Xmd.h
|
|
*/
|
|
.imageByteOrder = screenInfo.imageByteOrder,
|
|
|
|
.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit,
|
|
.bitmapScanlinePad = screenInfo.bitmapScanlinePad,
|
|
|
|
.bitmapBitOrder = screenInfo.bitmapBitOrder,
|
|
.motionBufferSize = NumMotionEvents(),
|
|
.numRoots = maxscreens,
|
|
.nbytesVendor = strlen(VendorString),
|
|
.numFormats = screenInfo.numPixmapFormats,
|
|
.maxRequestSize = MAX_REQUEST_SIZE,
|
|
};
|
|
QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
|
|
x_rpcbuf_write_CARD8s(&rpcbuf, (CARD8*)&setup, sizeof(setup));
|
|
|
|
x_rpcbuf_write_string_pad(&rpcbuf, VendorString);
|
|
|
|
for (int i = 0; i < screenInfo.numPixmapFormats; i++) {
|
|
x_rpcbuf_write_xPixmapFormat(&rpcbuf, &(screenInfo.formats[i]));
|
|
}
|
|
|
|
DIX_FOR_N_SCREENS(0, maxscreens, {
|
|
x_rpcbuf_write_xWindowRoot(&rpcbuf, walkScreen);
|
|
|
|
DepthPtr pDepth = walkScreen->allowedDepths;
|
|
for (int j = 0; j < walkScreen->numDepths; j++, pDepth++) {
|
|
x_rpcbuf_write_xDepth(&rpcbuf, pDepth);
|
|
for (int k = 0; k < pDepth->numVids; k++) {
|
|
unsigned long vid = pDepth->vids[k];
|
|
VisualPtr pVisual;
|
|
for (pVisual = walkScreen->visuals;
|
|
pVisual->vid != vid; pVisual++);
|
|
x_rpcbuf_write_xVisualInfo(&rpcbuf, pVisual);
|
|
}
|
|
}
|
|
});
|
|
|
|
return rpcbuf;
|
|
}
|
|
|
|
char *dixNewConnectionInfoBlock(ClientPtr pClient, size_t *sz, size_t *scrOffset)
|
|
{
|
|
if (!ConnectionInfo)
|
|
return NULL;
|
|
|
|
char *newone = malloc(ConnectionInfoSize);
|
|
if (!newone)
|
|
return NULL;
|
|
|
|
memcpy(newone, ConnectionInfo, ConnectionInfoSize);
|
|
|
|
((xConnSetup *)newone)->ridBase = pClient->clientAsMask;
|
|
((xConnSetup *)newone)->ridMask = RESOURCE_ID_MASK;
|
|
|
|
/* fill in the "currentInputMask" */
|
|
/* attention: this still depends on setup block screens matching screenInfo.screens */
|
|
xWindowRoot *root = (xWindowRoot *) (newone + dixConnBlockScreenStart(newone));
|
|
int numScreens = ((xConnSetup *) newone)->numRoots;
|
|
for (unsigned int walkScreenIdx = 0; walkScreenIdx < numScreens; walkScreenIdx++) {
|
|
ScreenPtr walkScreen = screenInfo.screens[walkScreenIdx];
|
|
WindowPtr pRoot = walkScreen->root;
|
|
|
|
root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
|
|
xDepth *pDepth = (xDepth *) (root + 1);
|
|
for (unsigned int j = 0; j < root->nDepths; j++) {
|
|
pDepth = (xDepth *) (((char *) (pDepth + 1)) +
|
|
pDepth->nVisuals * sizeof(xVisualType));
|
|
}
|
|
root = (xWindowRoot *) pDepth;
|
|
}
|
|
|
|
if (sz)
|
|
*sz = ConnectionInfoSize;
|
|
if (scrOffset)
|
|
*scrOffset = dixConnBlockScreenStart(newone);
|
|
|
|
return newone;
|
|
}
|