wayland backend now doublebuffered!
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
All checks were successful
pyrite-dev/milsko/pipeline/head This commit looks good
This commit is contained in:
parent
d2cbe88cb3
commit
f0fc3fa174
9 changed files with 86 additions and 149 deletions
|
|
@ -261,7 +261,6 @@ if(MW_USE_WAYLAND)
|
|||
scan_wayland_protocol("unstable" "primary-selection" "-unstable-v1")
|
||||
scan_wayland_protocol("unstable" "pointer-constraints" "-unstable-v1")
|
||||
scan_wayland_protocol("unstable" "relative-pointer" "-unstable-v1")
|
||||
scan_wayland_protocol("staging" "fifo" "-v1")
|
||||
scan_wayland_protocol_from_file("wlr-layer-shell" "wlr-layer-shell-unstable-v1.xml")
|
||||
|
||||
target_sources(
|
||||
|
|
|
|||
|
|
@ -188,8 +188,10 @@ struct _MwLLCairo {
|
|||
struct _MwLLCommon common;
|
||||
|
||||
cairo_surface_t* front_cs;
|
||||
cairo_surface_t* front_cs_back;
|
||||
cairo_surface_t* back_cs;
|
||||
cairo_t* front_cairo;
|
||||
cairo_t* front_cairo_back;
|
||||
cairo_t* back_cairo;
|
||||
/* The cairo to actually use for draw operations. Typically is front_cairo, but wayland's MwLLBeginDraw can change this to the back_cairo so it can be used to draw window decorations. */
|
||||
cairo_t* selected_cairo;
|
||||
|
|
|
|||
|
|
@ -207,7 +207,6 @@ MwInline int wayland_load_funcs() {
|
|||
#include "Wayland/relative-pointer-client-protocol.h"
|
||||
#include "Wayland/xdg-toplevel-icon-client-protocol.h"
|
||||
#include "Wayland/wlr-layer-shell-client-protocol.h"
|
||||
#include "Wayland/fifo-client-protocol.h"
|
||||
#endif
|
||||
|
||||
typedef struct wayland_protocol {
|
||||
|
|
@ -266,7 +265,6 @@ struct _MwLLWaylandShmBuffer {
|
|||
struct wl_buffer* shm_buffer_back;
|
||||
struct wl_surface* surface;
|
||||
struct wl_output* output;
|
||||
struct wp_fifo_v1* fifo;
|
||||
|
||||
MwU8* buf;
|
||||
MwU8* buf_back;
|
||||
|
|
@ -436,8 +434,6 @@ struct _MwLLWayland {
|
|||
struct _MwLLWaylandShmBuffer backbuffer;
|
||||
struct _MwLLWaylandShmBuffer cursor;
|
||||
struct _MwLLWaylandShmBuffer* icon;
|
||||
MwBool fifo_wait;
|
||||
MwBool disable_fifo;
|
||||
|
||||
MwLLPixmap icon_pixmap;
|
||||
|
||||
|
|
@ -475,17 +471,6 @@ void MwLLWaylandBackbufferSetup(struct _MwLLWayland* wayland);
|
|||
/* Destroy the backbuffer */
|
||||
void MwLLWaylandBackbufferDestroy(struct _MwLLWayland* handle);
|
||||
|
||||
/* Bind a wp_fifo_v1 object to `buffer`'s surface, if wp_fifo_manager_v1 is available and it doesn't have one already. */
|
||||
void MwLLWaylandFifoSurfaceSetup(struct _MwLLWayland* wayland, struct _MwLLWaylandShmBuffer* buffer);
|
||||
/* Destroy `buffer`'s wp_fifo_v1 object, if any. */
|
||||
void MwLLWaylandFifoSurfaceDestroy(struct _MwLLWaylandShmBuffer* buffer);
|
||||
/* Commit `buffer`'s surface, constraining the update to the next display refresh via wp_fifo_v1 if bound. */
|
||||
void MwLLWaylandFifoCommit(struct _MwLLWaylandShmBuffer* buffer);
|
||||
|
||||
#ifdef MW_VULKAN
|
||||
#warning Wayland backend currently disabled by default when Vulkan enabled. Use with caution (MW_BACKEND=wayland to override).
|
||||
#endif
|
||||
|
||||
void MwLLWaylandBufferSetup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height);
|
||||
void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer);
|
||||
void MwLLWaylandBufferDestroy(struct _MwLLWaylandShmBuffer* buffer);
|
||||
|
|
@ -508,8 +493,6 @@ void MwLLWaylandClipboardRead(wl_clipboard_device_context_t* ctx, int clipboard_
|
|||
/* Flush Wayland events */
|
||||
void MwLLWaylandFlush(MwLL handle);
|
||||
|
||||
void MwLLWaylandCascadeChildren(MwLL handle);
|
||||
|
||||
/* Standard procedure before event callbacks in Wayland */
|
||||
#define WAYLAND_EVENT_OP_START(self)
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@ if (grep(/^wayland$/, @backends)) {
|
|||
scan_wayland_protocol("unstable", "primary-selection", "-unstable-v1");
|
||||
scan_wayland_protocol("unstable", "pointer-constraints", "-unstable-v1");
|
||||
scan_wayland_protocol("unstable", "relative-pointer", "-unstable-v1");
|
||||
scan_wayland_protocol("staging", "fifo", "-v1");
|
||||
scan_wayland_protocol_from_file("wlr-layer-shell",
|
||||
"wlr-layer-shell-unstable-v1.xml");
|
||||
|
||||
|
|
|
|||
|
|
@ -6,38 +6,38 @@ cairo_call_table_t cairo_call_tbl;
|
|||
|
||||
void MwLLCairoPolygon(struct _MwLLCairo handle, MwPoint* points, int points_count, MwLLColor color) {
|
||||
int i;
|
||||
cairo_set_source_rgba(handle.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
|
||||
cairo_new_path(handle.front_cairo);
|
||||
cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
|
||||
cairo_new_path(handle.front_cairo_back);
|
||||
for(i = 0; i < points_count; i++) {
|
||||
if(i == 0) {
|
||||
cairo_move_to(handle.front_cairo, points[i].x, points[i].y);
|
||||
cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y);
|
||||
} else {
|
||||
cairo_line_to(handle.front_cairo, points[i].x, points[i].y);
|
||||
cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y);
|
||||
}
|
||||
}
|
||||
cairo_close_path(handle.front_cairo);
|
||||
cairo_close_path(handle.front_cairo_back);
|
||||
|
||||
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill(handle.front_cairo);
|
||||
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_fill(handle.front_cairo_back);
|
||||
cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER);
|
||||
};
|
||||
|
||||
void MwLLCairoLine(struct _MwLLCairo handle, MwPoint* points, MwLLColor color) {
|
||||
int i;
|
||||
|
||||
cairo_set_antialias(handle.front_cairo, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_line_cap(handle.front_cairo, CAIRO_LINE_CAP_SQUARE);
|
||||
cairo_set_source_rgba(handle.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
|
||||
cairo_new_path(handle.front_cairo);
|
||||
cairo_set_antialias(handle.front_cairo_back, CAIRO_ANTIALIAS_NONE);
|
||||
cairo_set_line_cap(handle.front_cairo_back, CAIRO_LINE_CAP_SQUARE);
|
||||
cairo_set_source_rgba(handle.front_cairo_back, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0);
|
||||
cairo_new_path(handle.front_cairo_back);
|
||||
for(i = 0; i < 2; i++) {
|
||||
if(i == 0) {
|
||||
cairo_move_to(handle.front_cairo, points[i].x, points[i].y);
|
||||
cairo_move_to(handle.front_cairo_back, points[i].x, points[i].y);
|
||||
} else {
|
||||
cairo_line_to(handle.front_cairo, points[i].x, points[i].y);
|
||||
cairo_line_to(handle.front_cairo_back, points[i].x, points[i].y);
|
||||
}
|
||||
}
|
||||
cairo_close_path(handle.front_cairo);
|
||||
cairo_stroke(handle.front_cairo);
|
||||
cairo_close_path(handle.front_cairo_back);
|
||||
cairo_stroke(handle.front_cairo_back);
|
||||
};
|
||||
|
||||
MwLLPixmap MwLLCairoCreatePixmap(struct _MwLLCairo handle, unsigned char* data, int width, int height) {
|
||||
|
|
@ -88,7 +88,7 @@ void MwLLCairoDestroyPixmap(MwLLPixmap pixmap) {
|
|||
void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixmap) {
|
||||
cairo_t* c;
|
||||
cairo_surface_t* cs;
|
||||
cairo_t* selected_cairo = handle.selected_cairo ? handle.selected_cairo : handle.front_cairo;
|
||||
cairo_t* selected_cairo = handle.selected_cairo ? handle.selected_cairo : handle.front_cairo_back;
|
||||
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height);
|
||||
c = cairo_create(cs);
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ void MwLLCairoDrawPixmap(struct _MwLLCairo handle, MwRect* rect, MwLLPixmap pixm
|
|||
cairo_set_source_surface(c, pixmap->cairo.cs, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
|
||||
|
||||
cairo_set_operator(handle.front_cairo, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_operator(handle.front_cairo_back, CAIRO_OPERATOR_OVER);
|
||||
|
||||
cairo_paint(c);
|
||||
|
||||
|
|
@ -118,7 +118,9 @@ void MwLLCairoFrontSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU3
|
|||
} else {
|
||||
cairo->front_cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
||||
}
|
||||
cairo->front_cairo = cairo_create(cairo->front_cs);
|
||||
cairo->front_cs_back = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
||||
cairo->front_cairo_back = cairo_create(cairo->front_cs_back);
|
||||
cairo->front_cairo = cairo_create(cairo->front_cs);
|
||||
}
|
||||
|
||||
void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32 height) {
|
||||
|
|
@ -132,6 +134,7 @@ void MwLLCairoBackSetup(struct _MwLLCairo* cairo, MwU8* data, MwU32 width, MwU32
|
|||
|
||||
void MwLLCairoFrontDestroy(struct _MwLLCairo* cairo) {
|
||||
cairo_destroy(cairo->front_cairo);
|
||||
cairo_destroy(cairo->front_cairo_back);
|
||||
cairo_surface_destroy(cairo->front_cs);
|
||||
};
|
||||
void MwLLCairoBackDestroy(struct _MwLLCairo* cairo) {
|
||||
|
|
@ -169,7 +172,7 @@ static void MwLLDestroyImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
static void MwLLBeginDrawImpl(MwLL handle) {
|
||||
handle->cairo.selected_cairo = handle->cairo.front_cairo;
|
||||
handle->cairo.selected_cairo = handle->cairo.front_cairo_back;
|
||||
}
|
||||
static void MwLLEndDrawImpl(MwLL handle) {
|
||||
}
|
||||
|
|
@ -212,8 +215,8 @@ static void MwLLFreeColorImpl(MwLLColor color) {}
|
|||
|
||||
static MwBool lmao = MwFALSE;
|
||||
static int MwLLPendingImpl(MwLL handle) {
|
||||
lmao = !lmao;
|
||||
return lmao;
|
||||
lmao = !lmao;
|
||||
return lmao;
|
||||
}
|
||||
static void MwLLNextEventImpl(MwLL handle) {
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
|
|
@ -257,10 +260,10 @@ static void MwLLRaiseImpl(MwLL handle) {}
|
|||
static void MwLLClipImpl(MwLL handle, MwRect* rect) {}
|
||||
static void MwLLSetupDragAndDropImpl(MwLL handle) {}
|
||||
static int MwLLCairoCallInitImpl(void) {
|
||||
if(cairo_load_funcs() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
if(cairo_load_funcs() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#include "call.c"
|
||||
CALL(Cairo);
|
||||
|
|
|
|||
|
|
@ -2,39 +2,6 @@
|
|||
#include <sys/mman.h>
|
||||
#include "../../../external/stb_ds.h"
|
||||
|
||||
/* Bind a wp_fifo_v1 object to `buffer`'s surface, if wp_fifo_manager_v1 is available and it doesn't have one already. */
|
||||
void MwLLWaylandFifoSurfaceSetup(struct _MwLLWayland* wayland, struct _MwLLWaylandShmBuffer* buffer) {
|
||||
wayland_protocol_t* fifo_manager;
|
||||
|
||||
if(buffer->fifo || !buffer->surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
fifo_manager = shget(wayland->wl_protocol_map, wp_fifo_manager_v1_interface.name);
|
||||
if(!fifo_manager) {
|
||||
return;
|
||||
}
|
||||
|
||||
buffer->fifo = wp_fifo_manager_v1_get_fifo(fifo_manager->context, buffer->surface);
|
||||
}
|
||||
|
||||
/* Destroy `buffer`'s wp_fifo_v1 object, if any. */
|
||||
void MwLLWaylandFifoSurfaceDestroy(struct _MwLLWaylandShmBuffer* buffer) {
|
||||
if(buffer->fifo) {
|
||||
wp_fifo_v1_destroy(buffer->fifo);
|
||||
buffer->fifo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Commit `buffer`'s surface, constraining the update to the next display refresh via wp_fifo_v1 if bound. */
|
||||
void MwLLWaylandFifoCommit(struct _MwLLWaylandShmBuffer* buffer) {
|
||||
if(buffer->fifo) {
|
||||
wp_fifo_v1_set_barrier(buffer->fifo);
|
||||
wp_fifo_v1_wait_barrier(buffer->fifo);
|
||||
}
|
||||
wl_surface_commit(buffer->surface);
|
||||
}
|
||||
|
||||
void MwLLWaylandFramebufferSetup(struct _MwLLWayland* wayland) {
|
||||
MwLLWaylandBufferSetup(&wayland->framebuffer, wayland->ww, wayland->wh);
|
||||
|
||||
|
|
|
|||
|
|
@ -600,7 +600,6 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time
|
|||
|
||||
MwLLDispatch(currentlyHeldWidgets[i], move, &p);
|
||||
}
|
||||
MwLLWaylandCascadeChildren(self);
|
||||
}
|
||||
if(self->wayland.backbuffer.surface) {
|
||||
wl_pointer_set_cursor(self->wayland.pointer, self->wayland.pointer_serial, self->wayland.cursor.surface, 0, 0);
|
||||
|
|
|
|||
|
|
@ -225,11 +225,8 @@ void MwLLWaylandBufferUpdate(MwLL self, struct _MwLLWaylandShmBuffer* buffer) {
|
|||
// Yes this is needed every time, it's how we fix weston.
|
||||
if(self->wayland.configured)
|
||||
wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0);
|
||||
if(self->wayland.fifo_wait) {
|
||||
MwLLWaylandFifoCommit(buffer);
|
||||
} else {
|
||||
wl_surface_commit(buffer->surface);
|
||||
}
|
||||
|
||||
wl_surface_commit(buffer->surface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -278,9 +275,7 @@ static void setup_toplevel(MwLL r, int x, int y) {
|
|||
/* 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);
|
||||
MwLLWaylandFifoSurfaceSetup(&r->wayland, &r->wayland.framebuffer);
|
||||
MwLLWaylandFifoSurfaceSetup(&r->wayland, &r->wayland.backbuffer);
|
||||
r->wayland.toplevel->ssurface = wl_subcompositor_get_subsurface(r->wayland.toplevel->scompositor, r->wayland.framebuffer.surface, r->wayland.backbuffer.surface);
|
||||
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 =
|
||||
|
|
@ -356,8 +351,6 @@ static void destroy_toplevel(MwLL r) {
|
|||
* after this function returns, so every widget type that binds a seat (toplevel, popup,
|
||||
* layer surface) releases them the same way instead of leaking or double-freeing them. */
|
||||
|
||||
MwLLWaylandFifoSurfaceDestroy(&r->wayland.framebuffer);
|
||||
MwLLWaylandFifoSurfaceDestroy(&r->wayland.backbuffer);
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
|
||||
free(r->wayland.toplevel);
|
||||
|
|
@ -521,7 +514,6 @@ static void setup_popup(MwLL r, int x, int y, MwLL parent) {
|
|||
r->wayland.xkb_state = topmost_parent->wayland.xkb_state;
|
||||
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
MwLLWaylandFifoSurfaceSetup(&r->wayland, &r->wayland.framebuffer);
|
||||
|
||||
r->wayland.popup->xdg_surface =
|
||||
xdg_wm_base_get_xdg_surface(WAYLAND_GET_INTERFACE(r->wayland, xdg_wm_base)->context, r->wayland.framebuffer.surface);
|
||||
|
|
@ -563,8 +555,6 @@ static void destroy_popup(MwLL r) {
|
|||
|
||||
xdg_positioner_destroy(r->wayland.popup->xdg_positioner);
|
||||
|
||||
MwLLWaylandFifoSurfaceDestroy(&r->wayland.framebuffer);
|
||||
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
|
||||
wl_registry_destroy(r->wayland.registry);
|
||||
|
|
@ -648,7 +638,6 @@ static void setup_layer_surface(MwLL r, int x, int y, int width, int height) {
|
|||
r->wayland.xkb_context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
|
||||
r->wayland.framebuffer.surface = wl_compositor_create_surface(r->wayland.compositor);
|
||||
MwLLWaylandFifoSurfaceSetup(&r->wayland, &r->wayland.framebuffer);
|
||||
|
||||
r->wayland.layer_surface->surface = zwlr_layer_shell_v1_get_layer_surface(layer_shell, r->wayland.framebuffer.surface, NULL, ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY, "milsko-surfaces");
|
||||
|
||||
|
|
@ -679,8 +668,6 @@ static void destroy_layer_surface(MwLL r) {
|
|||
zxdg_decoration_manager_v1_destroy(dec->manager);
|
||||
}
|
||||
|
||||
MwLLWaylandFifoSurfaceDestroy(&r->wayland.framebuffer);
|
||||
|
||||
wl_surface_destroy(r->wayland.framebuffer.surface);
|
||||
|
||||
wl_compositor_destroy(r->wayland.compositor);
|
||||
|
|
@ -810,15 +797,15 @@ static void clip(MwLL handle) {
|
|||
handle->wayland.clipping_rect.height = my - cy;
|
||||
MwLLWaylandRegionSetup(handle);
|
||||
|
||||
cairo_reset_clip(handle->wayland.cairo.front_cairo);
|
||||
cairo_reset_clip(handle->wayland.cairo.front_cairo_back);
|
||||
if(handle->wayland.type == MwLL_WAYLAND_SUBLEVEL && !handle->wayland.is_toplevel) {
|
||||
cairo_rectangle(handle->wayland.cairo.front_cairo, cx - x, cy - y, mx - cx, my - cy);
|
||||
cairo_clip(handle->wayland.cairo.front_cairo);
|
||||
cairo_rectangle(handle->wayland.cairo.front_cairo_back, cx - x, cy - y, mx - cx, my - cy);
|
||||
cairo_clip(handle->wayland.cairo.front_cairo_back);
|
||||
}
|
||||
|
||||
if(handle->wayland.is_clipping) {
|
||||
cairo_rectangle(handle->wayland.cairo.front_cairo, handle->wayland.clip.x, handle->wayland.clip.y, handle->wayland.clip.width, handle->wayland.clip.height);
|
||||
cairo_clip(handle->wayland.cairo.front_cairo);
|
||||
cairo_rectangle(handle->wayland.cairo.front_cairo_back, handle->wayland.clip.x, handle->wayland.clip.y, handle->wayland.clip.width, handle->wayland.clip.height);
|
||||
cairo_clip(handle->wayland.cairo.front_cairo_back);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -933,22 +920,31 @@ static void draw_children(MwLL handle);
|
|||
static void draw_child(MwLL handle, MwLL child) {
|
||||
cairo_t* c;
|
||||
cairo_surface_t* cs;
|
||||
cairo_t* selected_cairo = handle->wayland.cairo.front_cairo;
|
||||
cairo_t* selected_cairo;
|
||||
MwLL topmost_parent = handle;
|
||||
|
||||
if(topmost_parent->wayland.type != MwLL_WAYLAND_POPUP) {
|
||||
while(topmost_parent->wayland.parent) {
|
||||
topmost_parent = topmost_parent->wayland.parent;
|
||||
}
|
||||
}
|
||||
|
||||
wl_surface_commit(child->wayland.framebuffer.surface);
|
||||
|
||||
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, child->wayland.ww, child->wayland.wh);
|
||||
c = cairo_create(cs);
|
||||
|
||||
cairo_set_source_surface(c, child->wayland.cairo.front_cs, 0, 0);
|
||||
cairo_set_source_surface(c, child->wayland.cairo.front_cs_back, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
|
||||
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_OVER);
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
|
||||
|
||||
cairo_paint(c);
|
||||
|
||||
cairo_set_source_surface(selected_cairo, cs, child->wayland.x, child->wayland.y);
|
||||
cairo_paint(selected_cairo);
|
||||
// printf("%d %d\n", child->wayland.x, child->wayland.y);
|
||||
|
||||
cairo_set_source_surface(handle->wayland.cairo.front_cairo_back, cs, child->wayland.x, child->wayland.y);
|
||||
cairo_paint(handle->wayland.cairo.front_cairo_back);
|
||||
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
|
|
@ -965,20 +961,25 @@ static void draw_children(MwLL handle) {
|
|||
handle->wayland.events_pending = MwFALSE;
|
||||
}
|
||||
|
||||
static void cascade_child(MwLL handle, MwLL child) {
|
||||
child->wayland.do_cascading_draw = 10;
|
||||
}
|
||||
static void frontbuffer_draw(MwLL handle) {
|
||||
cairo_t* c;
|
||||
cairo_surface_t* cs;
|
||||
|
||||
static void count_child(MwLL handle, MwLL child) {
|
||||
handle->wayland.cascading_child_num++;
|
||||
}
|
||||
cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, handle->wayland.ww, handle->wayland.wh);
|
||||
c = cairo_create(cs);
|
||||
|
||||
void MwLLWaylandCascadeChildren(MwLL handle) {
|
||||
handle->wayland.cascading_child_num = 0;
|
||||
MwLLWaylandChildrenIterate(handle, count_child);
|
||||
cairo_set_source_surface(c, handle->wayland.cairo.front_cs_back, 0, 0);
|
||||
cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST);
|
||||
|
||||
handle->wayland.do_cascading_draw = handle->wayland.cascading_child_num * 10;
|
||||
MwLLWaylandChildrenIterate(handle, cascade_child);
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_OVER);
|
||||
|
||||
cairo_paint(c);
|
||||
|
||||
cairo_set_source_surface(handle->wayland.cairo.front_cairo, cs, 0, 0);
|
||||
cairo_paint(handle->wayland.cairo.front_cairo);
|
||||
|
||||
cairo_destroy(c);
|
||||
cairo_surface_destroy(cs);
|
||||
}
|
||||
|
||||
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
|
||||
|
|
@ -1069,7 +1070,6 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
|
|||
}
|
||||
|
||||
static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
||||
|
||||
MwLLWaylandRegionInvalidate(handle);
|
||||
|
||||
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
||||
|
|
@ -1082,8 +1082,11 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) {
|
|||
/* toplevels cannot be moved */
|
||||
break;
|
||||
case MwLL_WAYLAND_SUBLEVEL:
|
||||
/* sublevels are drawn according to their own x/y */
|
||||
{
|
||||
if(handle->wayland.parent)
|
||||
MwLLForceRender(handle->wayland.parent);
|
||||
break;
|
||||
}
|
||||
case MwLL_WAYLAND_POPUP:
|
||||
xdg_positioner_set_anchor_rect(handle->wayland.popup->xdg_positioner, handle->wayland.parent->wayland.x, handle->wayland.parent->wayland.y, handle->wayland.ww, handle->wayland.wh);
|
||||
xdg_positioner_set_offset(handle->wayland.popup->xdg_positioner, x, y);
|
||||
|
|
@ -1171,16 +1174,15 @@ const float_color one = {.2627451, .37254902, .49411765};
|
|||
const float_color two = {.05490196, .17254902, .30588235};
|
||||
|
||||
static void MwLLBeginDrawImpl(MwLL handle) {
|
||||
|
||||
cairo_save(handle->wayland.cairo.front_cairo);
|
||||
cairo_set_source_rgba(handle->wayland.cairo.front_cairo, 0, 0, 0, 0);
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_rectangle(handle->wayland.cairo.front_cairo, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
cairo_fill(handle->wayland.cairo.front_cairo);
|
||||
cairo_restore(handle->wayland.cairo.front_cairo);
|
||||
cairo_save(handle->wayland.cairo.front_cairo_back);
|
||||
cairo_set_source_rgba(handle->wayland.cairo.front_cairo_back, 0, 0, 0, 0);
|
||||
cairo_set_operator(handle->wayland.cairo.front_cairo_back, CAIRO_OPERATOR_SOURCE);
|
||||
cairo_rectangle(handle->wayland.cairo.front_cairo_back, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
cairo_fill(handle->wayland.cairo.front_cairo_back);
|
||||
cairo_restore(handle->wayland.cairo.front_cairo_back);
|
||||
|
||||
if(handle->wayland.type != MwLL_WAYLAND_TOPLEVEL) {
|
||||
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo;
|
||||
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo_back;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1310,7 +1312,7 @@ static void MwLLBeginDrawImpl(MwLL handle) {
|
|||
}
|
||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
||||
}
|
||||
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo;
|
||||
handle->wayland.cairo.selected_cairo = handle->wayland.cairo.front_cairo_back;
|
||||
}
|
||||
|
||||
static void MwLLEndDrawImpl(MwLL handle) {
|
||||
|
|
@ -1320,7 +1322,9 @@ static void MwLLEndDrawImpl(MwLL handle) {
|
|||
}
|
||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||
|
||||
MwLLWaylandCascadeChildren(handle);
|
||||
if(handle->wayland.type != MwLL_WAYLAND_SUBLEVEL) {
|
||||
handle->wayland.do_cascading_draw = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1385,8 +1389,7 @@ static int MwLLPendingImpl(MwLL handle) {
|
|||
|
||||
if(handle->wayland.do_cascading_draw) {
|
||||
draw_children(handle);
|
||||
if(handle->wayland.do_cascading_draw > 0)
|
||||
handle->wayland.do_cascading_draw--;
|
||||
frontbuffer_draw(handle);
|
||||
}
|
||||
|
||||
handle->wayland.end_time = MwTimeGetTick();
|
||||
|
|
@ -1437,12 +1440,10 @@ static int MwLLPendingImpl(MwLL handle) {
|
|||
return pending;
|
||||
}
|
||||
|
||||
if(!handle->wayland.disable_fifo) handle->wayland.fifo_wait = MwTRUE;
|
||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||
if(handle->wayland.type == MwLL_WAYLAND_TOPLEVEL) {
|
||||
MwLLWaylandBufferUpdate(handle, &handle->wayland.backbuffer);
|
||||
}
|
||||
if(!handle->wayland.disable_fifo) handle->wayland.fifo_wait = MwFALSE;
|
||||
|
||||
return handle->wayland.force_render || handle->wayland.events_pending || pending;
|
||||
}
|
||||
|
|
@ -1458,11 +1459,9 @@ static void MwLLNextEventImpl(MwLL handle) {
|
|||
}
|
||||
|
||||
if(handle->wayland.force_render) {
|
||||
handle->wayland.fifo_wait = MwTRUE;
|
||||
MwLLDispatch(handle, draw, NULL);
|
||||
if(handle->wayland.configured) MwLLWaylandBufferUpdate(handle, &handle->wayland.framebuffer);
|
||||
handle->wayland.force_render = 0;
|
||||
handle->wayland.fifo_wait = MwFALSE;
|
||||
}
|
||||
if(handle->wayland.events_pending) {
|
||||
handle->wayland.events_pending = 0;
|
||||
|
|
@ -1559,7 +1558,6 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
|
|||
}
|
||||
|
||||
static void MwLLForceRenderImpl(MwLL handle) {
|
||||
|
||||
if(!handle->wayland.configured) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -1567,9 +1565,6 @@ static void MwLLForceRenderImpl(MwLL handle) {
|
|||
wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh);
|
||||
|
||||
handle->wayland.force_render = MwTRUE;
|
||||
if(handle->wayland.parent) {
|
||||
handle->wayland.parent->wayland.force_render = MwTRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
|
||||
|
|
@ -1919,14 +1914,9 @@ static int MwLLWaylandCallInitImpl(void) {
|
|||
} else {
|
||||
loadWayland |= (strcmp(mw_backend_env, "wayland") == 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: when vulkan is enabled, refuse to default to wayland. Remove this if I ever get Vulkan widget working with the new surfaces system. */
|
||||
#ifndef MW_VULKAN
|
||||
else if(getenv("WAYLAND_DISPLAY")) {
|
||||
} else if(getenv("WAYLAND_DISPLAY")) {
|
||||
loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef MW_OPENGL
|
||||
if(getenv("WSLENV") || getenv("WSL_DISTRO_NAME")) {
|
||||
|
|
|
|||
|
|
@ -240,11 +240,6 @@ static int wcreate(MwWidget handle) {
|
|||
waylandopengl_t* o = r = malloc(sizeof(*o));
|
||||
int gbm_format = 0;
|
||||
EGLConfig egl_configs[1024];
|
||||
MwWidget topmost_parent = handle;
|
||||
|
||||
/* Disable fifo waiting when we have an OpenGL widget */
|
||||
while(topmost_parent->parent) topmost_parent = topmost_parent->parent;
|
||||
topmost_parent->lowlevel->wayland.disable_fifo = MwTRUE;
|
||||
|
||||
memset(o, 0, sizeof(waylandopengl_t));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue