fix crash: resolve frame_buf IDs via W_GetFrameBufImageFn

After removing frame_bufs from the view_table, policy code like
update_icon_title still passes frame_buf IDs to WMDrawString.
These IDs (0x10000000 range) were being treated as raw pointers,
causing a segfault. Add W_GetFrameBufImageFn hook that resolves
frame_buf IDs to pixman images via frame_buf_find().
This commit is contained in:
lkn 2026-06-23 22:40:49 +02:00
parent b20197ac91
commit 03eede810b
4 changed files with 18 additions and 3 deletions

View File

@ -23,13 +23,14 @@
#include <string.h>
extern void *W_GetViewBacking(unsigned long id);
/* Function pointer set by the WM backend to resolve frame_buf IDs. */
void *(*W_GetFrameBufImageFn)(unsigned long id) = NULL;
static inline pixman_image_t *wl_font_resolve_drawable(WMDrawable d)
{
/* WINGs view IDs (0x20000000-0x2FFFFFFF) are in the backing table.
* Frame_buf IDs (0x10000000-0x1FFFFFFF) are no longer stored;
* callers pass raw pixman_image_t pointers instead. */
if ((unsigned long)d >= 0x20000000 && (unsigned long)d < 0x30000000)
return (pixman_image_t *)W_GetViewBacking((unsigned long)d);
if ((unsigned long)d >= 0x10000000 && (unsigned long)d < 0x20000000)
return W_GetFrameBufImageFn ? (pixman_image_t *)W_GetFrameBufImageFn((unsigned long)d) : NULL;
return (pixman_image_t *)(uintptr_t)d;
}

View File

@ -29,11 +29,14 @@ render_wl_screen_fini(void *rctx)
* 0x20000000-0x2FFFFFFF = WINGs view windows.
* Both registered via W_RegisterBacking. */
extern void *W_GetViewBacking(unsigned long id);
extern void *(*W_GetFrameBufImageFn)(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);
if ((unsigned long)d >= 0x10000000 && (unsigned long)d < 0x20000000)
return W_GetFrameBufImageFn ? (pixman_image_t *)W_GetFrameBufImageFn((unsigned long)d) : NULL;
return (pixman_image_t *)d;
}

View File

@ -463,6 +463,10 @@ wl_display_open(const char *name)
extern void wl_view_scene_node_set_enabled(unsigned long id, int enabled);
W_ViewSceneNodeSetEnabledFn = wl_view_scene_node_set_enabled;
extern void *(*W_GetFrameBufImageFn)(unsigned long id);
extern void *W_GetFrameBufImage(unsigned long id);
W_GetFrameBufImageFn = W_GetFrameBufImage;
extern int (*W_WLPointerGrabFn)(WNativeWindow, WNativeWindow,
unsigned int, int, int, unsigned long);
extern void (*W_WLPointerUngrabFn)(unsigned long);

View File

@ -57,6 +57,13 @@ void frame_buf_end_data_ptr_access(struct wlr_buffer *wlr_buf)
(void)wlr_buf;
}
/* Resolve a frame_buf ID to its pixman image (for WMDrawString). */
void *W_GetFrameBufImage(unsigned long id)
{
struct wl_frame_buf *fb = frame_buf_find((WNativeWindow)id);
return fb ? fb->image : NULL;
}
const struct wlr_buffer_impl frame_buf_impl = {
.destroy = frame_buf_destroy,
.begin_data_ptr_access = frame_buf_begin_data_ptr_access,