decompose wl_backend.c: extract wl_badge.c

This commit is contained in:
Window Maker 2026-06-02 11:07:56 +02:00
parent 0878f6946d
commit db0db065a1
4 changed files with 119 additions and 97 deletions

View File

@ -169,7 +169,8 @@ wmaker_SOURCES += \
backend/wayland/wl_framebuf.c \
backend/wayland/wl_atom.c \
backend/wayland/wl_signalfd.c \
backend/wayland/wl_xkb.c
backend/wayland/wl_xkb.c \
backend/wayland/wl_badge.c
endif
if USE_NESTED_FUNC

View File

@ -6106,102 +6106,6 @@ wl_monitors_query(WScreen *scr, WHeadGeometry **heads_out, int *count_out)
static void wl_monitors_select_events(WScreen *scr) { (void)scr; }
/* ------------------------------------------------------------------ */
/* Workspace badge */
/* ------------------------------------------------------------------ */
static RImage *
wl_workspace_badge_render(WScreen *scr, WNativeWindow badge_win,
const char *name, int name_len,
int width, int height)
{
struct wl_frame_buf *fb = frame_buf_find(badge_win);
if (!fb) return NULL;
/* Resize pixman buffer if needed */
if (width > 0 && height > 0 && (width != fb->width || height != fb->height)) {
W_UnregisterBacking(fb->id);
pixman_image_unref(fb->image);
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
if (!fb->image) return NULL;
fb->width = width;
fb->height = height;
fb->base.width = width;
fb->base.height = height;
W_RegisterBacking(fb->id, fb->image);
}
/* Fill transparent */
uint32_t *px = pixman_image_get_data(fb->image);
for (int i = 0; i < width * height; i++)
px[i] = 0x00000000;
/* Draw white text */
WMDrawString(scr->wmscreen, (WMDrawable)badge_win, scr->white,
scr->workspace_name_font, 2, 2, name, name_len);
/* Update scene buffer */
if (fb->scene_buf)
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
/* Return RGBA RImage copy for fade animation */
RImage *result = RCreateImage(width, height, True);
if (result) {
uint32_t *src = pixman_image_get_data(fb->image);
for (int i = 0; i < width * height; i++) {
uint32_t p = src[i];
result->data[i * 4 + 0] = (p >> 16) & 0xFF; /* R */
result->data[i * 4 + 1] = (p >> 8) & 0xFF; /* G */
result->data[i * 4 + 2] = p & 0xFF; /* B */
result->data[i * 4 + 3] = (p >> 24) & 0xFF; /* A */
}
}
return result;
}
static RImage *
wl_workspace_badge_get_background(WScreen *scr, int x, int y, int width, int height)
{
(void)scr; (void)x; (void)y;
/* Return a fully transparent background so the badge floats over the desktop */
RImage *img = RCreateImage(width, height, True);
if (img)
memset(img->data, 0, width * height * 4);
return img;
}
static void
wl_workspace_badge_update(WScreen *scr, WNativeWindow badge_win, RImage *img)
{
(void)scr;
if (!img) return;
struct wl_frame_buf *fb = frame_buf_find(badge_win);
if (!fb || !fb->image) return;
int w = img->width;
int h = img->height;
if (w > fb->width) w = fb->width;
if (h > fb->height) h = fb->height;
/* Blit RImage (RGB or RGBA) into pixman ARGB32 buffer */
uint32_t *dst = pixman_image_get_data(fb->image);
int bpp = img->format == RRGBAFormat ? 4 : 3;
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int si = (y * img->width + x) * bpp;
uint8_t r = img->data[si];
uint8_t g = img->data[si + 1];
uint8_t b = img->data[si + 2];
uint8_t a = (bpp == 4) ? img->data[si + 3] : 0xFF;
dst[y * fb->width + x] = ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
}
}
if (fb->scene_buf)
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
if (wl_state.output)
wlr_output_schedule_frame(wl_state.output);
}
/* ------------------------------------------------------------------ */

View File

