From 6977718454a1a2ba2cca8e37a30055d17f347453 Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Thu, 15 Aug 2024 17:48:50 +0200 Subject: [PATCH] Xnest: screen: record visuals and cmaps in separate table Record the associations between host's and our visuals as well their corresponding cmaps in a global table, which's used later for lookups. Signed-off-by: Enrico Weigelt, metux IT consult --- hw/xnest/Display.c | 3 +++ hw/xnest/Screen.c | 22 ++++++++++++++++++++++ hw/xnest/xcb.c | 2 ++ hw/xnest/xnest-xcb.h | 11 +++++++++++ 4 files changed, 38 insertions(+) diff --git a/hw/xnest/Display.c b/hw/xnest/Display.c index ded8e21de..931369469 100644 --- a/hw/xnest/Display.c +++ b/hw/xnest/Display.c @@ -180,6 +180,9 @@ xnestCloseDisplay(void) If xnestDoFullGeneration all x resources will be destroyed upon closing the display connection. There is no need to generate extra protocol. */ + free(xnestVisualMap); + xnestVisualMap = NULL; + xnestNumVisualMap = 0; free(xnestDefaultColormaps); XFree(xnestVisuals); diff --git a/hw/xnest/Screen.c b/hw/xnest/Screen.c index dca614cb5..0357255cd 100644 --- a/hw/xnest/Screen.c +++ b/hw/xnest/Screen.c @@ -203,6 +203,11 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) return FALSE; } + if (!xnestVisualMap) + xnestVisualMap = calloc(1, sizeof(xnest_visual_t)); + else + xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(xnest_visual_t)); + depths[0].depth = 1; depths[0].numVids = 0; depths[0].vids = calloc(MAXVISUALSPERDEPTH, sizeof(VisualID)); @@ -244,6 +249,20 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) .vid = FakeClientID(0), }; + xnestVisualMap[xnestNumVisualMap] = (xnest_visual_t) { + .ourXID = visuals[numVisuals].vid, + .ourVisual = &visuals[numVisuals], + .upstreamDepth = depth_iter.data, + .upstreamVisual = &vts[x], + .upstreamCMap = xcb_generate_id(xnestUpstreamInfo.conn), + }; + + xcb_create_colormap(xnestUpstreamInfo.conn, + XCB_COLORMAP_ALLOC_NONE, + xnestVisualMap[xnestNumVisualMap].upstreamCMap, + xnestUpstreamInfo.screenInfo->root, + xnestVisualMap[xnestNumVisualMap].upstreamVisual->visual_id); + numDepths = add_depth_visual(depths, numDepths, visuals[numVisuals].nplanes, visuals[numVisuals].vid); if (xnestUserDefaultClass || xnestUserDefaultDepth) { @@ -266,11 +285,14 @@ xnestOpenScreen(ScreenPtr pScreen, int argc, char *argv[]) } numVisuals++; + xnestNumVisualMap++; visuals = reallocarray(visuals, numVisuals+1, sizeof(VisualRec)); + xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap+1, sizeof(xnest_visual_t)); } } breakout: visuals = reallocarray(visuals, numVisuals, sizeof(VisualRec)); + xnestVisualMap = reallocarray(xnestVisualMap, xnestNumVisualMap, sizeof(xnest_visual_t)); if (!found_default_visual) { ErrorF("Xnest: can't find matching visual for user specified depth %d\n", xnestDefaultDepth); diff --git a/hw/xnest/xcb.c b/hw/xnest/xcb.c index f3622346e..55578b742 100644 --- a/hw/xnest/xcb.c +++ b/hw/xnest/xcb.c @@ -24,6 +24,8 @@ #include "Display.h" struct xnest_upstream_info xnestUpstreamInfo = { 0 }; +xnest_visual_t *xnestVisualMap; +int xnestNumVisualMap; void xnest_upstream_setup(void) { xnestUpstreamInfo.screenId = DefaultScreen(xnestDisplay); diff --git a/hw/xnest/xnest-xcb.h b/hw/xnest/xnest-xcb.h index 1a76fdaae..9ec05c787 100644 --- a/hw/xnest/xnest-xcb.h +++ b/hw/xnest/xnest-xcb.h @@ -22,6 +22,17 @@ void xnest_upstream_setup(void); /* retrieve upstream GC XID for our xserver GC */ uint32_t xnest_upstream_gc(GCPtr pGC); +typedef struct { + xcb_visualtype_t *upstreamVisual; + xcb_depth_t *upstreamDepth; + xcb_colormap_t upstreamCMap; + uint32_t ourXID; + VisualPtr ourVisual; +} xnest_visual_t; + +extern xnest_visual_t *xnestVisualMap; +extern int xnestNumVisualMap; + void xnest_wm_colormap_windows(xcb_connection_t *conn, xcb_window_t w, xcb_window_t *windows, int count);