From 629662657f3e2f19e0b68835d419872023e4b393 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Thu, 20 Feb 2025 07:50:50 +1100 Subject: [PATCH] X11: Query actual window depth/visual for 2D framebuffer --- misc/x11/min-xlib.h | 34 ++++++++++++++++++++++++++++++++++ src/Window_X11.c | 14 +++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/misc/x11/min-xlib.h b/misc/x11/min-xlib.h index 4d7b2f30a..4c397ac05 100644 --- a/misc/x11/min-xlib.h +++ b/misc/x11/min-xlib.h @@ -216,6 +216,34 @@ typedef struct { Cursor cursor; /* cursor to be displayed (or None) */ } XSetWindowAttributes; +typedef struct { + int x, y; /* location of window */ + int width, height; /* width and height of window */ + int border_width; /* border width of window */ + int depth; /* depth of window */ + Visual *visual; /* the associated visual structure */ + Window root; /* root of screen containing window */ +#if defined(__cplusplus) || defined(c_plusplus) + int c_class; /* C++ InputOutput, InputOnly*/ +#else + int class; /* InputOutput, InputOnly*/ +#endif + int bit_gravity; /* one of bit gravity values */ + int win_gravity; /* one of the window gravity values */ + int backing_store; /* NotUseful, WhenMapped, Always */ + unsigned long backing_planes;/* planes to be preserved if possible */ + unsigned long backing_pixel;/* value to be used when restoring planes */ + Bool save_under; /* boolean, should bits under be saved? */ + Colormap colormap; /* color map to be associated with window */ + Bool map_installed; /* boolean, is color map currently installed*/ + int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ + long all_event_masks; /* set of events all people have interest in*/ + long your_event_mask; /* my event mask */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Screen *screen; /* back pointer to correct screen */ +} XWindowAttributes; + /* * Data structure for "image" data, used by image manipulation routines. */ @@ -1186,6 +1214,12 @@ extern int XChangeWindowAttributes( XSetWindowAttributes* /* attributes */ ); +extern Status XGetWindowAttributes( + Display* /* display */, + Window /* w */, + XWindowAttributes* /* window_attributes_return */ +); + extern Bool XCheckIfEvent( Display* /* display */, XEvent* /* event_return */, diff --git a/src/Window_X11.c b/src/Window_X11.c index 6aab72025..0041f3a70 100644 --- a/src/Window_X11.c +++ b/src/Window_X11.c @@ -1221,11 +1221,15 @@ cc_result Window_SaveFileDialog(const struct SaveFileDialogArgs* args) { static GC fb_gc; static XImage* fb_image; static void* fb_data; -static int fb_fast; +static int fb_fast, fb_depth; void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) { Window win = Window_Main.Handle.val; + XWindowAttributes attribs = { 0 }; + if (!fb_gc) fb_gc = XCreateGC(win_display, win, 0, NULL); + XGetWindowAttributes(win_display, win, &attribs); + fb_depth = attribs.depth; bmp->scan0 = (BitmapCol*)Mem_Alloc(width * height, BITMAPCOLOR_SIZE, "window pixels"); bmp->width = width; @@ -1234,11 +1238,11 @@ void Window_AllocFramebuffer(struct Bitmap* bmp, int width, int height) { /* X11 requires that the image to draw has same depth as window */ /* Easy for 24/32 bit case, but much trickier with other depths */ /* (have to do a manual and slow second blit for other depths) */ - fb_fast = win_visual.depth == 24 || win_visual.depth == 32; + fb_fast = attribs.depth == 24 || attribs.depth == 32; fb_data = fb_fast ? bmp->scan0 : Mem_Alloc(width * height, BITMAPCOLOR_SIZE, "window blit"); - fb_image = XCreateImage(win_display, win_visual.visual, - win_visual.depth, ZPixmap, 0, (char*)fb_data, + fb_image = XCreateImage(win_display, attribs.visual, + attribs.depth, ZPixmap, 0, (char*)fb_data, width, height, 32, 0); } @@ -1261,7 +1265,7 @@ static void BlitFramebuffer(int x1, int y1, int width, int height, struct Bitmap B = BitmapCol_B(src); A = BitmapCol_A(src); - switch (win_visual.depth) + switch (fb_depth) { case 30: /* R10 G10 B10 A2 */ pixel = (R << 2) | ((G << 2) << 10) | ((B << 2) << 20) | ((A >> 6) << 30);