decompose wl_stubs.c: move wl_frame_paint_button + wl_netwm_update_opacity to wl_framebuf.c
This commit is contained in:
parent
c635fcd3fa
commit
75a4224370
|
|
@ -10,6 +10,8 @@
|
|||
#include <wlr/types/wlr_output.h>
|
||||
#include <libdrm/drm_fourcc.h>
|
||||
#include <pixman.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include "../../def_pixmaps.h"
|
||||
#include "../../screen.h"
|
||||
#include "../../framewin.h"
|
||||
#include "../../texture.h"
|
||||
|
|
@ -727,3 +729,145 @@ wl_frame_paint(struct WFrameWindow *fwin)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
wl_frame_paint_button(WCoreWindow *button, WTexture *texture,
|
||||
unsigned long color, WPixmap *image, int pushed)
|
||||
{
|
||||
(void)texture; (void)image;
|
||||
WFrameWindow *fwin = (WFrameWindow *)button->descriptor.parent;
|
||||
if (!fwin || !fwin->core)
|
||||
return;
|
||||
|
||||
struct wl_frame_buf *btn_fb = frame_buf_find(button->window);
|
||||
if (!btn_fb || !btn_fb->image)
|
||||
return;
|
||||
|
||||
int bw = btn_fb->width;
|
||||
int bh = btn_fb->height;
|
||||
|
||||
RImage *icon = NULL;
|
||||
if (button == fwin->right_button) {
|
||||
if (!wl_state.btn_close_img)
|
||||
wl_state.btn_close_img = RGetImageFromXPMData(
|
||||
button->screen_ptr->rcontext, PRED_CLOSE_XPM);
|
||||
icon = wl_state.btn_close_img;
|
||||
} else if (button == fwin->left_button) {
|
||||
if (!wl_state.btn_iconify_img)
|
||||
wl_state.btn_iconify_img = RGetImageFromXPMData(
|
||||
button->screen_ptr->rcontext, PRED_ICONIFY_XPM);
|
||||
icon = wl_state.btn_iconify_img;
|
||||
}
|
||||
if (!icon)
|
||||
return;
|
||||
|
||||
struct wl_frame_buf *tb_fb = fwin->titlebar ? frame_buf_find(fwin->titlebar->window) : NULL;
|
||||
uint32_t bg_pixel = 0xFF333333;
|
||||
if (tb_fb && tb_fb->image) {
|
||||
uint32_t *tb_data = pixman_image_get_data(tb_fb->image);
|
||||
int tb_stride = pixman_image_get_stride(tb_fb->image) / 4;
|
||||
int sample_y = btn_fb->rel_y + bh / 2;
|
||||
int sample_x = btn_fb->rel_x + bw / 2;
|
||||
if (sample_y >= 0 && sample_y < tb_fb->height &&
|
||||
sample_x >= 0 && sample_x < tb_fb->width)
|
||||
bg_pixel = tb_data[sample_y * tb_stride + sample_x];
|
||||
}
|
||||
|
||||
uint32_t fg_pixel = 0xFF000000 | ((color >> 16 & 0xFF) << 16) |
|
||||
((color >> 8 & 0xFF) << 8) | (color & 0xFF);
|
||||
uint32_t fill_bg = pushed ? fg_pixel : bg_pixel;
|
||||
uint32_t fill_fg = pushed ? bg_pixel : fg_pixel;
|
||||
|
||||
uint32_t *dst = pixman_image_get_data(btn_fb->image);
|
||||
int dst_stride = pixman_image_get_stride(btn_fb->image) / 4;
|
||||
|
||||
for (int y = 0; y < bh; y++)
|
||||
for (int x = 0; x < bw; x++)
|
||||
dst[y * dst_stride + x] = fill_bg;
|
||||
|
||||
unsigned char bg_r = (bg_pixel >> 16) & 0xFF;
|
||||
unsigned char bg_g = (bg_pixel >> 8) & 0xFF;
|
||||
unsigned char bg_b = bg_pixel & 0xFF;
|
||||
uint32_t hi_c = 0xFF000000 | ((uint32_t)(bg_r + (255-bg_r)/3) << 16) |
|
||||
((uint32_t)(bg_g + (255-bg_g)/3) << 8) | (bg_b + (255-bg_b)/3);
|
||||
uint32_t lo_c = 0xFF000000 | ((uint32_t)(bg_r * 2/3) << 16) |
|
||||
((uint32_t)(bg_g * 2/3) << 8) | (bg_b * 2/3);
|
||||
uint32_t hi = pushed ? lo_c : hi_c;
|
||||
uint32_t lo = pushed ? hi_c : lo_c;
|
||||
for (int x = 0; x < bw; x++) { dst[x] = hi; dst[(bh-1) * dst_stride + x] = lo; }
|
||||
for (int y = 0; y < bh; y++) { dst[y * dst_stride] = hi; dst[y * dst_stride + bw - 1] = lo; }
|
||||
|
||||
int ix = (bw - icon->width) / 2 + (pushed ? 1 : 0);
|
||||
int iy = (bh - icon->height) / 2 + (pushed ? 1 : 0);
|
||||
|
||||
for (int y = 0; y < icon->height; y++) {
|
||||
int dy = iy + y;
|
||||
if (dy < 0 || dy >= bh) continue;
|
||||
uint32_t *dst_row = dst + dy * dst_stride;
|
||||
for (int x = 0; x < icon->width; x++) {
|
||||
int dx = ix + x;
|
||||
if (dx < 0 || dx >= bw) continue;
|
||||
unsigned char a;
|
||||
if (icon->format == RRGBAFormat)
|
||||
a = icon->data[(y * icon->width + x) * 4 + 3];
|
||||
else
|
||||
a = 255;
|
||||
if (a == 0) continue;
|
||||
dst_row[dx] = fill_fg;
|
||||
}
|
||||
}
|
||||
|
||||
wlr_scene_buffer_set_buffer_with_damage(btn_fb->scene_buf, &btn_fb->base, NULL);
|
||||
wlr_scene_node_set_enabled(&btn_fb->scene_buf->node, true);
|
||||
wlr_scene_node_raise_to_top(&btn_fb->scene_buf->node);
|
||||
}
|
||||
|
||||
void
|
||||
wl_netwm_update_opacity(WWindow *wwin)
|
||||
{
|
||||
if (!wwin->frame)
|
||||
return;
|
||||
|
||||
struct wl_frame_buf *fb = frame_buf_find(wwin->frame->core->window);
|
||||
if (!fb || !fb->scene_buf)
|
||||
return;
|
||||
|
||||
float alpha = 1.0f;
|
||||
if (wl_state.x_display && wwin->client_win) {
|
||||
WMNativeAtom type;
|
||||
int format;
|
||||
unsigned long items, rest;
|
||||
unsigned char *prop = NULL;
|
||||
WMNativeAtom opacity_atom = XInternAtom(wl_state.x_display,
|
||||
"_NET_WM_WINDOW_OPACITY", False);
|
||||
if (XGetWindowProperty(wl_state.x_display, (WNativeWindow)wwin->client_win,
|
||||
opacity_atom, 0L, 1L, False, AnyPropertyType,
|
||||
&type, &format, &items, &rest, &prop) == Success
|
||||
&& format == 32 && items == 1 && prop) {
|
||||
unsigned long val = *(unsigned long *)prop;
|
||||
alpha = (float)val / (float)0xFFFFFFFF;
|
||||
}
|
||||
if (prop)
|
||||
XFree(prop);
|
||||
}
|
||||
|
||||
wlr_scene_buffer_set_opacity(fb->scene_buf, alpha);
|
||||
|
||||
struct wl_frame_buf *child;
|
||||
wl_list_for_each(child, &wl_state.frame_list, link) {
|
||||
if (child->parent_id == fb->id && child->scene_buf)
|
||||
wlr_scene_buffer_set_opacity(child->scene_buf, alpha);
|
||||
}
|
||||
|
||||
struct wl_toplevel_view *v;
|
||||
wl_list_for_each(v, &wl_state.toplevel_list, link) {
|
||||
if (v->frame_id == fb->id && v->scene_node) {
|
||||
struct wlr_scene_node *node;
|
||||
wl_list_for_each(node, &v->scene_node->children, link) {
|
||||
if (node->type == WLR_SCENE_NODE_BUFFER)
|
||||
wlr_scene_buffer_set_opacity(
|
||||
wlr_scene_buffer_from_node(node), alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
/* Forward declarations */
|
||||
struct wl_toplevel_view *wl_find_view_by_id(WNativeWindow id);
|
||||
void wl_set_cursor_image(const char *name);
|
||||
void wl_frame_paint_button(WCoreWindow *button, WTexture *texture, unsigned long color, WPixmap *image, int pushed);
|
||||
void wl_netwm_update_opacity(WWindow *wwin);
|
||||
extern void *W_RegisterBacking(unsigned long id, void *img);
|
||||
extern void W_UnregisterBacking(unsigned long id);
|
||||
|
||||
|
|
@ -51,158 +53,10 @@ void wl_noop_frame_alloc_border_pixel(unsigned long colormap,
|
|||
|
||||
void wl_noop_frame_update_texture(struct WFrameWindow *fwin) { (void)fwin; }
|
||||
|
||||
void wl_frame_paint_button(WCoreWindow *button, WTexture *texture,
|
||||
unsigned long color, WPixmap *image, int pushed)
|
||||
{
|
||||
(void)texture; (void)image;
|
||||
WFrameWindow *fwin = (WFrameWindow *)button->descriptor.parent;
|
||||
if (!fwin || !fwin->core)
|
||||
return;
|
||||
|
||||
struct wl_frame_buf *btn_fb = frame_buf_find(button->window);
|
||||
if (!btn_fb || !btn_fb->image)
|
||||
return;
|
||||
|
||||
int bw = btn_fb->width;
|
||||
int bh = btn_fb->height;
|
||||
|
||||
/* Determine which icon to use */
|
||||
RImage *icon = NULL;
|
||||
if (button == fwin->right_button) {
|
||||
if (!wl_state.btn_close_img)
|
||||
wl_state.btn_close_img = RGetImageFromXPMData(
|
||||
button->screen_ptr->rcontext, PRED_CLOSE_XPM);
|
||||
icon = wl_state.btn_close_img;
|
||||
} else if (button == fwin->left_button) {
|
||||
if (!wl_state.btn_iconify_img)
|
||||
wl_state.btn_iconify_img = RGetImageFromXPMData(
|
||||
button->screen_ptr->rcontext, PRED_ICONIFY_XPM);
|
||||
icon = wl_state.btn_iconify_img;
|
||||
}
|
||||
if (!icon)
|
||||
return;
|
||||
|
||||
/* Get titlebar background color */
|
||||
struct wl_frame_buf *tb_fb = fwin->titlebar ? frame_buf_find(fwin->titlebar->window) : NULL;
|
||||
uint32_t bg_pixel = 0xFF333333;
|
||||
if (tb_fb && tb_fb->image) {
|
||||
uint32_t *tb_data = pixman_image_get_data(tb_fb->image);
|
||||
int tb_stride = pixman_image_get_stride(tb_fb->image) / 4;
|
||||
int sample_y = btn_fb->rel_y + bh / 2;
|
||||
int sample_x = btn_fb->rel_x + bw / 2;
|
||||
if (sample_y >= 0 && sample_y < tb_fb->height &&
|
||||
sample_x >= 0 && sample_x < tb_fb->width)
|
||||
bg_pixel = tb_data[sample_y * tb_stride + sample_x];
|
||||
}
|
||||
|
||||
/* Foreground = title text color; when pushed, swap fg/bg */
|
||||
uint32_t fg_pixel = 0xFF000000 | ((color >> 16 & 0xFF) << 16) |
|
||||
((color >> 8 & 0xFF) << 8) | (color & 0xFF);
|
||||
uint32_t fill_bg = pushed ? fg_pixel : bg_pixel;
|
||||
uint32_t fill_fg = pushed ? bg_pixel : fg_pixel;
|
||||
|
||||
uint32_t *dst = pixman_image_get_data(btn_fb->image);
|
||||
int dst_stride = pixman_image_get_stride(btn_fb->image) / 4;
|
||||
|
||||
/* Fill background */
|
||||
for (int y = 0; y < bh; y++)
|
||||
for (int x = 0; x < bw; x++)
|
||||
dst[y * dst_stride + x] = fill_bg;
|
||||
|
||||
/* Draw border bevel derived from bg color (raised normal, sunken pushed) */
|
||||
unsigned char bg_r = (bg_pixel >> 16) & 0xFF;
|
||||
unsigned char bg_g = (bg_pixel >> 8) & 0xFF;
|
||||
unsigned char bg_b = bg_pixel & 0xFF;
|
||||
uint32_t hi_c = 0xFF000000 | ((uint32_t)(bg_r + (255-bg_r)/3) << 16) |
|
||||
((uint32_t)(bg_g + (255-bg_g)/3) << 8) | (bg_b + (255-bg_b)/3);
|
||||
uint32_t lo_c = 0xFF000000 | ((uint32_t)(bg_r * 2/3) << 16) |
|
||||
((uint32_t)(bg_g * 2/3) << 8) | (bg_b * 2/3);
|
||||
uint32_t hi = pushed ? lo_c : hi_c;
|
||||
uint32_t lo = pushed ? hi_c : lo_c;
|
||||
for (int x = 0; x < bw; x++) { dst[x] = hi; dst[(bh-1) * dst_stride + x] = lo; }
|
||||
for (int y = 0; y < bh; y++) { dst[y * dst_stride] = hi; dst[y * dst_stride + bw - 1] = lo; }
|
||||
|
||||
/* Blit icon centered, using fill_fg color for opaque pixels */
|
||||
int ix = (bw - icon->width) / 2 + (pushed ? 1 : 0);
|
||||
int iy = (bh - icon->height) / 2 + (pushed ? 1 : 0);
|
||||
|
||||
for (int y = 0; y < icon->height; y++) {
|
||||
int dy = iy + y;
|
||||
if (dy < 0 || dy >= bh) continue;
|
||||
uint32_t *dst_row = dst + dy * dst_stride;
|
||||
for (int x = 0; x < icon->width; x++) {
|
||||
int dx = ix + x;
|
||||
if (dx < 0 || dx >= bw) continue;
|
||||
unsigned char a;
|
||||
if (icon->format == RRGBAFormat)
|
||||
a = icon->data[(y * icon->width + x) * 4 + 3];
|
||||
else
|
||||
a = 255;
|
||||
if (a == 0) continue;
|
||||
dst_row[dx] = fill_fg;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable and commit the button's own scene_buf */
|
||||
wlr_scene_buffer_set_buffer_with_damage(btn_fb->scene_buf, &btn_fb->base, NULL);
|
||||
wlr_scene_node_set_enabled(&btn_fb->scene_buf->node, true);
|
||||
wlr_scene_node_raise_to_top(&btn_fb->scene_buf->node);
|
||||
}
|
||||
|
||||
void wl_noop_netwm_init(WScreen *scr) { (void)scr; }
|
||||
void wl_noop_netwm_cleanup(WScreen *scr) { (void)scr; }
|
||||
void wl_noop_netwm_update_desktop(WScreen *scr) { (void)scr; }
|
||||
int wl_noop_netwm_get_current_desktop(WScreen *scr) { (void)scr; return -1; }
|
||||
void wl_netwm_update_opacity(WWindow *wwin)
|
||||
{
|
||||
if (!wwin->frame)
|
||||
return;
|
||||
|
||||
struct wl_frame_buf *fb = frame_buf_find(wwin->frame->core->window);
|
||||
if (!fb || !fb->scene_buf)
|
||||
return;
|
||||
|
||||
float alpha = 1.0f;
|
||||
if (wl_state.x_display && wwin->client_win) {
|
||||
WMNativeAtom type;
|
||||
int format;
|
||||
unsigned long items, rest;
|
||||
unsigned char *prop = NULL;
|
||||
WMNativeAtom opacity_atom = XInternAtom(wl_state.x_display,
|
||||
"_NET_WM_WINDOW_OPACITY", False);
|
||||
if (XGetWindowProperty(wl_state.x_display, (WNativeWindow)wwin->client_win,
|
||||
opacity_atom, 0L, 1L, False, AnyPropertyType,
|
||||
&type, &format, &items, &rest, &prop) == Success
|
||||
&& format == 32 && items == 1 && prop) {
|
||||
unsigned long val = *(unsigned long *)prop;
|
||||
alpha = (float)val / (float)0xFFFFFFFF;
|
||||
}
|
||||
if (prop)
|
||||
XFree(prop);
|
||||
}
|
||||
|
||||
wlr_scene_buffer_set_opacity(fb->scene_buf, alpha);
|
||||
|
||||
/* Apply to all child frame_bufs (titlebar buttons, resizebar) */
|
||||
struct wl_frame_buf *child;
|
||||
wl_list_for_each(child, &wl_state.frame_list, link) {
|
||||
if (child->parent_id == fb->id && child->scene_buf)
|
||||
wlr_scene_buffer_set_opacity(child->scene_buf, alpha);
|
||||
}
|
||||
|
||||
/* Apply to the client surface */
|
||||
struct wl_toplevel_view *v;
|
||||
wl_list_for_each(v, &wl_state.toplevel_list, link) {
|
||||
if (v->frame_id == fb->id && v->scene_node) {
|
||||
struct wlr_scene_node *node;
|
||||
wl_list_for_each(node, &v->scene_node->children, link) {
|
||||
if (node->type == WLR_SCENE_NODE_BUFFER)
|
||||
wlr_scene_buffer_set_opacity(
|
||||
wlr_scene_buffer_from_node(node), alpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
void wl_noop_netwm_update_actions(WWindow *wwin, int del) { (void)wwin; (void)del; }
|
||||
void wl_noop_netwm_check_client_hints(WWindow *wwin, int *layer, int *workspace)
|
||||
{ (void)wwin; (void)layer; (void)workspace; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue