wayland: merge libdecor
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
Some checks failed
pyrite-dev/milsko/pipeline/head There was a failure building this commit
This commit is contained in:
parent
70147b2716
commit
7aad2af609
3 changed files with 202 additions and 124 deletions
|
|
@ -14,7 +14,13 @@
|
|||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <cairo/cairo.h>
|
||||
#include <pthread.h>
|
||||
#include <dbus/dbus.h>
|
||||
/* libdecor is included later on so that it's covered by the wayland dynloading. */
|
||||
struct libdecor_frame;
|
||||
struct libdecor_interface;
|
||||
struct libdecor_configuration;
|
||||
struct libdecor_frame_interface;
|
||||
enum libdecor_window_state;
|
||||
struct wl_surface;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -44,6 +50,8 @@ typedef struct wayland_call_table {
|
|||
void* lib;
|
||||
void* xkb_lib;
|
||||
void* cairo_lib;
|
||||
|
||||
void* libdecor_lib;
|
||||
#ifdef USE_DBUS
|
||||
MwLLDBusFuncTable dbus;
|
||||
MwBool has_dbus;
|
||||
|
|
@ -141,6 +149,20 @@ typedef struct wayland_call_table {
|
|||
void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t);
|
||||
void (*cairo_set_operator)(cairo_t* cr, cairo_operator_t op);
|
||||
|
||||
MwBool has_libdecor;
|
||||
struct libdecor* (*libdecor_new)(struct wl_display* display, struct libdecor_interface* iface);
|
||||
struct libdecor_state* (*libdecor_state_new)(int width, int height);
|
||||
void (*libdecor_frame_commit)(struct libdecor_frame* frame, struct libdecor_state* state, struct libdecor_configuration* configuration);
|
||||
void (*libdecor_state_free)(struct libdecor_state* state);
|
||||
struct libdecor_frame* (*libdecor_decorate)(struct libdecor* context, struct wl_surface* surface, struct libdecor_frame_interface* iface, void* user_data);
|
||||
void (*libdecor_frame_set_app_id)(struct libdecor_frame* frame, const char* app_id);
|
||||
void (*libdecor_frame_set_title)(struct libdecor_frame* frame, const char* title);
|
||||
void (*libdecor_frame_map)(struct libdecor_frame* frame);
|
||||
MwBool (*libdecor_configuration_get_content_size)(struct libdecor_configuration* configuration, struct libdecor_frame* frame, int* width, int* height);
|
||||
MwBool (*libdecor_configuration_get_window_state)(struct libdecor_configuration* configuration, enum libdecor_window_state* window_state);
|
||||
struct xdg_surface* (*libdecor_frame_get_xdg_surface)(struct libdecor_frame* frame);
|
||||
int (*libdecor_dispatch)(struct libdecor* context, int timeout);
|
||||
void (*libdecor_frame_translate_coordinate)(struct libdecor_frame* frame, int surface_x, int surface_y, int* frame_x, int* frame_y);
|
||||
} wayland_call_table_t;
|
||||
|
||||
extern wayland_call_table_t wl_call_tbl;
|
||||
|
|
@ -186,6 +208,17 @@ MwInline int wayland_load_funcs() {
|
|||
return 1; \
|
||||
};
|
||||
|
||||
/* i mean i pray if somebody is using thr wayland backend over apple/ios that actual decorations are supported. */
|
||||
#ifdef __APPLE__
|
||||
wl_call_tbl.libdecor_lib = MwDynamicOpen("libdecor-0.dylib");
|
||||
#else
|
||||
wl_call_tbl.libdecor_lib = MwDynamicOpen("libdecor-0.so");
|
||||
#endif
|
||||
wl_call_tbl.has_libdecor = (wl_call_tbl.libdecor_lib != NULL);
|
||||
if(!wl_call_tbl.libdecor_lib) {
|
||||
printf("(libdecor not found, window will not have any decorations.)\n");
|
||||
}
|
||||
|
||||
WAYLAND_FUNC(wl_display_dispatch)
|
||||
WAYLAND_FUNC(wl_display_dispatch_pending)
|
||||
WAYLAND_FUNC(wl_display_disconnect)
|
||||
|
|
@ -267,6 +300,28 @@ MwInline int wayland_load_funcs() {
|
|||
wl_call_tbl.has_dbus = MwLLDBusFuncSetup(&wl_call_tbl.dbus);
|
||||
#endif
|
||||
|
||||
if(wl_call_tbl.has_libdecor) {
|
||||
#define LIBDECOR_FUNC(x) \
|
||||
wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.libdecor_lib, #x); \
|
||||
if(!wl_call_tbl.x) { \
|
||||
printf("WARNING: Can't use libdecor because libdecor-1 doesn't export " #x ".\n"); \
|
||||
wl_call_tbl.has_libdecor = MwFALSE; \
|
||||
};
|
||||
|
||||
LIBDECOR_FUNC(libdecor_new);
|
||||
LIBDECOR_FUNC(libdecor_state_new);
|
||||
LIBDECOR_FUNC(libdecor_frame_commit);
|
||||
LIBDECOR_FUNC(libdecor_state_free);
|
||||
LIBDECOR_FUNC(libdecor_decorate);
|
||||
LIBDECOR_FUNC(libdecor_frame_set_app_id);
|
||||
LIBDECOR_FUNC(libdecor_frame_set_title);
|
||||
LIBDECOR_FUNC(libdecor_frame_map);
|
||||
LIBDECOR_FUNC(libdecor_configuration_get_content_size);
|
||||
LIBDECOR_FUNC(libdecor_configuration_get_window_state);
|
||||
LIBDECOR_FUNC(libdecor_frame_get_xdg_surface);
|
||||
LIBDECOR_FUNC(libdecor_dispatch);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -342,6 +397,8 @@ MwInline int wayland_load_funcs() {
|
|||
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
|
||||
#endif
|
||||
|
||||
#include <libdecor-0/libdecor.h>
|
||||
|
||||
typedef struct wayland_protocol {
|
||||
void* listener;
|
||||
void* context;
|
||||
|
|
@ -495,6 +552,11 @@ struct _MwLLWayland {
|
|||
MwLLDBusContext dbus;
|
||||
#endif
|
||||
|
||||
struct libdecor* decor;
|
||||
struct libdecor_frame* decor_frame;
|
||||
struct libdecor_interface* decor_interface;
|
||||
enum libdecor_window_state decor_state;
|
||||
|
||||
MwBool dark_theme_detection;
|
||||
MwU32 dark_theme;
|
||||
|
||||
|
|
@ -568,8 +630,6 @@ struct _MwLLWayland {
|
|||
cairo_surface_t* back_cs;
|
||||
cairo_t* front_cairo;
|
||||
cairo_t* back_cairo;
|
||||
/* The cairo to actually use for draw operations. Typically is front_cairo, but MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
|
||||
cairo_t* selected_cairo;
|
||||
};
|
||||
|
||||
struct _MwLLWaylandColor {
|
||||
|
|
@ -610,10 +670,10 @@ void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_
|
|||
void MwLLWaylandFlush(MwLL handle);
|
||||
|
||||
/* Standard procedure before event callbacks in Wayland */
|
||||
#define WAYLAND_EVENT_OP_START(self) pthread_mutex_lock(&self->wayland.eventsMutex);
|
||||
#define WAYLAND_EVENT_OP_START(self)
|
||||
|
||||
/* Footer for WAYLAND_EVENT_OP_START */
|
||||
#define WAYLAND_EVENT_OP_END(self) pthread_mutex_unlock(&self->wayland.eventsMutex);
|
||||
#define WAYLAND_EVENT_OP_END(self)
|
||||
|
||||
/* the two decoration manager constructs */
|
||||
typedef struct zxdg_decoration_manager_v1_context {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
|||
wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0);
|
||||
wl_surface_commit(wayland->framebuffer.surface);
|
||||
|
||||
MwLLWaylandHangUntilConfigured((MwLL)wayland);
|
||||
// MwLLWaylandHangUntilConfigured((MwLL)wayland);
|
||||
MwLLWaylandBufferUpdate((MwLL)wayland, &wayland->framebuffer);
|
||||
};
|
||||
void MwLLWaylandFramebufferDestroy(struct _MwLLWayland* wayland) {
|
||||
|
|
|
|||
|
|
@ -201,6 +201,96 @@ void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
/* shitdecor */
|
||||
static void libdecor_error(struct libdecor* context,
|
||||
enum libdecor_error error,
|
||||
const char* message) {
|
||||
printf("libdecor error (%d): %s\n", error, message);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_configure(struct libdecor_frame* frame,
|
||||
struct libdecor_configuration* configuration,
|
||||
void* user_data) {
|
||||
MwLL self = user_data;
|
||||
int width, height;
|
||||
enum libdecor_window_state window_state;
|
||||
struct libdecor_state* state;
|
||||
|
||||
if(!wl_call_tbl.libdecor_configuration_get_content_size(configuration, frame,
|
||||
&width, &height)) {
|
||||
width = self->wayland.ww;
|
||||
height = self->wayland.wh;
|
||||
}
|
||||
|
||||
width = (width == 0) ? 1 : width;
|
||||
height = (height == 0) ? 1 : height;
|
||||
|
||||
// region_invalidate(self);
|
||||
self->wayland.ww = width;
|
||||
self->wayland.wh = height;
|
||||
|
||||
if(self->wayland.resizing == 0) {
|
||||
MwLLWaylandFramebufferDestroy(&self->wayland);
|
||||
MwLLWaylandFramebufferSetup(&self->wayland);
|
||||
MwLLWaylandRegionSetup(self);
|
||||
MwLLDispatch(self, resize, NULL);
|
||||
|
||||
recursive_dispatch_resize(self);
|
||||
|
||||
if(self->wayland.pointer_constrained) {
|
||||
zwp_locked_pointer_v1_set_cursor_position_hint(self->wayland.locked_pointer, 0, CSD_BORDER_FRAME_TOP);
|
||||
wl_surface_commit(self->wayland.framebuffer.surface);
|
||||
}
|
||||
|
||||
self->wayland.resizing = 1;
|
||||
}
|
||||
|
||||
MwLLDispatch(self, draw, NULL);
|
||||
|
||||
if(!wl_call_tbl.libdecor_configuration_get_window_state(configuration,
|
||||
&window_state))
|
||||
window_state = LIBDECOR_WINDOW_STATE_NONE;
|
||||
|
||||
self->wayland.decor_state = window_state;
|
||||
|
||||
state = wl_call_tbl.libdecor_state_new(width, height);
|
||||
wl_call_tbl.libdecor_frame_commit(frame, state, configuration);
|
||||
wl_call_tbl.libdecor_state_free(state);
|
||||
|
||||
self->wayland.configured = MwTRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
handle_close(struct libdecor_frame* frame,
|
||||
void* user_data) {
|
||||
MwLL self = user_data;
|
||||
MwLLDispatch(self, close, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_commit(struct libdecor_frame* frame,
|
||||
void* user_data) {
|
||||
MwLL self = user_data;
|
||||
wl_surface_commit(self->wayland.framebuffer.surface);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_dismiss_popup(struct libdecor_frame* frame,
|
||||
const char* seat_name,
|
||||
void* user_data) {
|
||||
}
|
||||
|
||||
static struct libdecor_frame_interface libdecor_frame_iface = {
|
||||
handle_configure,
|
||||
handle_close,
|
||||
handle_commit,
|
||||
handle_dismiss_popup,
|
||||
};
|
||||
|
||||
static struct libdecor_interface libdecor_interface = {
|
||||
libdecor_error};
|
||||
|
||||
/* Toplevel setup function */
|
||||
static void setup_toplevel(MwLL r, int x, int y) {
|
||||
r->wayland.type = MwLL_WAYLAND_TOPLEVEL;
|
||||
|
|
@ -234,15 +324,14 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
|
||||
r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
/* Create a wl_surface, a xdg_surface and a xdg_toplevel */
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
r->wayland.backbuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface);
|
||||
wl_subsurface_set_desync(r->wayland.toplevel->ssurface);
|
||||
|
||||
r->wayland.toplevel->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.backbuffer.surface);
|
||||
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
||||
if(r->wayland.has_decorations) {
|
||||
r->wayland.toplevel->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
||||
r->wayland.toplevel->xdg_top_level = xdg_surface_get_toplevel(r->wayland.toplevel->xdg_surface);
|
||||
}
|
||||
|
||||
/* setup mandatory listeners */
|
||||
r->wayland.toplevel->xdg_surface_listener.configure = xdg_surface_configure;
|
||||
|
|
@ -250,16 +339,26 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
r->wayland.toplevel->xdg_toplevel_listener.configure = xdg_toplevel_configure;
|
||||
r->wayland.toplevel->xdg_toplevel_listener.close = xdg_toplevel_close;
|
||||
|
||||
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
||||
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
||||
r);
|
||||
if(r->wayland.has_decorations) {
|
||||
xdg_surface_add_listener(r->wayland.toplevel->xdg_surface, &r->wayland.toplevel->xdg_surface_listener, r);
|
||||
xdg_toplevel_add_listener(r->wayland.toplevel->xdg_top_level, &r->wayland.toplevel->xdg_toplevel_listener,
|
||||
r);
|
||||
|
||||
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko App");
|
||||
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
||||
xdg_toplevel_set_title(r->wayland.toplevel->xdg_top_level, "Milsko App");
|
||||
xdg_toplevel_set_app_id(r->wayland.toplevel->xdg_top_level, "MilskoWaylandApp");
|
||||
} else {
|
||||
r->wayland.decor = wl_call_tbl.libdecor_new(r->wayland.display, &libdecor_interface);
|
||||
r->wayland.decor_frame = wl_call_tbl.libdecor_decorate(r->wayland.decor, r->wayland.framebuffer.surface,
|
||||
&libdecor_frame_iface, r);
|
||||
wl_call_tbl.libdecor_frame_set_app_id(r->wayland.decor_frame, "milsko-app");
|
||||
wl_call_tbl.libdecor_frame_set_title(r->wayland.decor_frame, "Milsko App");
|
||||
wl_call_tbl.libdecor_frame_map(r->wayland.decor_frame);
|
||||
}
|
||||
|
||||
/* Perform the initial commit and wait for the first configure event */
|
||||
wl_surface_commit(r->wayland.backbuffer.surface);
|
||||
wl_surface_commit(r->wayland.framebuffer.surface);
|
||||
wl_surface_commit(r->wayland.backbuffer.surface);
|
||||
|
||||
while(!r->wayland.configured) {
|
||||
event_loop(r);
|
||||
}
|
||||
|
|
@ -273,8 +372,6 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
|
||||
zxdg_toplevel_decoration_v1_set_mode(
|
||||
dec->decoration, ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
} else {
|
||||
wl_subsurface_set_position(r->wayland.toplevel->ssurface, CSD_BORDER_FRAME_LEFT, CSD_BORDER_FRAME_TOP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -406,6 +503,7 @@ struct xdg_popup_listener popup_listener = {
|
|||
/* Popup setup function */
|
||||
static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
||||
struct xdg_surface* xdg_surface;
|
||||
struct xdg_surface* parent_xdg_surface;
|
||||
MwLL topmost_parent = r->wayland.parent;
|
||||
|
||||
r->wayland.type = MwLL_WAYLAND_POPUP;
|
||||
|
|
@ -437,7 +535,7 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
|||
|
||||
/* check now if we have decorations so that everything else can act accordingly */
|
||||
if(shget(r->wayland.wl_protocol_map, zxdg_decoration_manager_v1_interface.name) != NULL) {
|
||||
r->wayland.has_decorations = MwTRUE;
|
||||
// r->wayland.has_decorations = MwTRUE;
|
||||
}
|
||||
|
||||
r->wayland.popup->xdg_wm_base = WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context;
|
||||
|
|
@ -455,16 +553,20 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
|||
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
|
||||
if(r->wayland.has_decorations) {
|
||||
parent_xdg_surface = topmost_parent->wayland.toplevel->xdg_surface;
|
||||
} else {
|
||||
parent_xdg_surface = wl_call_tbl.libdecor_frame_get_xdg_surface(topmost_parent->wayland.decor_frame);
|
||||
}
|
||||
|
||||
r->wayland.popup->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
||||
|
||||
r->wayland.popup->xdg_popup = xdg_surface_get_popup(
|
||||
r->wayland.popup->xdg_surface,
|
||||
xdg_surface,
|
||||
parent_xdg_surface,
|
||||
r->wayland.popup->xdg_positioner);
|
||||
|
||||
uint32_t ver = wl_proxy_get_version((struct wl_proxy*)r->wayland.popup->xdg_popup);
|
||||
|
||||
xdg_popup_add_listener(r->wayland.popup->xdg_popup, &popup_listener, r);
|
||||
|
||||
r->wayland.popup->xdg_surface_listener.configure = xdg_surface_configure;
|
||||
|
|
@ -783,7 +885,11 @@ static void actually_set_wh(MwLL handle) {
|
|||
MwLLWaylandRegionInvalidate(handle);
|
||||
|
||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL && handle->wayland.configured) {
|
||||
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
if(handle->wayland.has_decorations) {
|
||||
xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
} else {
|
||||
xdg_surface_set_window_geometry(wl_call_tbl.libdecor_frame_get_xdg_surface(handle->wayland.decor_frame), 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
}
|
||||
}
|
||||
|
||||
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && handle->wayland.configured && !handle->wayland.dispatching_resize) {
|
||||
|
|
@ -831,101 +937,6 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) {
|
|||
}
|
||||
|
||||
static void MwLLBeginDrawImpl(MwLL handle) {
|
||||
cairo_save(handle->wayland.front_cairo);
|
||||
cairo_set_source_rgba(handle->wayland.front_cairo, 0, 0, 0, 0);
|
||||
cairo_set_operator(handle->wayland.front_cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_rectangle(handle->wayland.front_cairo, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
cairo_fill(handle->wayland.front_cairo);
|
||||
cairo_restore(handle->wayland.front_cairo);
|
||||
|
||||
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
||||
handle->wayland.selected_cairo = handle->wayland.front_cairo;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!handle->wayland.has_decorations) {
|
||||
int x;
|
||||
MwU32 w = handle->wayland.ww + CSD_BORDER_FRAME_LEFT + CSD_BORDER_FRAME_RIGHT;
|
||||
MwU32 h = handle->wayland.wh + CSD_BORDER_FRAME_TOP + CSD_BORDER_FRAME_BOTTOM;
|
||||
cairo_set_line_width(handle->wayland.back_cairo, 4.0);
|
||||
for(x = 0; x < w; x++) {
|
||||
float placeholder = (float)x / (float)w;
|
||||
cairo_set_source_rgb(handle->wayland.back_cairo, placeholder, 0.25, 0.25);
|
||||
|
||||
cairo_move_to(handle->wayland.back_cairo, w - x, 0);
|
||||
cairo_line_to(handle->wayland.back_cairo, w - x, CSD_BORDER_FRAME_TOP);
|
||||
cairo_stroke(handle->wayland.back_cairo);
|
||||
|
||||
cairo_move_to(handle->wayland.back_cairo, x, CSD_BORDER_FRAME_TOP);
|
||||
cairo_line_to(handle->wayland.back_cairo, x, h);
|
||||
cairo_stroke(handle->wayland.back_cairo);
|
||||
}
|
||||
cairo_set_source_rgba(handle->wayland.back_cairo, 1, 1, 1, 0.5);
|
||||
cairo_move_to(handle->wayland.back_cairo, 0, 0);
|
||||
cairo_line_to(handle->wayland.back_cairo, 0, h);
|
||||
cairo_stroke(handle->wayland.back_cairo);
|
||||
cairo_move_to(handle->wayland.back_cairo, 0, 0);
|
||||
cairo_line_to(handle->wayland.back_cairo, w, 0);
|
||||
cairo_stroke(handle->wayland.back_cairo);
|
||||
|
||||
cairo_set_source_rgba(handle->wayland.back_cairo, 0, 0, 0, 0.5);
|
||||
cairo_move_to(handle->wayland.back_cairo, 0, h);
|
||||
cairo_line_to(handle->wayland.back_cairo, w, h);
|
||||
cairo_stroke(handle->wayland.back_cairo);
|
||||
cairo_move_to(handle->wayland.back_cairo, w, 0);
|
||||
cairo_line_to(handle->wayland.back_cairo, w, h);
|
||||
cairo_stroke(handle->wayland.back_cairo);
|
||||
|
||||
if(strlen(handle->wayland.title) != 0) {
|
||||
int y, x;
|
||||
int i = 0, sx = 0, sy = 0;
|
||||
int tw, th;
|
||||
unsigned char* px;
|
||||
MwRect r;
|
||||
MwLLPixmap p;
|
||||
tw = strlen(handle->wayland.title) * 7;
|
||||
th = 14;
|
||||
px = malloc(tw * th * 4);
|
||||
assert(px);
|
||||
|
||||
memset(px, 0, tw * th * 4);
|
||||
|
||||
handle->wayland.selected_cairo = handle->wayland.back_cairo;
|
||||
|
||||
while(handle->wayland.title[i]) {
|
||||
int out;
|
||||
i += MwUTF8ToUTF32(handle->wayland.title + i, &out);
|
||||
|
||||
if(out > 0xff) {
|
||||
out = 0;
|
||||
}
|
||||
|
||||
for(y = 0; y < 14; y++) {
|
||||
for(x = 0; x < 7; x++) {
|
||||
unsigned char* ppx = &px[((sy + y) * tw + sx + x) * 4];
|
||||
int col = MwFontData[out].data[y] & (1 << ((7 - 1) - x)) ? 255 : 0;
|
||||
ppx[0] = col;
|
||||
ppx[1] = col;
|
||||
ppx[2] = col;
|
||||
ppx[3] = col;
|
||||
}
|
||||
}
|
||||
sx += 7;
|
||||
}
|
||||
|
||||
p = MwLLCreatePixmap(handle, px, tw, th);
|
||||
r.x = 5;
|
||||
r.y = 5;
|
||||
r.width = tw;
|
||||
r.height = th;
|
||||
|
||||
MwLLDrawPixmap(handle, &r, p);
|
||||
MwLLDestroyPixmap(p);
|
||||
free(px);
|
||||
}
|
||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
||||
}
|
||||
handle->wayland.selected_cairo = handle->wayland.front_cairo;
|
||||
}
|
||||
|
||||
static void MwLLEndDrawImpl(MwLL handle) {
|
||||
|
|
@ -1074,6 +1085,10 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
}
|
||||
}
|
||||
|
||||
if(handle->wayland.decor) {
|
||||
wl_call_tbl.libdecor_dispatch(handle->wayland.decor, 0);
|
||||
}
|
||||
|
||||
if(handle->wayland.force_render) {
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||
|
|
@ -1086,7 +1101,11 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
|
||||
static void MwLLSetTitleImpl(MwLL handle, const char* title) {
|
||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
|
||||
if(handle->wayland.has_decorations) {
|
||||
xdg_toplevel_set_title(handle->wayland.toplevel->xdg_top_level, title);
|
||||
} else {
|
||||
wl_call_tbl.libdecor_frame_set_title(handle->wayland.decor_frame, title);
|
||||
}
|
||||
}
|
||||
if(!handle->wayland.has_decorations) {
|
||||
strncpy(handle->wayland.title, title, 255);
|
||||
|
|
@ -1143,7 +1162,6 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) {
|
|||
static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||
cairo_t* c;
|
||||
cairo_surface_t* cs;
|
||||
cairo_t* selected_cairo = handle->wayland.selected_cairo ? handle->wayland.selected_cairo : handle->wayland.front_cairo;
|
||||
|
||||
if(rect->width <= 0 || rect->height <= 0 || pixmap->common.width <= 0 || pixmap->common.height <= 0) return;
|
||||
if(rect->width >= INT16_MAX) rect->width = INT16_MAX;
|
||||
|
|
@ -1163,8 +1181,8 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
|
|||
|
||||
cairo_paint(c);
|
||||
|
||||
cairo_set_source_surface(selected_cairo, cs, rect->x, rect->y);
|
||||
cairo_paint(selected_cairo);
|
||||
cairo_set_source_surface(handle->wayland.front_cairo, cs, rect->x, rect->y);
|
||||
cairo_paint(handle->wayland.front_cairo);
|
||||
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue