From 6f6b08c0f56469fb4003bbf2613a6b5dab6bb337 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 14:18:13 -0700 Subject: [PATCH 01/14] wayland: start getting rid of cairo in favor of pixman --- include/Mw/LowLevel/Wayland.h | 146 ++-------------------- pl/rules.pl | 3 + src/backend/wayland.c | 224 +++++++++++++++------------------- src/backend/x11.c | 10 +- 4 files changed, 113 insertions(+), 270 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 7b31bd7..5ebba33 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -6,6 +6,7 @@ #ifndef __MW_LOWLEVEL_WAYLAND_H__ #define __MW_LOWLEVEL_WAYLAND_H__ +#include "pixman.h" #include #include #include @@ -34,7 +35,6 @@ struct _MwLLWayland; typedef struct wayland_call_table { void* lib; void* xkb_lib; - void* cairo_lib; #if WAYLAND_LOAD_OPENGL #endif @@ -66,64 +66,6 @@ typedef struct wayland_call_table { xkb_layout_index_t (*xkb_state_key_get_layout)(struct xkb_state* state, xkb_keycode_t key); void (*xkb_keymap_unref)(struct xkb_keymap* keymap); - void (*cairo_set_line_width)(cairo_t* cr, - double width); - void (*cairo_scale)(cairo_t* cr, - double sx, - double sy); - cairo_t* (*cairo_create)(cairo_surface_t* target); - void (*cairo_move_to)(cairo_t* cr, - double x, - double y); - - void (*cairo_rectangle)(cairo_t* cr, - double x, - double y, - double width, - double height); - void (*cairo_new_path)(cairo_t* cr); - void (*cairo_set_line_cap)(cairo_t* cr, - cairo_line_cap_t line_cap); - void (*cairo_set_source_rgba)(cairo_t* cr, - double red, - double green, - double blue, - double alpha); - void (*cairo_set_source_rgb)(cairo_t* cr, - double red, - double green, - double blue); - void (*cairo_reset_clip)(cairo_t* cr); - unsigned char* (*cairo_image_surface_get_data)(cairo_surface_t* surface); - void (*cairo_line_to)(cairo_t* cr, - double x, - double y); - void (*cairo_surface_destroy)(cairo_surface_t* surface); - cairo_surface_t* (*cairo_image_surface_create_for_data)(unsigned char* data, - cairo_format_t format, - int width, - int height, - int stride); - cairo_surface_t* (*cairo_image_surface_create)(cairo_format_t format, - int width, - int height); - void (*cairo_destroy)(cairo_t* cr); - cairo_pattern_t* (*cairo_get_source)(cairo_t* cr); - void (*cairo_close_path)(cairo_t* cr); - void (*cairo_paint)(cairo_t* cr); - void (*cairo_surface_flush)(cairo_surface_t* surface); - void (*cairo_clip)(cairo_t* cr); - void (*cairo_surface_mark_dirty)(cairo_surface_t* surface); - void (*cairo_stroke)(cairo_t* cr); - void (*cairo_set_source_surface)(cairo_t* cr, - cairo_surface_t* surface, - double x, - double y); - void (*cairo_fill)(cairo_t* cr); - void (*cairo_pattern_set_filter)(cairo_pattern_t* pattern, - cairo_filter_t filter); - void (*cairo_set_antialias)(cairo_t*, cairo_antialias_t); - } wayland_call_table_t; extern wayland_call_table_t wl_call_tbl; @@ -140,11 +82,7 @@ MwInline int wayland_load_funcs() { printf("(libxkbcommon.so not found, cannot use Wayland backend.)\n"); return 1; } - wl_call_tbl.cairo_lib = MwDynamicOpen("libcairo.so"); - if(!wl_call_tbl.cairo_lib) { - printf("(libcairo.so not found, cannot use Wayland backend.)\n"); - return 1; - } + #define WAYLAND_FUNC(x) \ wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.lib, #x); \ if(!wl_call_tbl.x) { \ @@ -187,42 +125,6 @@ MwInline int wayland_load_funcs() { XKB_FUNC(xkb_state_key_get_layout) #undef XKB_FUNC -#define CAIRO_FUNC(x) \ - wl_call_tbl.x = MwDynamicSymbol(wl_call_tbl.cairo_lib, #x); \ - if(!wl_call_tbl.x) { \ - printf("WARNING: Could use Wayland backend if " #x " was found. Do you have libcairo?\n"); \ - return 1; \ - }; - - CAIRO_FUNC(cairo_set_line_width); - CAIRO_FUNC(cairo_scale); - CAIRO_FUNC(cairo_create); - CAIRO_FUNC(cairo_move_to); - CAIRO_FUNC(cairo_rectangle); - CAIRO_FUNC(cairo_new_path); - CAIRO_FUNC(cairo_set_line_cap); - CAIRO_FUNC(cairo_set_antialias); - CAIRO_FUNC(cairo_set_source_rgba); - CAIRO_FUNC(cairo_set_source_rgb); - CAIRO_FUNC(cairo_reset_clip); - CAIRO_FUNC(cairo_image_surface_get_data); - CAIRO_FUNC(cairo_line_to); - CAIRO_FUNC(cairo_surface_destroy); - CAIRO_FUNC(cairo_image_surface_create_for_data); - CAIRO_FUNC(cairo_image_surface_create); - CAIRO_FUNC(cairo_destroy); - CAIRO_FUNC(cairo_get_source); - CAIRO_FUNC(cairo_close_path); - CAIRO_FUNC(cairo_paint); - CAIRO_FUNC(cairo_surface_flush); - CAIRO_FUNC(cairo_clip); - CAIRO_FUNC(cairo_surface_mark_dirty); - CAIRO_FUNC(cairo_stroke); - CAIRO_FUNC(cairo_set_source_surface); - CAIRO_FUNC(cairo_fill); - CAIRO_FUNC(cairo_pattern_set_filter); -#undef CAIRO_FUNC - return 0; } @@ -251,34 +153,6 @@ MwInline int wayland_load_funcs() { #define xkb_keymap_key_get_syms_by_level wl_call_tbl.xkb_keymap_key_get_syms_by_level #define xkb_state_key_get_layout wl_call_tbl.xkb_state_key_get_layout -#define cairo_set_line_width wl_call_tbl.cairo_set_line_width -#define cairo_scale wl_call_tbl.cairo_scale -#define cairo_create wl_call_tbl.cairo_create -#define cairo_move_to wl_call_tbl.cairo_move_to -#define cairo_rectangle wl_call_tbl.cairo_rectangle -#define cairo_new_path wl_call_tbl.cairo_new_path -#define cairo_set_line_cap wl_call_tbl.cairo_set_line_cap -#define cairo_set_antialias wl_call_tbl.cairo_set_antialias -#define cairo_set_source_rgba wl_call_tbl.cairo_set_source_rgba -#define cairo_set_source_rgb wl_call_tbl.cairo_set_source_rgb -#define cairo_reset_clip wl_call_tbl.cairo_reset_clip -#define cairo_image_surface_get_data wl_call_tbl.cairo_image_surface_get_data -#define cairo_line_to wl_call_tbl.cairo_line_to -#define cairo_surface_destroy wl_call_tbl.cairo_surface_destroy -#define cairo_image_surface_create_for_data wl_call_tbl.cairo_image_surface_create_for_data -#define cairo_image_surface_create wl_call_tbl.cairo_image_surface_create -#define cairo_destroy wl_call_tbl.cairo_destroy -#define cairo_get_source wl_call_tbl.cairo_get_source -#define cairo_close_path wl_call_tbl.cairo_close_path -#define cairo_paint wl_call_tbl.cairo_paint -#define cairo_surface_flush wl_call_tbl.cairo_surface_flush -#define cairo_clip wl_call_tbl.cairo_clip -#define cairo_surface_mark_dirty wl_call_tbl.cairo_surface_mark_dirty -#define cairo_stroke wl_call_tbl.cairo_stroke -#define cairo_set_source_surface wl_call_tbl.cairo_set_source_surface -#define cairo_fill wl_call_tbl.cairo_fill -#define cairo_pattern_set_filter wl_call_tbl.cairo_pattern_set_filter - #ifndef WL_PROTOCOLS_DEFINED #define WL_PROTOCOLS_DEFINED #include "Wayland/wayland-core-protocol.h" @@ -347,12 +221,15 @@ struct _MwLLWaylandShmBuffer { struct wl_surface* surface; struct wl_output* output; - MwU8* buf; - MwU8* buf_back; + MwU32* buf; + MwU32* buf_back; MwU64 buf_size; int fd; int fd_back; MwBool setup; + + pixman_image_t* pixman_fb_front; + pixman_image_t* pixman_fb_back; }; enum _MwLLWaylandType { @@ -493,13 +370,6 @@ struct _MwLLWayland { uint32_t last_time; MwBool moving; - - cairo_surface_t* front_cs; - 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 { @@ -509,7 +379,7 @@ struct _MwLLWaylandColor { struct _MwLLWaylandPixmap { struct _MwLLCommonPixmap common; - cairo_surface_t* cs; + pixman_image_t* img; }; #endif diff --git a/pl/rules.pl b/pl/rules.pl index bf18575..46d9da9 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -38,6 +38,9 @@ if (grep(/^wayland$/, @backends)) { add_cflags("-DWAYLAND_LOAD_OPENGL"); } + add_cflags("-I/usr/include/pixman-1"); + add_libs("-lpixman-1"); + scan_wayland_protocol_core(); scan_wayland_protocol("stable", "xdg-shell", ""); scan_wayland_protocol("stable", "viewporter", ""); diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 0bd23a6..c9a06b0 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -4,6 +4,7 @@ #include #include "../../external/stb_ds.h" +#include "pixman.h" /* TODO: find out what FreeBSD and such wants us to include */ #ifdef __FreeBSD__ @@ -1264,7 +1265,7 @@ static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); // Yes this is needed every time, it's how we fix weston. wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); - wl_surface_commit(buffer->surface); + wl_surface_commit(buffer->surface); } static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU32 height) { @@ -1272,7 +1273,7 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3 char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; char temp_name_back[] = "/tmp/milsko-wl-shm-back-XXXXXX"; - buffer->buf_size = width * height * 4; + buffer->buf_size = (width * height * 4) * sizeof(MwU32); buffer->fd = mkstemp(temp_name); buffer->fd_back = mkstemp(temp_name_back); @@ -1315,7 +1316,15 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3 } buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); buffer->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); - buffer->setup = MwTRUE; + + pixman_color_t col = {0, 0, 0, 0xffff}; + + buffer->pixman_fb_front = pixman_image_create_bits(PIXMAN_a8b8g8r8, + width, height, buffer->buf, stride); + buffer->pixman_fb_back = pixman_image_create_bits(PIXMAN_a8b8g8r8, + width, height, buffer->buf_back, stride); + + buffer->setup = MwTRUE; } static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) { @@ -1328,15 +1337,15 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) { if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back); close(buffer->fd); close(buffer->fd_back); + pixman_image_unref(buffer->pixman_fb_front); + pixman_image_unref(buffer->pixman_fb_back); + buffer->setup = MwFALSE; } static void framebuffer_setup(struct _MwLLWayland* wayland) { buffer_setup(&wayland->framebuffer, wayland->ww, wayland->wh); - wayland->front_cs = cairo_image_surface_create_for_data(wayland->framebuffer.buf_back, CAIRO_FORMAT_ARGB32, wayland->ww, wayland->wh, 4 * wayland->ww); - wayland->front_cairo = cairo_create(wayland->front_cs); - memset(wayland->framebuffer.buf_back, 0, wayland->framebuffer.buf_size); wl_surface_attach(wayland->framebuffer.surface, wayland->framebuffer.shm_buffer, 0, 0); wl_surface_commit(wayland->framebuffer.surface); @@ -1346,8 +1355,6 @@ static void framebuffer_setup(struct _MwLLWayland* wayland) { }; static void framebuffer_destroy(struct _MwLLWayland* wayland) { buffer_destroy(&wayland->framebuffer); - cairo_destroy(wayland->front_cairo); - cairo_surface_destroy(wayland->front_cs); }; static void backbuffer_setup(struct _MwLLWayland* wayland) { @@ -1362,9 +1369,6 @@ static void backbuffer_setup(struct _MwLLWayland* wayland) { } buffer_setup(&wayland->backbuffer, w, h); - wayland->back_cs = cairo_image_surface_create_for_data(wayland->backbuffer.buf_back, CAIRO_FORMAT_ARGB32, w, h, 4 * w); - wayland->back_cairo = cairo_create(wayland->back_cs); - memset(wayland->backbuffer.buf_back, 255, wayland->backbuffer.buf_size); wl_surface_attach(wayland->backbuffer.surface, wayland->backbuffer.shm_buffer, 0, 0); wl_surface_commit(wayland->backbuffer.surface); @@ -1373,8 +1377,6 @@ static void backbuffer_setup(struct _MwLLWayland* wayland) { }; static void backbuffer_destroy(struct _MwLLWayland* wayland) { buffer_destroy(&wayland->backbuffer); - cairo_destroy(wayland->back_cairo); - cairo_surface_destroy(wayland->back_cs); }; static void region_invalidate(MwLL handle) { @@ -1751,15 +1753,6 @@ static void destroy_popup(MwLL r) { r->wayland.configured = MwFALSE; } -static void clip(MwLL handle) { - MwLL parent = handle->wayland.parent; - if(parent && handle->wayland.type == MWLL_WAYLAND_SUBLEVEL) { - cairo_reset_clip(handle->wayland.front_cairo); - cairo_rectangle(handle->wayland.front_cairo, 0, 0, (parent->wayland.ww + handle->wayland.x), (parent->wayland.wh + handle->wayland.y)); - cairo_clip(handle->wayland.front_cairo); - } -} - static void wl_logger(const char* fmt, va_list args) { vprintf(fmt, args); raise(SIGTRAP); @@ -1966,7 +1959,7 @@ refresh: static void MwLLBeginDrawImpl(MwLL handle) { if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) { - handle->wayland.selected_cairo = handle->wayland.front_cairo; + // handle->wayland.selected_cairo = handle->wayland.front_cairo; return; } @@ -1974,34 +1967,34 @@ static void MwLLBeginDrawImpl(MwLL handle) { 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_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, 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_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); + // 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; @@ -2017,7 +2010,7 @@ static void MwLLBeginDrawImpl(MwLL handle) { memset(px, 0, tw * th * 4); - handle->wayland.selected_cairo = handle->wayland.back_cairo; + // handle->wayland.selected_cairo = handle->wayland.back_cairo; while(handle->wayland.title[i]) { int out; @@ -2052,7 +2045,7 @@ static void MwLLBeginDrawImpl(MwLL handle) { } update_buffer(handle, &handle->wayland.backbuffer); } - handle->wayland.selected_cairo = handle->wayland.front_cairo; + // handle->wayland.selected_cairo = handle->wayland.front_cairo; } static void MwLLEndDrawImpl(MwLL handle) { @@ -2065,44 +2058,43 @@ static void MwLLEndDrawImpl(MwLL handle) { } static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - int i; + int i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * points_count); + pixman_image_t* image = pixman_image_create_solid_fill(&col); + memset(triangles, 0, sizeof(pixman_triangle_t) * points_count); - clip(handle); - - cairo_set_source_rgba(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); - cairo_new_path(handle->wayland.front_cairo); - for(i = 0; i < points_count; i++) { - if(i == 0) { - cairo_move_to(handle->wayland.front_cairo, points[i].x, points[i].y); - } else { - cairo_line_to(handle->wayland.front_cairo, points[i].x, points[i].y); - } + for(i = 0; i < points_count; i += 3) { + triangles[i].p1.x = pixman_double_to_fixed((double)points[i].x); + triangles[i].p1.y = pixman_double_to_fixed((double)points[i].y); + triangles[i].p2.x = pixman_double_to_fixed((double)points[i + 1].x); + triangles[i].p2.y = pixman_double_to_fixed((double)points[i + 1].y); + triangles[i].p3.x = pixman_double_to_fixed((double)points[i + 2].x); + triangles[i].p3.y = pixman_double_to_fixed((double)points[i + 2].y); } - cairo_close_path(handle->wayland.front_cairo); + pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb_back, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles); - cairo_fill(handle->wayland.front_cairo); + pixman_image_unref(image); handle->wayland.events_pending = 1; } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - int i; + int i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * 3); + pixman_image_t* image = pixman_image_create_solid_fill(&col); - clip(handle); + // for(i = 0; i < 3; i += 3) { + // triangles[i].p1.x = pixman_double_to_fixed((double)points[i].x); + // triangles[i].p1.y = pixman_double_to_fixed((double)points[i].y); + // triangles[i].p2.x = pixman_double_to_fixed((double)points[i + 1].x); + // triangles[i].p2.y = pixman_double_to_fixed((double)points[i + 1].y); + // triangles[i].p3.x = pixman_double_to_fixed((double)points[i].x); + // triangles[i].p3.y = pixman_double_to_fixed((double)points[i].y); + // } - cairo_set_antialias(handle->wayland.front_cairo, CAIRO_ANTIALIAS_NONE); - cairo_set_line_cap(handle->wayland.front_cairo, CAIRO_LINE_CAP_SQUARE); - cairo_set_source_rgba(handle->wayland.front_cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0, 1.0); - cairo_new_path(handle->wayland.front_cairo); - for(i = 0; i < 2; i++) { - if(i == 0) { - cairo_move_to(handle->wayland.front_cairo, points[i].x, points[i].y); - } else { - cairo_line_to(handle->wayland.front_cairo, points[i].x, points[i].y); - } - } - cairo_close_path(handle->wayland.front_cairo); - cairo_stroke(handle->wayland.front_cairo); + pixman_image_unref(image); handle->wayland.events_pending = 1; } @@ -2206,15 +2198,22 @@ static void MwLLSetTitleImpl(MwLL handle, const char* title) { } static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { - MwLLPixmap r = malloc(sizeof(*r)); + MwLLPixmap r = malloc(sizeof(*r)); + pixman_transform_t transform; + (void)handle; + int stride = width * 4; r->common.width = width; r->common.height = height; r->common.raw = malloc(4 * width * height); memcpy(r->common.raw, data, 4 * width * height); - r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + // pixman_transform_init_identity(&transform); + + r->wayland.img = NULL; + + // pixman_image_set_transform(r->wayland.img, &transform); MwLLPixmapUpdate(r); @@ -2224,54 +2223,33 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid static void MwLLPixmapUpdateImpl(MwLLPixmap r) { int i; unsigned char* d; - - cairo_surface_flush(r->wayland.cs); - d = cairo_image_surface_get_data(r->wayland.cs); - for(i = 0; i < r->common.width * r->common.height * 4; i += 4) { - MwU32* p = (MwU32*)&d[i]; - *p <<= 8; - *p |= r->common.raw[i + 3]; - *p <<= 8; - *p |= r->common.raw[i + 0]; - *p <<= 8; - *p |= r->common.raw[i + 1]; - *p <<= 8; - *p |= r->common.raw[i + 2]; + if(r->wayland.img) { + pixman_image_unref(r->wayland.img); } - cairo_surface_mark_dirty(r->wayland.cs); + r->wayland.img = pixman_image_create_bits(PIXMAN_a8b8g8r8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4); } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - cairo_surface_destroy(pixmap->wayland.cs); free(pixmap->common.raw); free(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; + int width, height; - cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height); - c = cairo_create(cs); + width = pixman_image_get_width(pixmap->wayland.img); + height = pixman_image_get_height(pixmap->wayland.img); - clip(handle); - - cairo_scale(c, (double)rect->width / pixmap->common.width, (double)rect->height / pixmap->common.height); - - cairo_set_source_surface(c, pixmap->wayland.cs, 0, 0); - cairo_pattern_set_filter(cairo_get_source(c), CAIRO_FILTER_NEAREST); - - cairo_paint(c); - - cairo_set_source_surface(selected_cairo, cs, rect->x, rect->y); - cairo_paint(selected_cairo); - - cairo_destroy(c); - cairo_surface_destroy(cs); - - MwLLForceRender(handle); - wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); + pixman_image_composite32(PIXMAN_OP_ATOP, + pixmap->wayland.img, /* src */ + NULL /* mask */, + handle->wayland.framebuffer.pixman_fb_back, /* dest */ + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + rect->x, rect->y, /* dest_x, dest_y */ + width, /* width */ + height /* height */); + return; } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { @@ -2579,16 +2557,12 @@ static int MwLLWaylandCallInitImpl(void) { * - manually checking environment variables */ #ifdef __linux__ - MwBool loadWayland; + MwBool loadWayland = MwFALSE; if(getenv("MILSKO_BACKEND")) { - loadWayland |= + loadWayland = (strcmp(getenv("MILSKO_BACKEND"), "wayland") == 0); - } - if(getenv("XDG_SESSION_TYPE")) { - loadWayland |= (strcmp(getenv("XDG_SESSION_TYPE"), "wayland") == 0); - } - if(getenv("WAYLAND_DISPLAY")) { - loadWayland |= (getenv("WAYLAND_DISPLAY") != NULL); + } else if(getenv("WAYLAND_DISPLAY") && !loadWayland) { + loadWayland = (getenv("WAYLAND_DISPLAY") != NULL); } if(loadWayland) { diff --git a/src/backend/x11.c b/src/backend/x11.c index 72e54f3..253012d 100644 --- a/src/backend/x11.c +++ b/src/backend/x11.c @@ -1278,14 +1278,10 @@ static void MwLLEndStateChangeImpl(MwLL handle) { static int MwLLX11CallInitImpl(void) { MwBool loadX11 = MwFALSE; if(getenv("MILSKO_BACKEND")) { - loadX11 |= + loadX11 = (strcmp(getenv("MILSKO_BACKEND"), "x11") == 0); - } - if(getenv("XDG_SESSION_TYPE")) { - loadX11 |= (strcmp(getenv("XDG_SESSION_TYPE"), "x11") == 0); - } - if(getenv("DISPLAY")) { - loadX11 |= (getenv("DISPLAY") != NULL); + } else if(getenv("DISPLAY")) { + loadX11 = (getenv("DISPLAY") != NULL); } if(!loadX11) { From ec2c128c7cd3538054dd3c34ef213d6b1e4d6c58 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 14:31:24 -0700 Subject: [PATCH 02/14] actual triangulation --- src/backend/wayland.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index c9a06b0..8b89589 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -1319,9 +1319,9 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3 pixman_color_t col = {0, 0, 0, 0xffff}; - buffer->pixman_fb_front = pixman_image_create_bits(PIXMAN_a8b8g8r8, + buffer->pixman_fb_front = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, buffer->buf, stride); - buffer->pixman_fb_back = pixman_image_create_bits(PIXMAN_a8b8g8r8, + buffer->pixman_fb_back = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, buffer->buf_back, stride); buffer->setup = MwTRUE; @@ -2059,18 +2059,23 @@ static void MwLLEndDrawImpl(MwLL handle) { static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { int i; - pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_color_t col = {color->common.blue * 0xFF, color->common.green * 0xFF, color->common.red * 0xFF, 0xffff}; pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * points_count); pixman_image_t* image = pixman_image_create_solid_fill(&col); memset(triangles, 0, sizeof(pixman_triangle_t) * points_count); - for(i = 0; i < points_count; i += 3) { - triangles[i].p1.x = pixman_double_to_fixed((double)points[i].x); - triangles[i].p1.y = pixman_double_to_fixed((double)points[i].y); - triangles[i].p2.x = pixman_double_to_fixed((double)points[i + 1].x); - triangles[i].p2.y = pixman_double_to_fixed((double)points[i + 1].y); - triangles[i].p3.x = pixman_double_to_fixed((double)points[i + 2].x); - triangles[i].p3.y = pixman_double_to_fixed((double)points[i + 2].y); + // todo: somebody smarter then me can do a real triangulation algorithim + for(i = 0; i < points_count; i++) { + triangles[i].p1.x = pixman_int_to_fixed(points[i].x); + triangles[i].p1.y = pixman_int_to_fixed(points[i].y); + if(i + 1 < points_count) { + triangles[i].p2.x = pixman_int_to_fixed(points[i + 1].x); + triangles[i].p2.y = pixman_int_to_fixed(points[i + 1].y); + } + if(i + 2 < points_count) { + triangles[i].p3.x = pixman_int_to_fixed(points[i + 2].x); + triangles[i].p3.y = pixman_int_to_fixed(points[i + 2].y); + } } pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb_back, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles); @@ -2226,7 +2231,7 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) { if(r->wayland.img) { pixman_image_unref(r->wayland.img); } - r->wayland.img = pixman_image_create_bits(PIXMAN_a8b8g8r8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4); + r->wayland.img = pixman_image_create_bits(PIXMAN_a8r8g8b8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4); } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { From 3ce1cb88f64eb77e1438ee326b68080a8ae9f8c9 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 14:39:26 -0700 Subject: [PATCH 03/14] only need one pixman buf --- include/Mw/LowLevel/Wayland.h | 5 +++-- src/backend/wayland.c | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 5ebba33..39a92f2 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -228,8 +228,9 @@ struct _MwLLWaylandShmBuffer { int fd_back; MwBool setup; - pixman_image_t* pixman_fb_front; - pixman_image_t* pixman_fb_back; + // pixman_image_t* pixman_fb_front; + pixman_image_t* pixman_fb; + int width, height; }; enum _MwLLWaylandType { diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 8b89589..ac482b0 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -1263,8 +1263,10 @@ static void wl_shm_interface_destroy(struct _MwLLWayland* wayland, wayland_proto static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { (void)self; memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); + // Yes this is needed every time, it's how we fix weston. wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); + wl_surface_commit(buffer->surface); } @@ -1319,10 +1321,11 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3 pixman_color_t col = {0, 0, 0, 0xffff}; - buffer->pixman_fb_front = pixman_image_create_bits(PIXMAN_a8r8g8b8, - width, height, buffer->buf, stride); - buffer->pixman_fb_back = pixman_image_create_bits(PIXMAN_a8r8g8b8, - width, height, buffer->buf_back, stride); + buffer->pixman_fb = pixman_image_create_bits(PIXMAN_a8r8g8b8, + width, height, buffer->buf_back, stride); + + buffer->width = width; + buffer->height = height; buffer->setup = MwTRUE; } @@ -1337,8 +1340,7 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) { if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back); close(buffer->fd); close(buffer->fd_back); - pixman_image_unref(buffer->pixman_fb_front); - pixman_image_unref(buffer->pixman_fb_back); + pixman_image_unref(buffer->pixman_fb); buffer->setup = MwFALSE; } @@ -2077,7 +2079,7 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL triangles[i].p3.y = pixman_int_to_fixed(points[i + 2].y); } } - pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb_back, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles); + pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles); pixman_image_unref(image); @@ -2248,11 +2250,11 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { pixman_image_composite32(PIXMAN_OP_ATOP, pixmap->wayland.img, /* src */ NULL /* mask */, - handle->wayland.framebuffer.pixman_fb_back, /* dest */ - 0, 0, /* src_x, src_y */ - 0, 0, /* mask_x, mask_y */ - rect->x, rect->y, /* dest_x, dest_y */ - width, /* width */ + handle->wayland.framebuffer.pixman_fb, /* dest */ + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + rect->x, rect->y, /* dest_x, dest_y */ + width, /* width */ height /* height */); return; } From 5462103815430b97ee67393e1ed54afcd5b0e1fb Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 14:45:55 -0700 Subject: [PATCH 04/14] wayland: we don't need wayland shms for the back buffer (anymore) --- include/Mw/LowLevel/Wayland.h | 3 --- src/backend/wayland.c | 31 ++++++------------------------- 2 files changed, 6 insertions(+), 28 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 39a92f2..5497cd3 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -216,8 +216,6 @@ struct _MwLLWaylandShmBuffer { struct wl_shm* shm; struct wl_shm_pool* shm_pool; struct wl_buffer* shm_buffer; - struct wl_shm_pool* shm_pool_back; - struct wl_buffer* shm_buffer_back; struct wl_surface* surface; struct wl_output* output; @@ -225,7 +223,6 @@ struct _MwLLWaylandShmBuffer { MwU32* buf_back; MwU64 buf_size; int fd; - int fd_back; MwBool setup; // pixman_image_t* pixman_fb_front; diff --git a/src/backend/wayland.c b/src/backend/wayland.c index ac482b0..93e6341 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -1277,8 +1277,7 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3 buffer->buf_size = (width * height * 4) * sizeof(MwU32); - buffer->fd = mkstemp(temp_name); - buffer->fd_back = mkstemp(temp_name_back); + buffer->fd = mkstemp(temp_name); unlink(temp_name); unlink(temp_name_back); @@ -1288,38 +1287,21 @@ static void buffer_setup(struct _MwLLWaylandShmBuffer* buffer, MwU32 width, MwU3 close(buffer->fd); return; } - if(posix_fallocate(buffer->fd_back, 0, buffer->buf_size) != 0) { - printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); - close(buffer->fd_back); - return; - } if(ftruncate(buffer->fd, buffer->buf_size) != 0) { printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); close(buffer->fd); return; } - if(ftruncate(buffer->fd_back, buffer->buf_size) != 0) { - printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); - close(buffer->fd_back); - return; - } buffer->buf = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd, 0); - buffer->buf_back = mmap(NULL, buffer->buf_size, PROT_WRITE, MAP_SHARED, buffer->fd_back, 0); + buffer->buf_back = malloc(buffer->buf_size); fsync(buffer->fd); - fsync(buffer->fd_back); if(!(buffer->shm_pool = wl_shm_create_pool(buffer->shm, buffer->fd, buffer->buf_size))) { printf("failure setting up wl_shm: could not create pool.\n"); } - if(!(buffer->shm_pool_back = wl_shm_create_pool(buffer->shm, buffer->fd_back, buffer->buf_size))) { - printf("failure setting up wl_shm: could not create pool.\n"); - } - buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); - buffer->shm_buffer_back = wl_shm_pool_create_buffer(buffer->shm_pool_back, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); - - pixman_color_t col = {0, 0, 0, 0xffff}; + buffer->shm_buffer = wl_shm_pool_create_buffer(buffer->shm_pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); buffer->pixman_fb = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, buffer->buf_back, stride); @@ -1335,11 +1317,10 @@ static void buffer_destroy(struct _MwLLWaylandShmBuffer* buffer) { return; } if(buffer->shm_buffer) wl_buffer_destroy(buffer->shm_buffer); - if(buffer->shm_buffer_back) wl_buffer_destroy(buffer->shm_buffer_back); if(buffer->shm_pool) wl_shm_pool_destroy(buffer->shm_pool); - if(buffer->shm_pool_back) wl_shm_pool_destroy(buffer->shm_pool_back); + munmap(buffer->buf, buffer->buf_size); + free(buffer->buf_back); close(buffer->fd); - close(buffer->fd_back); pixman_image_unref(buffer->pixman_fb); buffer->setup = MwFALSE; @@ -2292,7 +2273,7 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { if(handle->wayland.configured) update_buffer(handle, handle->wayland.icon); - xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer_back, 1); + xdg_toplevel_icon_v1_add_buffer(icon, handle->wayland.icon->shm_buffer, 1); xdg_toplevel_icon_manager_v1_set_icon(icon_manager, handle->wayland.toplevel->xdg_top_level, icon); } From c8e4d44e3e90faab5130d914012796877ac7eae7 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 17:06:29 -0700 Subject: [PATCH 05/14] fan triangulation --- src/backend/wayland.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 93e6341..18d7fd4 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2045,23 +2045,17 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL pixman_color_t col = {color->common.blue * 0xFF, color->common.green * 0xFF, color->common.red * 0xFF, 0xffff}; pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * points_count); pixman_image_t* image = pixman_image_create_solid_fill(&col); - memset(triangles, 0, sizeof(pixman_triangle_t) * points_count); - // todo: somebody smarter then me can do a real triangulation algorithim - for(i = 0; i < points_count; i++) { - triangles[i].p1.x = pixman_int_to_fixed(points[i].x); - triangles[i].p1.y = pixman_int_to_fixed(points[i].y); - if(i + 1 < points_count) { - triangles[i].p2.x = pixman_int_to_fixed(points[i + 1].x); - triangles[i].p2.y = pixman_int_to_fixed(points[i + 1].y); - } - if(i + 2 < points_count) { - triangles[i].p3.x = pixman_int_to_fixed(points[i + 2].x); - triangles[i].p3.y = pixman_int_to_fixed(points[i + 2].y); - } + for(int i = 1; i < points_count - 1; i++) { + triangles[i - 1] = (pixman_triangle_t){ + .p1 = {pixman_int_to_fixed(points[0].x), pixman_int_to_fixed(points[0].y)}, + .p2 = {pixman_int_to_fixed(points[i].x), pixman_int_to_fixed(points[i].y)}, + .p3 = {pixman_int_to_fixed(points[i + 1].x), pixman_int_to_fixed(points[i + 1].y)}, + }; } pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles); + free(triangles); pixman_image_unref(image); handle->wayland.events_pending = 1; From afb46f173a5f8f52d70f385714df346dd87021bc Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 17:58:10 -0700 Subject: [PATCH 06/14] draw images scaled on wayland --- src/backend/wayland.c | 225 +++++++++++++++++++++++++++++++++++------- src/draw.c | 10 +- 2 files changed, 191 insertions(+), 44 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 18d7fd4..f9d0acd 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2040,41 +2040,183 @@ static void MwLLEndDrawImpl(MwLL handle) { } } -static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - int i; - pixman_color_t col = {color->common.blue * 0xFF, color->common.green * 0xFF, color->common.red * 0xFF, 0xffff}; - pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * points_count); - pixman_image_t* image = pixman_image_create_solid_fill(&col); +#define MAXPTS 512 +#define MAXTRI (MAXPTS * 4) +#define EPS 1e-7 - for(int i = 1; i < points_count - 1; i++) { - triangles[i - 1] = (pixman_triangle_t){ - .p1 = {pixman_int_to_fixed(points[0].x), pixman_int_to_fixed(points[0].y)}, - .p2 = {pixman_int_to_fixed(points[i].x), pixman_int_to_fixed(points[i].y)}, - .p3 = {pixman_int_to_fixed(points[i + 1].x), pixman_int_to_fixed(points[i + 1].y)}, - }; +#define PACK(dst, pts, idx) \ + do { \ + (dst).x = pixman_int_to_fixed((pts)[(idx)].x); \ + (dst).y = pixman_int_to_fixed((pts)[(idx)].y); \ + } while(0) + +typedef struct { + int a, b, c; + double cx, cy, r2; /* circumcircle centre + radius^2 */ +} triangle; + +typedef struct { + MwPoint pts[MAXPTS + 3]; + int npts; + triangle tris[MAXTRI]; + int ntris; + int bad[MAXTRI]; + int nbad; + MwPoint edges[MAXTRI * 3]; + int nedges; +} triangulation_state; + +static void circumcircle(triangulation_state* s, int t) { + double ax = s->pts[s->tris[t].a].x, ay = s->pts[s->tris[t].a].y; + double bx = s->pts[s->tris[t].b].x, by = s->pts[s->tris[t].b].y; + double cx = s->pts[s->tris[t].c].x, cy = s->pts[s->tris[t].c].y; + double D = 2.0 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)); + double ux, uy; + if(fabs(D) < EPS) { + s->tris[t].r2 = 1e30; + return; } - pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, triangles); + ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / D; + uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / D; + s->tris[t].cx = ux; + s->tris[t].cy = uy; + s->tris[t].r2 = (ax - ux) * (ax - ux) + (ay - uy) * (ay - uy); +} + +static int in_circumcircle(triangulation_state* s, int t, int p) { + double dx = s->pts[p].x - s->tris[t].cx; + double dy = s->pts[p].y - s->tris[t].cy; + return dx * dx + dy * dy < s->tris[t].r2 - EPS; +} + +static void add_tri(triangulation_state* s, int a, int b, int c) { + s->tris[s->ntris].a = a; + s->tris[s->ntris].b = b; + s->tris[s->ntris].c = c; + circumcircle(s, s->ntris); + s->ntris++; +} + +static void remove_tri(triangulation_state* s, int i) { + s->tris[i] = s->tris[--s->ntris]; +} + +static int delaunay(const int* src, int npts, + pixman_triangle_t* out, int out_size) { + triangulation_state s; + int si, i, j, k; + double mnx, mxx, mny, mxy, dx, dy, dmx, mx, my; + + if(npts < 3 || npts > MAXPTS) return -1; + + s.npts = npts; + for(i = 0; i < npts; i++) { + s.pts[i].x = src[i * 2]; + s.pts[i].y = src[i * 2 + 1]; + } + + /* super-triangle */ + mnx = mxx = s.pts[0].x; + mny = mxy = s.pts[0].y; + for(i = 1; i < npts; i++) { + if(s.pts[i].x < mnx) mnx = s.pts[i].x; + if(s.pts[i].x > mxx) mxx = s.pts[i].x; + if(s.pts[i].y < mny) mny = s.pts[i].y; + if(s.pts[i].y > mxy) mxy = s.pts[i].y; + } + dx = mxx - mnx; + dy = mxy - mny; + dmx = (dx > dy) ? dx : dy; + mx = (mnx + mxx) * 0.5; + my = (mny + mxy) * 0.5; + + si = npts; + s.pts[si].x = mx - 20.0 * dmx; + s.pts[si].y = my - dmx; + s.pts[si + 1].x = mx; + s.pts[si + 1].y = my + 20.0 * dmx; + s.pts[si + 2].x = mx + 20.0 * dmx; + s.pts[si + 2].y = my - dmx; + + s.ntris = 0; + add_tri(&s, si, si + 1, si + 2); + + /* insert each point */ + for(i = 0; i < npts; i++) { + s.nbad = 0; + for(j = 0; j < s.ntris; j++) + if(in_circumcircle(&s, j, i)) + s.bad[s.nbad++] = j; + + s.nedges = 0; + for(j = 0; j < s.nbad; j++) { + int ea[3][2]; + ea[0][0] = s.tris[s.bad[j]].a; + ea[0][1] = s.tris[s.bad[j]].b; + ea[1][0] = s.tris[s.bad[j]].b; + ea[1][1] = s.tris[s.bad[j]].c; + ea[2][0] = s.tris[s.bad[j]].c; + ea[2][1] = s.tris[s.bad[j]].a; + for(k = 0; k < 3; k++) { + int m, shared = 0; + for(m = 0; m < s.nbad; m++) { + if(m == j) continue; + if((s.tris[s.bad[m]].a == ea[k][0] || s.tris[s.bad[m]].b == ea[k][0] || s.tris[s.bad[m]].c == ea[k][0]) && + (s.tris[s.bad[m]].a == ea[k][1] || s.tris[s.bad[m]].b == ea[k][1] || s.tris[s.bad[m]].c == ea[k][1])) { + shared = 1; + break; + } + } + if(!shared) { + s.edges[s.nedges].x = ea[k][0]; + s.edges[s.nedges].y = ea[k][1]; + s.nedges++; + } + } + } + + for(j = s.nbad - 1; j >= 0; j--) + remove_tri(&s, s.bad[j]); + + for(j = 0; j < s.nedges; j++) + add_tri(&s, s.edges[j].x, s.edges[j].y, i); + } + + /* remove triangles touching the super-triangle */ + for(i = s.ntris - 1; i >= 0; i--) + if(s.tris[i].a >= npts || s.tris[i].b >= npts || s.tris[i].c >= npts) + remove_tri(&s, i); + + if(s.ntris > out_size) return -1; + + /* pack into pixman_triangle_t */ + for(i = 0; i < s.ntris; i++) { + PACK(out[i].p1, s.pts, s.tris[i].a); + PACK(out[i].p2, s.pts, s.tris[i].b); + PACK(out[i].p3, s.pts, s.tris[i].c); + } + return s.ntris; +} + +static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { + int n, i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_image_t* image = pixman_image_create_solid_fill(&col); + pixman_triangle_t out[MAXTRI]; + + n = delaunay((int*)points, points_count, out, MAXTRI); + + pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, out); - free(triangles); pixman_image_unref(image); handle->wayland.events_pending = 1; } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - int i; - pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; - pixman_triangle_t* triangles = malloc(sizeof(pixman_triangle_t) * 3); - pixman_image_t* image = pixman_image_create_solid_fill(&col); - - // for(i = 0; i < 3; i += 3) { - // triangles[i].p1.x = pixman_double_to_fixed((double)points[i].x); - // triangles[i].p1.y = pixman_double_to_fixed((double)points[i].y); - // triangles[i].p2.x = pixman_double_to_fixed((double)points[i + 1].x); - // triangles[i].p2.y = pixman_double_to_fixed((double)points[i + 1].y); - // triangles[i].p3.x = pixman_double_to_fixed((double)points[i].x); - // triangles[i].p3.y = pixman_double_to_fixed((double)points[i].y); - // } + int i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_image_t* image = pixman_image_create_solid_fill(&col); pixman_image_unref(image); @@ -2208,7 +2350,7 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) { if(r->wayland.img) { pixman_image_unref(r->wayland.img); } - r->wayland.img = pixman_image_create_bits(PIXMAN_a8r8g8b8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4); + r->wayland.img = pixman_image_create_bits(PIXMAN_a8b8g8r8, r->common.width, r->common.height, (MwU32*)r->common.raw, r->common.width * 4); } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { @@ -2217,21 +2359,28 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - int width, height; + int width, height; + pixman_transform_t transform; + pixman_transform_t reverse; + struct pixman_box16 b; + + pixman_transform_init_identity(&transform); + + pixman_transform_scale(&transform, &reverse, pixman_double_to_fixed((double)pixmap->common.width / (double)rect->width), pixman_double_to_fixed((double)pixmap->common.height / (double)rect->height)); + + pixman_image_set_transform(pixmap->wayland.img, &transform); width = pixman_image_get_width(pixmap->wayland.img); height = pixman_image_get_height(pixmap->wayland.img); - pixman_image_composite32(PIXMAN_OP_ATOP, - pixmap->wayland.img, /* src */ - NULL /* mask */, - handle->wayland.framebuffer.pixman_fb, /* dest */ - 0, 0, /* src_x, src_y */ - 0, 0, /* mask_x, mask_y */ - rect->x, rect->y, /* dest_x, dest_y */ - width, /* width */ - height /* height */); - return; + pixman_image_composite(PIXMAN_OP_OVER, + pixmap->wayland.img, /* src */ + NULL /* mask */, + handle->wayland.framebuffer.pixman_fb, /* dest */ + 0, 0, /* src_x, src_y */ + 0, 0, /* mask_x, mask_y */ + rect->x, rect->y, /* dest_x, dest_y */ + rect->width, rect->height /* height */); } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { diff --git a/src/draw.c b/src/draw.c index 12ccb51..3dce0c3 100644 --- a/src/draw.c +++ b/src/draw.c @@ -197,13 +197,11 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert if(rect->width <= 0 || rect->height <= 0) return; if(border) { - if(!handle->lowlevel->common.supports_transparency) { - MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); + MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); - if(c != NULL) { - MwDrawRect(handle, rect, c); - MwLLFreeColor(c); - } + if(c != NULL) { + MwDrawRect(handle, rect, c); + MwLLFreeColor(c); } MwDrawFrame(handle, rect, color, invert, rounded); From 94ace21566bb062221af2848f446b9a3cd8b8985 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 18:04:25 -0700 Subject: [PATCH 07/14] a --- src/backend/wayland.c | 11 +++------ src/draw.c | 55 +++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index f9d0acd..c98a187 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2333,12 +2333,8 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid r->common.raw = malloc(4 * width * height); memcpy(r->common.raw, data, 4 * width * height); - // pixman_transform_init_identity(&transform); - r->wayland.img = NULL; - // pixman_image_set_transform(r->wayland.img, &transform); - MwLLPixmapUpdate(r); return r; @@ -2359,10 +2355,9 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - int width, height; - pixman_transform_t transform; - pixman_transform_t reverse; - struct pixman_box16 b; + int width, height; + pixman_transform_t transform; + pixman_transform_t reverse; pixman_transform_init_identity(&transform); diff --git a/src/draw.c b/src/draw.c index 3dce0c3..55ace33 100644 --- a/src/draw.c +++ b/src/draw.c @@ -140,15 +140,16 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde pixmap = MwLLCreatePixmap(handle->lowlevel, data, 1, rect->height); if(rounded && rect->height >= (roundness * 2) && rect->width >= (roundness * 2) && roundness > 0) { for(i = 0; i < roundness; i++) { - int x = (roundness + 2); - int y = rect->y + (roundness + 2); - double point = ((i + (M_PI * 4)) / div); - r.x = (roundness + 4) - (sin(point) * roundness); - r.y = y + (cos(point) * roundness) + 1; - r.width = roundness; - r.height = (rect->height - ((r.y - rect->y) * 2) - 1); + int x = (roundness + 2); + int y = rect->y + (roundness + 2); + double point = ((i + (M_PI * 4)) / div); + double point2 = (((i + 2) + (M_PI * 4)) / div); + r.x = (roundness + 4) - (sin(point) * roundness); + r.y = y + (cos(point) * roundness) + 1; + r.width = roundness; + r.height = (rect->height - ((r.y - rect->y) * 2) - 1); MwLLDrawPixmap(handle->lowlevel, &r, pixmap); - r.width = x + (sin(point + 1) * roundness); + r.width = x + (sin(point2) * roundness); r.x = ((rect->width - (roundness + 1)) + (sin(point) * roundness)) - r.width; MwLLDrawPixmap(handle->lowlevel, &r, pixmap); } @@ -355,14 +356,15 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte /* top left edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; - double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - int x = rect->x + (roundness + 2); - int y = rect->y + (roundness + 2); + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + double point2 = (((i + 2) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = rect->x + (roundness + 2); + int y = rect->y + (roundness + 2); line[0].x = x - (sin(point) * roundness); line[0].y = y + (cos(point) * roundness); - line[1].x = x - (sin(point + 1) * roundness); - line[1].y = y + (cos(point + 1) * roundness); + line[1].x = x - (sin(point2) * roundness); + line[1].y = y + (cos(point2) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } @@ -389,13 +391,14 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + double point2 = (((i + 1) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); int x = (rect->x + rect->width) - (roundness + 2); int y = rect->y + (roundness + 2); double placeholder = (sin(point) * roundness); line[0].x = x + placeholder; line[0].y = y + (cos(point) * roundness); - line[1].x = x + (sin(point + 1) * roundness); - line[1].y = y + (cos(point + 1) * roundness); + line[1].x = x + (sin(point2) * roundness); + line[1].y = y + (cos(point2) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } } else { @@ -422,14 +425,15 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte /* bottom left edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; - double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - int x = rect->x + (roundness + 2); - int y = (rect->y + rect->height) - (roundness + 2); + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + double point2 = (((i + 1) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = rect->x + (roundness + 2); + int y = (rect->y + rect->height) - (roundness + 2); line[0].x = x - (sin(point) * roundness); line[0].y = y - (cos(point) * roundness); - line[1].x = x - (sin(point + 1) * roundness); - line[1].y = y - (cos(point + 1) * roundness); + line[1].x = x - (sin(point2) * roundness); + line[1].y = y - (cos(point2) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } p[0].x = rect->x + roundness; @@ -458,14 +462,15 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte /* bottom right edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; - double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - int x = (rect->x + rect->width) - (roundness + 2); - int y = (rect->y + rect->height) - (roundness + 2); + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + double point2 = (((i + 2) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = (rect->x + rect->width) - (roundness + 2); + int y = (rect->y + rect->height) - (roundness + 2); line[0].x = x + (sin(point) * roundness); line[0].y = y - (cos(point) * roundness); - line[1].x = x + (sin(point + 1) * roundness); - line[1].y = y - (cos(point + 1) * roundness); + line[1].x = x + (sin(point2) * roundness); + line[1].y = y - (cos(point2) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } } else { From 46c4e98506c974411f2d5dd7502ced173986ecf8 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 18:12:11 -0700 Subject: [PATCH 08/14] org --- src/backend/wayland.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index c98a187..f4f6164 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2101,7 +2101,7 @@ static void remove_tri(triangulation_state* s, int i) { s->tris[i] = s->tris[--s->ntris]; } -static int delaunay(const int* src, int npts, +static int delaunay(MwPoint* src, int npts, pixman_triangle_t* out, int out_size) { triangulation_state s; int si, i, j, k; @@ -2110,10 +2110,7 @@ static int delaunay(const int* src, int npts, if(npts < 3 || npts > MAXPTS) return -1; s.npts = npts; - for(i = 0; i < npts; i++) { - s.pts[i].x = src[i * 2]; - s.pts[i].y = src[i * 2 + 1]; - } + memcpy(s.pts, src, npts * sizeof(MwPoint)); /* super-triangle */ mnx = mxx = s.pts[0].x; @@ -2204,7 +2201,7 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL pixman_image_t* image = pixman_image_create_solid_fill(&col); pixman_triangle_t out[MAXTRI]; - n = delaunay((int*)points, points_count, out, MAXTRI); + n = delaunay(points, points_count, out, MAXTRI); pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, out); From 9960f7e7efeb3347fef042ae7da4c203b263da6f Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 18:20:58 -0700 Subject: [PATCH 09/14] composite polygons properly --- src/backend/wayland.c | 2 +- src/draw.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index f4f6164..f9b1b0c 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2203,7 +2203,7 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL n = delaunay(points, points_count, out, MAXTRI); - pixman_composite_triangles(PIXMAN_OP_ATOP_REVERSE, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, out); + pixman_composite_triangles(PIXMAN_OP_OVER, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, out); pixman_image_unref(image); diff --git a/src/draw.c b/src/draw.c index 55ace33..7d23aa9 100644 --- a/src/draw.c +++ b/src/draw.c @@ -143,7 +143,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde int x = (roundness + 2); int y = rect->y + (roundness + 2); double point = ((i + (M_PI * 4)) / div); - double point2 = (((i + 2) + (M_PI * 4)) / div); + double point2 = (((i + 1) + (M_PI * 4)) / div); r.x = (roundness + 4) - (sin(point) * roundness); r.y = y + (cos(point) * roundness) + 1; r.width = roundness; From 709067c7420517600a1916fe250d4b333ab80f6a Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 18:52:23 -0700 Subject: [PATCH 10/14] fix responsiveness, fix comments --- src/backend/wayland.c | 67 ++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 36 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index f9b1b0c..693c94c 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -69,8 +69,6 @@ static void new_protocol(void* data, struct wl_registry* registry, /* we don't care for adding this protocol, we just use it to know if the compositor will let us have transparent surfaces */ } else if(strcmp(interface, "wp_alpha_modifier_v1") == 0) { self->common.supports_transparency = MwTRUE; - } else { - // printf("unknown interface %s\n", interface); } WAYLAND_EVENT_OP_END(self); @@ -1264,7 +1262,7 @@ static void update_buffer(MwLL self, struct _MwLLWaylandShmBuffer* buffer) { (void)self; memcpy(buffer->buf, buffer->buf_back, buffer->buf_size); - // Yes this is needed every time, it's how we fix weston. + /* Yes this is needed every time, it's how we fix weston.*/ wl_surface_attach(buffer->surface, buffer->shm_buffer, 0, 0); wl_surface_commit(buffer->surface); @@ -1842,7 +1840,6 @@ static void MwLLDestroyImpl(MwLL handle) { pthread_mutex_unlock(&handle->wayland.eventsMutex); pthread_mutex_destroy(&handle->wayland.eventsMutex); - // framebuffer_destroy(&handle->wayland); buffer_destroy(&handle->wayland.cursor); wl_region_destroy(handle->wayland.region); @@ -1942,7 +1939,6 @@ refresh: static void MwLLBeginDrawImpl(MwLL handle) { if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) { - // handle->wayland.selected_cairo = handle->wayland.front_cairo; return; } @@ -1950,34 +1946,34 @@ static void MwLLBeginDrawImpl(MwLL handle) { 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_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, 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_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); + 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; @@ -1993,8 +1989,6 @@ static void MwLLBeginDrawImpl(MwLL handle) { 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); @@ -2028,7 +2022,6 @@ static void MwLLBeginDrawImpl(MwLL handle) { } update_buffer(handle, &handle->wayland.backbuffer); } - // handle->wayland.selected_cairo = handle->wayland.front_cairo; } static void MwLLEndDrawImpl(MwLL handle) { @@ -2373,6 +2366,10 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { 0, 0, /* mask_x, mask_y */ rect->x, rect->y, /* dest_x, dest_y */ rect->width, rect->height /* height */); + + /* this seems worthless but this actually makes it a bit more responsive */ + MwLLForceRender(handle); + wl_surface_damage(handle->wayland.framebuffer.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { @@ -2467,13 +2464,11 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { } handle->wayland.cursor.surface = wl_compositor_create_surface(handle->wayland.compositor); - wl_surface_attach(handle->wayland.cursor.surface, handle->wayland.cursor.shm_buffer, 0, 0); - wl_surface_commit(handle->wayland.cursor.surface); update_buffer(handle, &handle->wayland.cursor); /* If there's currently a pointer, set it up. (Otherwise, it'll be setup during the pointer enter event) */ if(handle->wayland.pointer != NULL) { - // wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0); + wl_pointer_set_cursor(handle->wayland.pointer, handle->wayland.pointer_serial, handle->wayland.cursor.surface, 0, 0); } } From 41a874432d5aeb06d7cfb26cbbb1eb437e5f3200 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 19:23:25 -0700 Subject: [PATCH 11/14] stub out cursor code but have it be a white box at least for now --- src/backend/wayland.c | 61 +++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 693c94c..40c9e7c 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2391,15 +2391,16 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { } handle->wayland.icon->surface = wl_compositor_create_surface(handle->wayland.compositor); + buffer_setup(handle->wayland.icon, pixmap->common.width, pixmap->common.height); + wl_surface_attach(handle->wayland.icon->surface, handle->wayland.icon->shm_buffer, 0, 0); wl_surface_commit(handle->wayland.icon->surface); - buffer_setup(handle->wayland.icon, pixmap->common.width, pixmap->common.height); - for(; i < size; i += 2) { - handle->wayland.icon->buf_back[i] = pixmap->common.raw[i + 2]; - handle->wayland.icon->buf_back[i + 1] = pixmap->common.raw[i + 1]; - handle->wayland.icon->buf_back[i + 2] = pixmap->common.raw[i + 0]; + MwU32* data = pixman_image_get_data(pixmap->wayland.img); + handle->wayland.icon->buf_back[i] = data[i + 2]; + handle->wayland.icon->buf_back[i + 1] = data[i + 1]; + handle->wayland.icon->buf_back[i + 2] = data[i + 0]; handle->wayland.icon->buf_back[i + 3] = 255; } @@ -2429,39 +2430,41 @@ static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { wl_surface_destroy(handle->wayland.cursor.surface); } buffer_setup(&handle->wayland.cursor, image->width, image->height); - memset(handle->wayland.cursor.buf_back, 0, handle->wayland.cursor.buf_size); + memset(handle->wayland.cursor.buf_back, 255, handle->wayland.cursor.buf_size); xs = -mask->x + image->x; ys = mask->height + mask->y; ys = image->height + image->y - ys; - for(y = 0; y < mask->height; y++) { - unsigned int d = mask->data[y]; - for(x = mask->width - 1; x >= 0; x--) { - int idx = ((y * image->width) + x) * 4; + /* currently broken */ + /* for(y = 0; y < mask->height; y++) { + unsigned int d = mask->data[y]; + for(x = mask->width - 1; x >= 0; x--) { + int idx = ((y * image->width) + x) * 4; - if(d & 1) { - handle->wayland.cursor.buf_back[idx + 3] = 255; - }; - d = d >> 1; + if(d & 1) { + handle->wayland.cursor.buf_back[idx + 3] = 255; + }; + d = d >> 1; + } } - } - for(y = 0; y < image->height; y++) { - unsigned int d = image->data[y]; - for(x = image->width - 1; x >= 0; x--) { - int px = 0; - int idx = (((y + ys) * image->width) + (x + xs)) * 4; + for(y = 0; y < image->height; y++) { + unsigned int d = image->data[y]; + for(x = image->width - 1; x >= 0; x--) { + int px = 0; + int idx = (((y + ys) * image->width) + (x + xs)) * 4; - if(d & 1) { - px = 255; - }; + if(d & 1) { + px = 255; + }; - handle->wayland.cursor.buf_back[idx] = px; - handle->wayland.cursor.buf_back[idx + 1] = px; - handle->wayland.cursor.buf_back[idx + 2] = px; - d = d >> 1; - } - } + handle->wayland.cursor.buf_back[idx] = px; + handle->wayland.cursor.buf_back[idx + 1] = px; + handle->wayland.cursor.buf_back[idx + 2] = px; + handle->wayland.cursor.buf_back[idx + 3] = px; + d = d >> 1; + } + }*/ handle->wayland.cursor.surface = wl_compositor_create_surface(handle->wayland.compositor); update_buffer(handle, &handle->wayland.cursor); From ba917c8b13b70ad798ba1a8f6cb8490df8a54877 Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Wed, 8 Apr 2026 20:00:59 -0700 Subject: [PATCH 12/14] undo fixing the corners for now, it doesn't work on master anyways --- src/draw.c | 65 ++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/src/draw.c b/src/draw.c index 7d23aa9..12ccb51 100644 --- a/src/draw.c +++ b/src/draw.c @@ -140,16 +140,15 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color, int rounde pixmap = MwLLCreatePixmap(handle->lowlevel, data, 1, rect->height); if(rounded && rect->height >= (roundness * 2) && rect->width >= (roundness * 2) && roundness > 0) { for(i = 0; i < roundness; i++) { - int x = (roundness + 2); - int y = rect->y + (roundness + 2); - double point = ((i + (M_PI * 4)) / div); - double point2 = (((i + 1) + (M_PI * 4)) / div); - r.x = (roundness + 4) - (sin(point) * roundness); - r.y = y + (cos(point) * roundness) + 1; - r.width = roundness; - r.height = (rect->height - ((r.y - rect->y) * 2) - 1); + int x = (roundness + 2); + int y = rect->y + (roundness + 2); + double point = ((i + (M_PI * 4)) / div); + r.x = (roundness + 4) - (sin(point) * roundness); + r.y = y + (cos(point) * roundness) + 1; + r.width = roundness; + r.height = (rect->height - ((r.y - rect->y) * 2) - 1); MwLLDrawPixmap(handle->lowlevel, &r, pixmap); - r.width = x + (sin(point2) * roundness); + r.width = x + (sin(point + 1) * roundness); r.x = ((rect->width - (roundness + 1)) + (sin(point) * roundness)) - r.width; MwLLDrawPixmap(handle->lowlevel, &r, pixmap); } @@ -198,11 +197,13 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert if(rect->width <= 0 || rect->height <= 0) return; if(border) { - MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); + if(!handle->lowlevel->common.supports_transparency) { + MwLLColor c = handle->parent == NULL ? NULL : MwParseColor(handle->parent, MwGetText(handle->parent, MwNbackground)); - if(c != NULL) { - MwDrawRect(handle, rect, c); - MwLLFreeColor(c); + if(c != NULL) { + MwDrawRect(handle, rect, c); + MwLLFreeColor(c); + } } MwDrawFrame(handle, rect, color, invert, rounded); @@ -356,15 +357,14 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte /* top left edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; - double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - double point2 = (((i + 2) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - int x = rect->x + (roundness + 2); - int y = rect->y + (roundness + 2); + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = rect->x + (roundness + 2); + int y = rect->y + (roundness + 2); line[0].x = x - (sin(point) * roundness); line[0].y = y + (cos(point) * roundness); - line[1].x = x - (sin(point2) * roundness); - line[1].y = y + (cos(point2) * roundness); + line[1].x = x - (sin(point + 1) * roundness); + line[1].y = y + (cos(point + 1) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } @@ -391,14 +391,13 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - double point2 = (((i + 1) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); int x = (rect->x + rect->width) - (roundness + 2); int y = rect->y + (roundness + 2); double placeholder = (sin(point) * roundness); line[0].x = x + placeholder; line[0].y = y + (cos(point) * roundness); - line[1].x = x + (sin(point2) * roundness); - line[1].y = y + (cos(point2) * roundness); + line[1].x = x + (sin(point + 1) * roundness); + line[1].y = y + (cos(point + 1) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } } else { @@ -425,15 +424,14 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte /* bottom left edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; - double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - double point2 = (((i + 1) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - int x = rect->x + (roundness + 2); - int y = (rect->y + rect->height) - (roundness + 2); + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = rect->x + (roundness + 2); + int y = (rect->y + rect->height) - (roundness + 2); line[0].x = x - (sin(point) * roundness); line[0].y = y - (cos(point) * roundness); - line[1].x = x - (sin(point2) * roundness); - line[1].y = y - (cos(point2) * roundness); + line[1].x = x - (sin(point + 1) * roundness); + line[1].y = y - (cos(point + 1) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } p[0].x = rect->x + roundness; @@ -462,15 +460,14 @@ static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighte /* bottom right edge */ for(i = 0; i < BORDER_SMOOTHNESS; i += 2) { MwPoint line[2]; - double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - double point2 = (((i + 2) + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); - int x = (rect->x + rect->width) - (roundness + 2); - int y = (rect->y + rect->height) - (roundness + 2); + double point = ((i + (M_PI * (BORDER_SMOOTHNESS / 2.))) / (BORDER_SMOOTHNESS)); + int x = (rect->x + rect->width) - (roundness + 2); + int y = (rect->y + rect->height) - (roundness + 2); line[0].x = x + (sin(point) * roundness); line[0].y = y - (cos(point) * roundness); - line[1].x = x + (sin(point2) * roundness); - line[1].y = y - (cos(point2) * roundness); + line[1].x = x + (sin(point + 1) * roundness); + line[1].y = y - (cos(point + 1) * roundness); MwLLLine(handle->lowlevel, line, invert ? lighter : darker); } } else { From d3f2054bab28c0e35f58d6535d1a5508903fa0fb Mon Sep 17 00:00:00 2001 From: IoIxD Date: Fri, 10 Apr 2026 10:27:59 -0700 Subject: [PATCH 13/14] triangulation code that isn't ai generated --- src/backend/wayland.c | 255 +++++++++++++++++++----------------------- 1 file changed, 113 insertions(+), 142 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 40c9e7c..48b22f9 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2032,171 +2032,142 @@ static void MwLLEndDrawImpl(MwLL handle) { update_buffer(handle, &handle->wayland.framebuffer); } } +typedef struct pointf64 { + double x; + double y; +} pointf64_t; -#define MAXPTS 512 -#define MAXTRI (MAXPTS * 4) -#define EPS 1e-7 +pixman_triangle_t* triangulate_polygon(pointf64_t* poly_points, int poly_points_count, int* tri_count_out) { + pixman_triangle_t* tris; + int* indices; + double ax, ay, bx, by, cx, cy, cross; + double px, py, d0x, d0y, d1x, d1y, d2x, d2y; + double t, u; + int n, i, j, prev, curr, next, count; + MwBool ear_found, is_ear; -#define PACK(dst, pts, idx) \ - do { \ - (dst).x = pixman_int_to_fixed((pts)[(idx)].x); \ - (dst).y = pixman_int_to_fixed((pts)[(idx)].y); \ - } while(0) + *tri_count_out = 0; -typedef struct { - int a, b, c; - double cx, cy, r2; /* circumcircle centre + radius^2 */ -} triangle; - -typedef struct { - MwPoint pts[MAXPTS + 3]; - int npts; - triangle tris[MAXTRI]; - int ntris; - int bad[MAXTRI]; - int nbad; - MwPoint edges[MAXTRI * 3]; - int nedges; -} triangulation_state; - -static void circumcircle(triangulation_state* s, int t) { - double ax = s->pts[s->tris[t].a].x, ay = s->pts[s->tris[t].a].y; - double bx = s->pts[s->tris[t].b].x, by = s->pts[s->tris[t].b].y; - double cx = s->pts[s->tris[t].c].x, cy = s->pts[s->tris[t].c].y; - double D = 2.0 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by)); - double ux, uy; - if(fabs(D) < EPS) { - s->tris[t].r2 = 1e30; - return; + if(!poly_points || poly_points_count < 3) { + return NULL; } - ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / D; - uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / D; - s->tris[t].cx = ux; - s->tris[t].cy = uy; - s->tris[t].r2 = (ax - ux) * (ax - ux) + (ay - uy) * (ay - uy); -} -static int in_circumcircle(triangulation_state* s, int t, int p) { - double dx = s->pts[p].x - s->tris[t].cx; - double dy = s->pts[p].y - s->tris[t].cy; - return dx * dx + dy * dy < s->tris[t].r2 - EPS; -} - -static void add_tri(triangulation_state* s, int a, int b, int c) { - s->tris[s->ntris].a = a; - s->tris[s->ntris].b = b; - s->tris[s->ntris].c = c; - circumcircle(s, s->ntris); - s->ntris++; -} - -static void remove_tri(triangulation_state* s, int i) { - s->tris[i] = s->tris[--s->ntris]; -} - -static int delaunay(MwPoint* src, int npts, - pixman_triangle_t* out, int out_size) { - triangulation_state s; - int si, i, j, k; - double mnx, mxx, mny, mxy, dx, dy, dmx, mx, my; - - if(npts < 3 || npts > MAXPTS) return -1; - - s.npts = npts; - memcpy(s.pts, src, npts * sizeof(MwPoint)); - - /* super-triangle */ - mnx = mxx = s.pts[0].x; - mny = mxy = s.pts[0].y; - for(i = 1; i < npts; i++) { - if(s.pts[i].x < mnx) mnx = s.pts[i].x; - if(s.pts[i].x > mxx) mxx = s.pts[i].x; - if(s.pts[i].y < mny) mny = s.pts[i].y; - if(s.pts[i].y > mxy) mxy = s.pts[i].y; + n = poly_points_count; + indices = malloc(n * sizeof(int)); + if(!indices) { + return NULL; + } + for(i = 0; i < n; i++) { + indices[i] = i; } - dx = mxx - mnx; - dy = mxy - mny; - dmx = (dx > dy) ? dx : dy; - mx = (mnx + mxx) * 0.5; - my = (mny + mxy) * 0.5; - si = npts; - s.pts[si].x = mx - 20.0 * dmx; - s.pts[si].y = my - dmx; - s.pts[si + 1].x = mx; - s.pts[si + 1].y = my + 20.0 * dmx; - s.pts[si + 2].x = mx + 20.0 * dmx; - s.pts[si + 2].y = my - dmx; + tris = malloc((n - 2) * sizeof(pixman_triangle_t)); + if(!tris) { + free(indices); + return NULL; + } - s.ntris = 0; - add_tri(&s, si, si + 1, si + 2); + count = 0; + while(n > 2) { + ear_found = MwFALSE; - /* insert each point */ - for(i = 0; i < npts; i++) { - s.nbad = 0; - for(j = 0; j < s.ntris; j++) - if(in_circumcircle(&s, j, i)) - s.bad[s.nbad++] = j; + for(i = 0; i < n; i++) { + prev = (i + n - 1) % n; + curr = i; + next = (i + 1) % n; + ax = (double)poly_points[indices[prev]].x; + ay = (double)poly_points[indices[prev]].y; + bx = (double)poly_points[indices[curr]].x; + by = (double)poly_points[indices[curr]].y; + cx = (double)poly_points[indices[next]].x; + cy = (double)poly_points[indices[next]].y; - s.nedges = 0; - for(j = 0; j < s.nbad; j++) { - int ea[3][2]; - ea[0][0] = s.tris[s.bad[j]].a; - ea[0][1] = s.tris[s.bad[j]].b; - ea[1][0] = s.tris[s.bad[j]].b; - ea[1][1] = s.tris[s.bad[j]].c; - ea[2][0] = s.tris[s.bad[j]].c; - ea[2][1] = s.tris[s.bad[j]].a; - for(k = 0; k < 3; k++) { - int m, shared = 0; - for(m = 0; m < s.nbad; m++) { - if(m == j) continue; - if((s.tris[s.bad[m]].a == ea[k][0] || s.tris[s.bad[m]].b == ea[k][0] || s.tris[s.bad[m]].c == ea[k][0]) && - (s.tris[s.bad[m]].a == ea[k][1] || s.tris[s.bad[m]].b == ea[k][1] || s.tris[s.bad[m]].c == ea[k][1])) { - shared = 1; - break; - } + cross = (bx - ax) * (cy - ay) - (by - ay) * (cx - ax); + if(cross <= 0.0) { + continue; + } + + is_ear = MwTRUE; + for(j = 0; j < n; j++) { + if(j == prev || j == curr || j == next) { + continue; } - if(!shared) { - s.edges[s.nedges].x = ea[k][0]; - s.edges[s.nedges].y = ea[k][1]; - s.nedges++; + + px = (double)poly_points[indices[j]].x; + py = (double)poly_points[indices[j]].y; + d0x = cx - ax; + d0y = cy - ay; + d1x = bx - ax; + d1y = by - ay; + d2x = px - ax; + d2y = py - ay; + t = (d0x * d2y - d0y * d2x) / (d0x * d1y - d0y * d1x + 1e-10); + u = (d1x * d2y - d1y * d2x) / (d0x * d1y - d0y * d1x + 1e-10); + if(t >= 0.0 && u >= 0.0 && (t + u) <= 1.0) { + is_ear = MwFALSE; + break; } } + + if(is_ear) { + pixman_triangle_t* tri; + + tri = &tris[count++]; + tri->p1.x = pixman_int_to_fixed(poly_points[indices[prev]].x); + tri->p1.y = pixman_int_to_fixed(poly_points[indices[prev]].y); + tri->p2.x = pixman_int_to_fixed(poly_points[indices[curr]].x); + tri->p2.y = pixman_int_to_fixed(poly_points[indices[curr]].y); + tri->p3.x = pixman_int_to_fixed(poly_points[indices[next]].x); + tri->p3.y = pixman_int_to_fixed(poly_points[indices[next]].y); + + for(j = curr; j < n - 1; j++) { + indices[j] = indices[j + 1]; + } + + n--; + ear_found = MwTRUE; + break; + } } - for(j = s.nbad - 1; j >= 0; j--) - remove_tri(&s, s.bad[j]); - - for(j = 0; j < s.nedges; j++) - add_tri(&s, s.edges[j].x, s.edges[j].y, i); + if(!ear_found) { + break; + } } - /* remove triangles touching the super-triangle */ - for(i = s.ntris - 1; i >= 0; i--) - if(s.tris[i].a >= npts || s.tris[i].b >= npts || s.tris[i].c >= npts) - remove_tri(&s, i); + free(indices); - if(s.ntris > out_size) return -1; - - /* pack into pixman_triangle_t */ - for(i = 0; i < s.ntris; i++) { - PACK(out[i].p1, s.pts, s.tris[i].a); - PACK(out[i].p2, s.pts, s.tris[i].b); - PACK(out[i].p3, s.pts, s.tris[i].c); + if(count == 0) { + free(tris); + return NULL; } - return s.ntris; + + if(count < poly_points_count - 2) { + pixman_triangle_t* shrunk; + + shrunk = realloc(tris, count * sizeof(pixman_triangle_t)); + if(shrunk) { + tris = shrunk; + } + } + + *tri_count_out = count; + return tris; } static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - int n, i; - pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; - pixman_image_t* image = pixman_image_create_solid_fill(&col); - pixman_triangle_t out[MAXTRI]; + int n, i; + pixman_color_t col = {color->common.red * 0xFF, color->common.green * 0xFF, color->common.blue * 0xFF, 0xffff}; + pixman_image_t* image = pixman_image_create_solid_fill(&col); + pixman_triangle_t* triangles; + pointf64_t* f64points = malloc(points_count * sizeof(pointf64_t)); + for(i = 0; i < points_count; i++) { + f64points[i].x = points[i].x; + f64points[i].y = points[i].y; + } + triangles = triangulate_polygon(f64points, points_count, &n); - n = delaunay(points, points_count, out, MAXTRI); - - pixman_composite_triangles(PIXMAN_OP_OVER, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, points_count, out); + pixman_composite_triangles(PIXMAN_OP_OVER, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, n, triangles); pixman_image_unref(image); From f2afa16bfae470645ca82923f60de4c1cd977cee Mon Sep 17 00:00:00 2001 From: IoI_xD Date: Mon, 13 Apr 2026 11:26:33 -0700 Subject: [PATCH 14/14] small typing fixes --- src/backend/wayland.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 48b22f9..df05dce 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -2113,12 +2113,12 @@ pixman_triangle_t* triangulate_polygon(pointf64_t* poly_points, int poly_points_ pixman_triangle_t* tri; tri = &tris[count++]; - tri->p1.x = pixman_int_to_fixed(poly_points[indices[prev]].x); - tri->p1.y = pixman_int_to_fixed(poly_points[indices[prev]].y); - tri->p2.x = pixman_int_to_fixed(poly_points[indices[curr]].x); - tri->p2.y = pixman_int_to_fixed(poly_points[indices[curr]].y); - tri->p3.x = pixman_int_to_fixed(poly_points[indices[next]].x); - tri->p3.y = pixman_int_to_fixed(poly_points[indices[next]].y); + tri->p1.x = pixman_double_to_fixed(poly_points[indices[prev]].x); + tri->p1.y = pixman_double_to_fixed(poly_points[indices[prev]].y); + tri->p2.x = pixman_double_to_fixed(poly_points[indices[curr]].x); + tri->p2.y = pixman_double_to_fixed(poly_points[indices[curr]].y); + tri->p3.x = pixman_double_to_fixed(poly_points[indices[next]].x); + tri->p3.y = pixman_double_to_fixed(poly_points[indices[next]].y); for(j = curr; j < n - 1; j++) { indices[j] = indices[j + 1]; @@ -2169,6 +2169,7 @@ static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLL pixman_composite_triangles(PIXMAN_OP_OVER, image, handle->wayland.framebuffer.pixman_fb, PIXMAN_a8, 0, 0, 0, 0, n, triangles); + free(triangles); pixman_image_unref(image); handle->wayland.events_pending = 1;