wl_backend: implement client_snapshot via buffer read (XWayland: XGetImage, native: wlr_buffer)
This commit is contained in:
parent
d548b2a1b0
commit
8a4e3954a0
16
ROADMAP.md
16
ROADMAP.md
|
|
@ -63,15 +63,13 @@ XWayland bridge auto-syncs. Needs verification.
|
|||
|
||||
### 1.4 Remaining Vtable Stubs
|
||||
|
||||
These vtable slots are stubs or partial implementations:
|
||||
|
||||
| Slot | Purpose | Needed For |
|
||||
|------|---------|------------|
|
||||
| `overlay_draw_*` | Pixman animation buffer | Iconify zoom animation |
|
||||
| `client_snapshot` | Window thumbnail capture | Switch panel thumbnails, icon preview |
|
||||
| `window_set_border` | Scene rect border nodes | Window borders |
|
||||
| `client_synth_configure` | XDG configure scheduling | Resize negotiation |
|
||||
| `pointer_change_grab` | Grab parameter update | Menu tracking |
|
||||
| Slot | Status |
|
||||
|------|--------|
|
||||
| `overlay_draw_*` | ✅ Done — real pixman overlay implementation |
|
||||
| `client_snapshot` | ❌ Stub — needs last-committed texture → RImage |
|
||||
| `window_set_border` | ✅ No-op (borders drawn into frame buffer) |
|
||||
| `client_synth_configure` | ✅ Done — XDG configure + XWayland configure |
|
||||
| `pointer_change_grab` | ⚠️ No-op — menu tracking may need this |
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -7882,7 +7882,65 @@ static int wl_client_get_pid(WNativeWindow win)
|
|||
|
||||
static RImage *
|
||||
wl_client_snapshot(WScreen *scr, WNativeWindow client_win, WNativeWindow frame_win)
|
||||
{ (void)scr; (void)client_win; (void)frame_win; return NULL; }
|
||||
{
|
||||
(void)frame_win;
|
||||
struct wl_toplevel_view *v = wl_find_view_by_id(client_win);
|
||||
if (!v) return NULL;
|
||||
|
||||
/* XWayland: capture via XGetImage on the WM's X display */
|
||||
if (v->xw_surface && wl_state.x_display) {
|
||||
Window xid = (Window)v->xw_surface->window_id;
|
||||
XWindowAttributes attr;
|
||||
if (!XGetWindowAttributes(wl_state.x_display, xid, &attr))
|
||||
return NULL;
|
||||
XImage *img = XGetImage(wl_state.x_display, xid,
|
||||
0, 0, attr.width, attr.height,
|
||||
AllPlanes, ZPixmap);
|
||||
if (!img) return NULL;
|
||||
RImage *res = RCreateImageFromXImage(scr->rcontext, img, NULL);
|
||||
XDestroyImage(img);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Native Wayland: read pixels from last committed surface buffer */
|
||||
if (!v->xdg_surface || !v->xdg_surface->surface) return NULL;
|
||||
struct wlr_surface *s = v->xdg_surface->surface;
|
||||
if (!s->buffer) return NULL;
|
||||
struct wlr_buffer *buf = &s->buffer->base;
|
||||
|
||||
uint32_t fmt;
|
||||
void *data;
|
||||
size_t stride;
|
||||
if (!wlr_buffer_begin_data_ptr_access(buf, WLR_BUFFER_DATA_PTR_ACCESS_READ, &data, &fmt, &stride))
|
||||
return NULL;
|
||||
|
||||
int w = s->current.width;
|
||||
int h = s->current.height;
|
||||
if (w <= 0 || h <= 0) {
|
||||
wlr_buffer_end_data_ptr_access(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create RImage and copy pixels (ARGB32 → RGBA byte order swap) */
|
||||
RImage *res = RCreateImage(w, h, True);
|
||||
if (res) {
|
||||
unsigned char *src = (unsigned char *)data;
|
||||
unsigned char *dst = res->data;
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
int si = y * stride + x * 4;
|
||||
int di = (y * w + x) * 4;
|
||||
dst[di + 0] = src[si + 2]; /* B → R */
|
||||
dst[di + 1] = src[si + 1]; /* G → G */
|
||||
dst[di + 2] = src[si + 0]; /* R → B */
|
||||
dst[di + 3] = src[si + 3]; /* A → A */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wlr_buffer_end_data_ptr_access(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
wl_coords_translate(WNativeWindow src, WNativeWindow dst,
|
||||
|
|
|
|||
Loading…
Reference in New Issue