@ -0,0 +1,112 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <stdint.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_scene.h>
#include <wlr/types/wlr_output.h>
#include <pixman.h>
#include "../../screen.h"
#include "wl_types.h"
/* Forward declarations */
extern void *W_RegisterBacking(unsigned long id, void *img);
extern void W_UnregisterBacking(unsigned long id);
/* ------------------------------------------------------------------ */
/* Workspace badge */
/* ------------------------------------------------------------------ */
RImage *
wl_workspace_badge_render(WScreen *scr, WNativeWindow badge_win,
const char *name, int name_len,
int width, int height)
{
struct wl_frame_buf *fb = frame_buf_find(badge_win);
if (!fb) return NULL;
/* Resize pixman buffer if needed */
if (width > 0 && height > 0 && (width != fb->width || height != fb->height)) {
W_UnregisterBacking(fb->id);
pixman_image_unref(fb->image);
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
if (!fb->image) return NULL;
fb->width = width;
fb->height = height;
fb->base.width = width;
fb->base.height = height;
W_RegisterBacking(fb->id, fb->image);
}
/* Fill transparent */
uint32_t *px = pixman_image_get_data(fb->image);
for (int i = 0; i < width * height; i++)
px[i] = 0x00000000;
/* Draw white text */
WMDrawString(scr->wmscreen, (WMDrawable)badge_win, scr->white,
scr->workspace_name_font, 2, 2, name, name_len);
/* Update scene buffer */
if (fb->scene_buf)
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
/* Return RGBA RImage copy for fade animation */
RImage *result = RCreateImage(width, height, True);
if (result) {
uint32_t *src = pixman_image_get_data(fb->image);
for (int i = 0; i < width * height; i++) {
uint32_t p = src[i];
result->data[i * 4 + 0] = (p >> 16) & 0xFF; /* R */
result->data[i * 4 + 1] = (p >> 8) & 0xFF; /* G */
result->data[i * 4 + 2] = p & 0xFF; /* B */
result->data[i * 4 + 3] = (p >> 24) & 0xFF; /* A */
}
}
return result;
}
RImage *
wl_workspace_badge_get_background(WScreen *scr, int x, int y, int width, int height)
{
(void)scr; (void)x; (void)y;
/* Return a fully transparent background so the badge floats over the desktop */
RImage *img = RCreateImage(width, height, True);
if (img)
memset(img->data, 0, width * height * 4);
return img;
}
void
wl_workspace_badge_update(WScreen *scr, WNativeWindow badge_win, RImage *img)
{
(void)scr;
if (!img) return;
struct wl_frame_buf *fb = frame_buf_find(badge_win);
if (!fb || !fb->image) return;
int w = img->width;
int h = img->height;
if (w > fb->width) w = fb->width;
if (h > fb->height) h = fb->height;
/* Blit RImage (RGB or RGBA) into pixman ARGB32 buffer */
uint32_t *dst = pixman_image_get_data(fb->image);
int bpp = img->format == RRGBAFormat ? 4 : 3;
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
int si = (y * img->width + x) * bpp;
uint8_t r = img->data[si];
uint8_t g = img->data[si + 1];
uint8_t b = img->data[si + 2];
uint8_t a = (bpp == 4) ? img->data[si + 3] : 0xFF;
dst[y * fb->width + x] = ((uint32_t)a << 24) | (r << 16) | (g << 8) | b;
}
}
if (fb->scene_buf)
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
if (wl_state.output)
wlr_output_schedule_frame(wl_state.output);
}

View File

@ -509,3 +509,8 @@ WKeyCode wl_keysym_to_keycode(unsigned long keysym);
unsigned long wl_keysym_from_keycode(unsigned int keycode, unsigned int index);
void wl_xkb_lock_group(int group);
int wl_xkb_get_group(void);
/* Workspace badge declarations (extracted to wl_badge.c) */
RImage *wl_workspace_badge_render(WScreen *scr, WNativeWindow badge_win, const char *name, int name_len, int width, int height);
RImage *wl_workspace_badge_get_background(WScreen *scr, int x, int y, int width, int height);
void wl_workspace_badge_update(WScreen *scr, WNativeWindow badge_win, RImage *img);