Fix render backend crashes: resolve view IDs in all drawing functions

All WINGs render backend functions (draw_line, draw_rect, fill_rect,
pixmap_copy, composite_pixmap) now use resolve_drawable() to handle
WINGs view IDs (0x20000000+) by looking up the backing pixman image.

Also fixes:
- wfont_wl.c: resolve view IDs in draw_string/draw_image_string
- wtextfield.c paintCursor: use render backend draw_line (not XDrawLine)
- dialog.c wShowInfoPanel: guard scr->w_visual for Wayland mode
This commit is contained in:
Levi Neely 2026-05-13 19:40:31 +02:00
parent 1d0b82eed5
commit 9191f12913
3 changed files with 38 additions and 22 deletions

View File

@ -20,6 +20,14 @@
#include <pixman.h>
#include <string.h>
extern void *W_GetViewBacking(unsigned long id);
static inline pixman_image_t *wl_font_resolve_drawable(WMDrawable d)
{
if ((unsigned long)d >= 0x20000000 && (unsigned long)d < 0x30000000)
return (pixman_image_t *)W_GetViewBacking((unsigned long)d);
return (pixman_image_t *)(uintptr_t)d;
}
/* ------------------------------------------------------------------ */
typedef struct {
@ -139,7 +147,7 @@ wl_draw_string(void *sctx, void *handle, WMDrawable d,
const char *text, int len)
{
FontHandleWL *h = handle;
pixman_image_t *dst = (pixman_image_t *)(uintptr_t)d;
pixman_image_t *dst = wl_font_resolve_drawable(d); if (!dst) return;
(void)sctx; (void)pixel;
const char *prev = pango_layout_get_text(h->layout);
@ -178,7 +186,7 @@ wl_draw_image_string(void *sctx, void *handle, WMDrawable d,
int bg_w, int bg_h,
const char *text, int len)
{
pixman_image_t *dst = (pixman_image_t *)(uintptr_t)d;
pixman_image_t *dst = wl_font_resolve_drawable(d); if (!dst) return;
(void)tpix; (void)bpix;
/* Fill background. */

View File

@ -22,6 +22,17 @@ render_wl_screen_fini(void *rctx)
wfree(rctx);
}
/* Resolve a WMDrawable to a pixman_image_t*.
* If it's a WINGs view ID (0x20000000..0x2FFFFFFF), look up backing image. */
extern void *W_GetViewBacking(unsigned long id);
static inline pixman_image_t *
resolve_drawable(WMDrawable d)
{
if ((unsigned long)d >= 0x20000000 && (unsigned long)d < 0x30000000)
return (pixman_image_t *)W_GetViewBacking((unsigned long)d);
return (pixman_image_t *)d;
}
static WMDrawable
render_wl_pixmap_create(void *rctx, unsigned int width, unsigned int height, int depth)
{
@ -45,16 +56,8 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst,
{
(void)rctx;
pixman_image_t *s = (pixman_image_t *)src;
pixman_image_t *d;
/* If dst is a WINGs view ID, look up its backing image */
if ((unsigned long)dst >= 0x20000000 && (unsigned long)dst < 0x30000000) {
extern void *W_GetViewBacking(unsigned long id);
d = (pixman_image_t *)W_GetViewBacking((unsigned long)dst);
if (!d) return; /* no backing store yet */
} else {
d = (pixman_image_t *)dst;
}
pixman_image_t *d = resolve_drawable(dst);
if (!d) return;
pixman_image_composite32(PIXMAN_OP_SRC, s, NULL, d,
sx, sy, 0, 0, dx, dy, w, h);
}
@ -75,7 +78,7 @@ render_wl_draw_line(void *rctx, WMDrawable d, WMColor *color,
int x1, int y1, int x2, int y2)
{
(void)rctx;
pixman_image_t *dst = (pixman_image_t *)d;
pixman_image_t *dst = resolve_drawable(d); if (!dst) return;
pixman_color_t pc = wm_color_to_pixman(color);
pixman_image_t *fill = pixman_image_create_solid_fill(&pc);
@ -101,7 +104,7 @@ render_wl_draw_rect(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h)
{
(void)rctx;
pixman_image_t *dst = (pixman_image_t *)d;
pixman_image_t *dst = resolve_drawable(d); if (!dst) return;
pixman_color_t pc = wm_color_to_pixman(color);
/* top */
@ -123,7 +126,7 @@ render_wl_fill_rect(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h)
{
(void)rctx;
pixman_image_t *dst = (pixman_image_t *)d;
pixman_image_t *dst = resolve_drawable(d); if (!dst) return;
pixman_color_t pc = wm_color_to_pixman(color);
pixman_image_fill_rectangles(PIXMAN_OP_OVER, dst, &pc, 1,
&(pixman_rectangle16_t){x, y, w, h});
@ -134,7 +137,7 @@ render_wl_fill_stippled(void *rctx, WMDrawable d, WMColor *color,
int x, int y, unsigned int w, unsigned int h)
{
(void)rctx;
pixman_image_t *dst = (pixman_image_t *)d;
pixman_image_t *dst = resolve_drawable(d); if (!dst) return;
pixman_color_t pc = wm_color_to_pixman(color);
pixman_image_t *fill = pixman_image_create_solid_fill(&pc);
@ -154,7 +157,7 @@ render_wl_composite_pixmap(void *rctx, WMDrawable dst, W_Pixmap *src,
int dx, int dy)
{
(void)rctx;
pixman_image_t *d = (pixman_image_t *)dst;
pixman_image_t *d = resolve_drawable(dst); if (!d) return;
pixman_image_t *s = (pixman_image_t *)(uintptr_t)src->pixmap;
pixman_image_t *m = src->mask ? (pixman_image_t *)(uintptr_t)src->mask : NULL;
@ -168,7 +171,7 @@ render_wl_fill_polygon(void *rctx, WMDrawable d, WMColor *color,
{
(void)rctx;
if (npoints < 3) return;
pixman_image_t *dst = (pixman_image_t *)d;
pixman_image_t *dst = resolve_drawable(d); if (!dst) return;
pixman_color_t pc = wm_color_to_pixman(color);
/* Find bounding box */
@ -204,7 +207,7 @@ render_wl_fill_arc(void *rctx, WMDrawable d, WMColor *color,
int angle1, int angle2)
{
(void)rctx;
pixman_image_t *dst = (pixman_image_t *)d;
pixman_image_t *dst = resolve_drawable(d); if (!dst) return;
pixman_color_t pc = wm_color_to_pixman(color);
/* X11 angles are in 64ths of a degree */

View File

@ -1353,9 +1353,14 @@ void wShowInfoPanel(WScreen *scr)
strbuf = wstrappend(strbuf, buffer);
}
snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
(unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
strbuf = wstrappend(strbuf, buffer);
if (scr->w_visual) {
snprintf(buffer, sizeof(buffer), _("Using visual 0x%x: %s %ibpp "),
(unsigned)scr->w_visual->visualid, visuals[scr->w_visual->class], scr->w_depth);
strbuf = wstrappend(strbuf, buffer);
} else {
snprintf(buffer, sizeof(buffer), _("Using Wayland compositor %ibpp "), scr->w_depth ? scr->w_depth : 32);
strbuf = wstrappend(strbuf, buffer);
}
switch (scr->w_depth) {
case 15: