From f68b9a9aaef71d5b9d9a9e01132b678cee0c27b4 Mon Sep 17 00:00:00 2001 From: IoIxD Date: Sun, 14 Dec 2025 17:04:35 -0700 Subject: [PATCH 1/6] remove egl stuff from wayland to make way for a software renderer lmao --- Makefile.pl | 6 +- include/Mw/LowLevel/Wayland.h | 47 ++-- pl/ostype/Linux.pl | 6 +- pl/rules.pl | 12 +- src/backend/wayland.c | 453 ++++++++++------------------------ src/widget/opengl.c | 22 +- 6 files changed, 170 insertions(+), 376 deletions(-) diff --git a/Makefile.pl b/Makefile.pl index 6eba069..2d42299 100755 --- a/Makefile.pl +++ b/Makefile.pl @@ -56,14 +56,16 @@ my %features = ( "vulkan" => "build Vulkan widget", "vulkan-string-helper" => "use Vulkan string helper", "shared" => "build shared library", - "static" => "build static library" + "static" => "build static library", + "experimental-wayland" => "enable WIP wayland backend", ); my @features_keys = ( "1classic-theme", "1stb-image", "1stb-truetype", "1freetype2", "1opengl", "2xrender", "1vulkan", "2vulkan-string-helper", - "1shared", "1static" + "1shared", "1static", + "1experimental-wayland" ); foreach my $l (@ARGV) { diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index af80f47..394facf 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -53,15 +53,27 @@ struct _MwLLWaylandTopLevel { MwBool xdg_surface_created; }; +struct _MwLLWaylandSublevel { + struct wl_subsurface* subsurface; + struct wl_subcompositor* subcompositor; + + MwLL parent; + MwLL topmost_parent; /* The parent at the top of all the other parents. Usually a toplevel. */ +}; + struct _MwLLWayland { struct _MwLLCommon common; - /* Pointer for data that's only loaded if the widget is a toplevel */ - struct _MwLLWaylandTopLevel* toplevel; + union { + /* Pointer for data that's only loaded if the widget is a toplevel */ + struct _MwLLWaylandTopLevel* toplevel; + /* Pointer for data that's only loaded if the widget is a sublevel */ + struct _MwLLWaylandSublevel* sublevel; + }; enum { MWLL_WAYLAND_TOPLEVEL = 0, - MWLL_WAYLAND_SUBLEVEL = 1, /* Sublevels are surfaces that have the toplevel as a parent. They could be implemented as subsurfaces if we ever switch away from OpenGL. Some parts of the code also call them subwidgets. */ + MWLL_WAYLAND_SUBLEVEL, /* Sublevels are surfaces that have the toplevel as a parent. Some parts of the code also call them subwidgets. */ } type; /* Map of Wayland interfaces to their relevant setup functions. */ @@ -79,33 +91,22 @@ struct _MwLLWayland { struct wl_display* display; struct wl_registry* registry; struct wl_compositor* compositor; - struct wl_subcompositor* subcompositor; struct wl_surface* surface; struct wl_registry_listener registry_listener; - struct wl_event_queue* event_queue; - - EGLNativeWindowType egl_window_native; - EGLDisplay egl_display; - EGLContext egl_context; - EGLSurface egl_surface; - EGLConfig egl_config; + /*struct wl_event_queue* event_queue;*/ MwLL* sublevels; /* stb_ds managed array of any sublevels */ MwBool configured; /* Whether or not xdg_toplevel_configure has run once */ - MwBool egl_setup; /* Whether or not EGL has been set up */ - MwBool has_set_xy /* Whether or not MwSetXY has been called */; - int resize_counter; /* Counter that's for a hack in event_loop */ - MwU32 x, y, ww, wh; /* Window position */ - MwU32 lw, lh; /* Last known window position */ - MwPoint cur_mouse_pos; /* Currently known mouse position */ + MwU32 x, y, ww, wh; /* Window position */ + MwPoint cur_mouse_pos; /* Currently known mouse position */ - struct timeval timer; - MwU64 cooldown_timer; - MwU64 cooldown_timer_epoch; - - MwLL parent; - MwLL topmost_parent; /* The parent at the top of all the other parents. Usually a toplevel. */ + struct wl_shm* shm; + struct wl_shm_pool* shm_pool; + struct wl_buffer* shm_buffer; + void* mapped_shm_buf; + MwU64 mapped_shm_buf_size; + int shm_fd; }; struct _MwLLWaylandColor { diff --git a/pl/ostype/Linux.pl b/pl/ostype/Linux.pl index f695e4f..d87b738 100644 --- a/pl/ostype/Linux.pl +++ b/pl/ostype/Linux.pl @@ -1,3 +1,7 @@ -use_backend("x11"); +if(param_get("experimental-wayland")) { + use_backend("wayland","x11"); +} else { + use_backend("x11"); +} 1; diff --git a/pl/rules.pl b/pl/rules.pl index ab5521b..96d7a8e 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -29,21 +29,15 @@ if (grep(/^gdi$/, @backends)) { if (grep(/^wayland$/, @backends)) { add_cflags("-DUSE_WAYLAND"); new_object("src/backend/wayland.c"); - if ($cross) { - add_libs("-lGL -lEGL -lwayland-egl -lwayland-client -lxkbcommon"); - } - else { - add_libs("-lGL -lEGL"); - add_cflags(`pkg-config --cflags wayland-egl wayland-client xkbcommon`); - add_libs(`pkg-config --libs wayland-egl wayland-client xkbcommon`); - } + add_cflags(`pkg-config --cflags wayland-client xkbcommon`); + add_libs(`pkg-config --libs wayland-client xkbcommon`); scan_wayland_protocol("stable", "xdg-shell", ""); scan_wayland_protocol("stable", "tablet", "-v2"); scan_wayland_protocol("staging", "cursor-shape", "-v1"); scan_wayland_protocol("unstable", "xdg-decoration", "-unstable-v1"); - $gl_libs = "-lGL -lGLU"; + $gl_libs = "-lEGL -lwayland-egl lGL -lGLU"; } if (param_get("stb-image")) { diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 307e1ee..016456b 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -6,7 +6,6 @@ #include "../../external/stb_ds.h" #include -#include #include /* TODO: find out what FreeBSD and such wants us to include */ @@ -18,19 +17,6 @@ #include #endif -/* - * TODO: - * make sure MwLLDestroy is finished (+ handle dropdown bug that results from it) - * GNOME doesn't want to support zxdg_decoration_protocol so we're gonna design some Windows 95 ass ui just for that window manager. - * finish the rest of the owl - */ - -/* - * Redraw `handle` if the given cooldown hasn't expired (`time` >= `cooldown_timer` + `cooldown)). - * Used for pointer callbacks, resize callbacks, etc. to ensure we only resize every x milliseconds - */ -static void timed_redraw(MwLL handle, MwU32 time, int cooldown, MwU64* cooldown_timer); - /* Get the registered interface from r, or NULL if it doesn't currently have it. */ #define WAYLAND_GET_INTERFACE(handle, inter) shget(handle.wl_protocol_map, inter##_interface.name) @@ -78,7 +64,7 @@ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time p.point = self->wayland.cur_mouse_pos; MwLLDispatch(self, move, &p); - timed_redraw(self, time, 50, &self->wayland.cooldown_timer); + /*timed_redraw(self, time, 50, &self->wayland.cooldown_timer);*/ }; /* `wl_pointer.button` callback */ @@ -144,17 +130,6 @@ static void recursive_key_released(MwLL handle, void* ud) { } } -/* Recursively dispatch the draw event to `handle` and its children */ -static void recursive_draw(MwLL handle) { - int i; - if(handle->wayland.sublevels != NULL) { - for(i = 0; i < arrlen(handle->wayland.sublevels); i++) { - MwLLDispatch(handle->wayland.sublevels[i], draw, NULL); - recursive_draw(handle->wayland.sublevels[i]); - } - } -} - /* `wl_keyboard.keymap` callback */ static void keyboard_keymap(void* data, struct wl_keyboard* wl_keyboard, @@ -350,7 +325,7 @@ static wayland_protocol_t* wl_compositor_setup(MwU32 name, struct _MwLLWayland* /* wl_subcompositor setup function */ static wayland_protocol_t* wl_subcompositor_setup(MwU32 name, struct _MwLLWayland* wayland) { - wayland->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); + wayland->sublevel->subcompositor = wl_registry_bind(wayland->registry, name, &wl_subcompositor_interface, 1); return NULL; } @@ -398,129 +373,6 @@ static wayland_protocol_t* zxdg_decoration_manager_v1_setup(MwU32 name, struct _ return proto; } -/* EGL Setup function */ -static MwBool egl_setup(MwLL self, int x, int y, int width, int height) { - int err; - EGLint numConfigs; - EGLint majorVersion; - EGLint minorVersion; - EGLContext context; - EGLSurface surface; - EGLint fbAttribs[] = - { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - EGL_NONE}; - EGLint contextAttribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 1, - EGL_CONTEXT_MAJOR_VERSION, 1, - EGL_CONTEXT_MINOR_VERSION, 1, - EGL_NONE}; - - EGLDisplay display; - display = eglGetDisplay(self->wayland.display); - if(display == EGL_NO_DISPLAY) { - printf("ERROR: eglGetDisplay, %0X\n", eglGetError()); - return MwFALSE; - } - /* Initialize EGL */ - if(!eglInitialize(display, &majorVersion, &minorVersion)) { - printf("ERROR: eglInitialize, %0X\n", eglGetError()); - return MwFALSE; - } - - /* Get configs */ - if((eglGetConfigs(display, NULL, 0, &numConfigs) != EGL_TRUE) || (numConfigs == 0)) { - printf("ERROR: eglGetConfigs, %0X\n", eglGetError()); - return MwFALSE; - } - - /* Choose config */ - if((eglChooseConfig(display, fbAttribs, &self->wayland.egl_config, 1, &numConfigs) != EGL_TRUE) || (numConfigs != 1)) { - printf("ERROR: eglChooseConfig, %0X\n", eglGetError()); - return MwFALSE; - } - - self->wayland.egl_window_native = - wl_egl_window_create(self->wayland.surface, width, height); - if(self->wayland.egl_window_native == EGL_NO_SURFACE) { - printf("ERROR: wl_egl_window_create, EGL_NO_SURFACE\n"); - return MwFALSE; - } - - /* Create a surface */ - surface = eglCreateWindowSurface(display, self->wayland.egl_config, self->wayland.egl_window_native, NULL); - if(surface == EGL_NO_SURFACE) { - printf("ERROR: eglCreateWindowSurface, %0X\n", eglGetError()); - return MwFALSE; - } - - eglBindAPI(EGL_OPENGL_API); - - /* Create a GL context */ - context = eglCreateContext(display, self->wayland.egl_config, EGL_NO_CONTEXT, contextAttribs); - if(context == EGL_NO_CONTEXT) { - printf("ERROR: eglCreateContext, %0X\n", eglGetError()); - return MwFALSE; - } - - self->wayland.egl_display = display; - self->wayland.egl_surface = surface; - self->wayland.egl_context = context; - - if(self->wayland.parent == NULL) { - if(!eglMakeCurrent(self->wayland.egl_display, self->wayland.egl_surface, self->wayland.egl_surface, self->wayland.egl_context)) { - printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); - } - } - - glEnable(GL_TEXTURE_2D); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glEnable(GL_SCISSOR_TEST); - - return MwTRUE; -} - -/* EGL reconfiguration function for resizes */ -static void egl_resetup(MwLL handle) { - float w, h; - - if(handle->wayland.parent == NULL) { - w = handle->wayland.ww; - h = handle->wayland.wh; - } else { - w = handle->wayland.parent->wayland.ww; - h = handle->wayland.parent->wayland.wh; - } - - glViewport(handle->wayland.x, handle->wayland.y, w, h); - glScissor(handle->wayland.x, handle->wayland.y, w, h); -} - -static void timed_redraw(MwLL handle, MwU32 time, int cooldown, MwU64* cooldown_timer) { - if(handle->wayland.parent == NULL) { - if(time >= (*cooldown_timer + cooldown)) { - egl_resetup(handle); - MwLLDispatch(handle, draw, NULL); - *cooldown_timer = time; - } - } -} - -/* Same as timed_redraw but it uses the unix epoch as the cooldown timer. */ -static void timed_redraw_by_epoch(MwLL handle, int cooldown) { - gettimeofday(&handle->wayland.timer, NULL); - unsigned long long time = - (unsigned long long)(handle->wayland.timer.tv_sec) * 1000 + - (unsigned long long)(handle->wayland.timer.tv_usec) / 1000; - timed_redraw(handle, time, cooldown, &handle->wayland.cooldown_timer_epoch); -} - /* `xdg_toplevel.close` callback */ static void xdg_toplevel_configure(void* data, struct xdg_toplevel* xdg_toplevel, @@ -543,12 +395,12 @@ static void xdg_toplevel_configure(void* data, MwLLDispatch(self, resize, NULL); - if(!self->wayland.egl_setup) { + /*if(!self->wayland.egl_setup) { self->wayland.egl_setup = egl_setup(self, self->wayland.x, self->wayland.y, width, height); } else { wl_egl_window_resize(self->wayland.egl_window_native, width, height, 0, 0); egl_resetup(self); - } + }*/ return; }; @@ -580,6 +432,58 @@ static void xdg_surface_configure( self->wayland.configured = MwTRUE; } +/* wl_shm setup function */ +static wayland_protocol_t* wl_shm_setup(MwU32 name, struct _MwLLWayland* wayland) { + int x, y; + int stride = wayland->ww * 4; + char temp_name[] = "/tmp/milsko-wl-shm-XXXXXX"; + + wayland->mapped_shm_buf_size = wayland->ww * wayland->wh * 4; + + wayland->shm = wl_registry_bind(wayland->registry, name, &wl_shm_interface, 1); + + wayland->shm_fd = mkstemp(temp_name); + + unlink(temp_name); + + if(posix_fallocate(wayland->shm_fd, 0, wayland->mapped_shm_buf_size) != 0) { + printf("failure setting up wl_shm: could not fallocate. %s.\n", strerror(errno)); + close(wayland->shm_fd); + return NULL; + } + if(ftruncate(wayland->shm_fd, wayland->mapped_shm_buf_size) != 0) { + printf("failure setting up wl_shm: could not truncate. %s.\n", strerror(errno)); + close(wayland->shm_fd); + return NULL; + } + + wayland->mapped_shm_buf = mmap(NULL, wayland->mapped_shm_buf_size, PROT_WRITE, MAP_SHARED, wayland->shm_fd, 0); + + fsync(wayland->shm_fd); + + if(!(wayland->shm_pool = wl_shm_create_pool(wayland->shm, wayland->shm_fd, wayland->mapped_shm_buf_size))) { + printf("failure setting up wl_shm: could not create pool.\n"); + } + + wayland->shm_buffer = wl_shm_pool_create_buffer(wayland->shm_pool, 0, wayland->ww, wayland->wh, stride, WL_SHM_FORMAT_ARGB8888); + + if(wayland->configured) { + wl_surface_attach(wayland->surface, wayland->shm_buffer, 0, 0); + wl_surface_commit(wayland->surface); + } + + return NULL; +} + +static void update_buffer(MwLL handle) { + fsync(handle->wayland.shm_fd); + + if(handle->wayland.configured) { + wl_surface_attach(handle->wayland.surface, handle->wayland.shm_buffer, 0, 0); + wl_surface_commit(handle->wayland.surface); + } +} + /* Standard Wayland event loop. */ static int event_loop(MwLL handle) { enum { @@ -588,9 +492,8 @@ static int event_loop(MwLL handle) { CURSOR_FD }; struct pollfd fd; - int timeout = 100; - struct _MwLLWayland* wayland = &handle->wayland; - MwLL topmost_parent = handle->wayland.parent; + int timeout = 1; + struct _MwLLWayland* wayland = &handle->wayland; if(wayland->display == NULL) { return 0; @@ -598,6 +501,12 @@ static int event_loop(MwLL handle) { fd.fd = wl_display_get_fd(wayland->display); fd.events = POLLIN; + while(wl_display_prepare_read(handle->wayland.display) != 0) { + if(wl_display_dispatch_pending(handle->wayland.display) > 0) { + return 0; + } + } + /* If an error other than EAGAIN happens, we have likely been disconnected from the Wayland session */ while(wl_display_flush(wayland->display) == -1) { if(errno != EAGAIN) { @@ -614,33 +523,23 @@ static int event_loop(MwLL handle) { } } + /* Condition where no events are being sent. */ + if(!poll(&fd, 1, timeout)) { + wl_display_cancel_read(handle->wayland.display); + /* In this case, we need to commit the surface for any animations, etc. */ + wl_surface_commit(handle->wayland.surface); + return 0; + } + if(fd.revents & POLLIN) { wl_display_read_events(wayland->display); if(wl_display_dispatch_pending(wayland->display) > 0) { } } else { - /* Condition for no events being sent */ - if(wl_display_dispatch_pending(wayland->display) == 0) { - if(wayland->event_queue != NULL) { - if(wl_display_roundtrip_queue(wayland->display, wayland->event_queue) < 0) { - printf("error\n"); - }; - } - /* HACK: If the last known size is different, force a redraw */ - if(wayland->lw != wayland->ww || wayland->lh != wayland->wh) { - MwLLDispatch(handle, draw, 0); - wayland->resize_counter++; - if(wayland->resize_counter >= 5) { - wayland->lw = wayland->ww; - wayland->lh = wayland->wh; - wayland->lh = wayland->wh; - wayland->resize_counter = 0; - } - } - } + wl_display_cancel_read(handle->wayland.display); } - return 0; + return 1; } /* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ @@ -655,13 +554,15 @@ static void setup_callbacks(struct _MwLLWayland* wayland) { wayland->wl_protocol_setup_map = NULL; wayland->wl_protocol_map = NULL; + WL_INTERFACE(wl_shm); WL_INTERFACE(wl_compositor); - WL_INTERFACE(wl_subcompositor); WL_INTERFACE(wl_seat); if(wayland->type == MWLL_WAYLAND_TOPLEVEL) { WL_INTERFACE(xdg_wm_base); WL_INTERFACE(zxdg_decoration_manager_v1); WL_INTERFACE(wp_cursor_shape_manager_v1); + } else { + WL_INTERFACE(wl_subcompositor); } #undef WL_INTERFACE } @@ -670,9 +571,8 @@ static void setup_callbacks(struct _MwLLWayland* wayland) { static void setup_toplevel(MwLL r, int x, int y) { int i; - r->wayland.type = MWLL_WAYLAND_TOPLEVEL; - r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel)); - r->wayland.topmost_parent = NULL; + r->wayland.type = MWLL_WAYLAND_TOPLEVEL; + r->wayland.toplevel = malloc(sizeof(struct _MwLLWaylandTopLevel)); setup_callbacks(&r->wayland); @@ -731,27 +631,17 @@ static void setup_toplevel(MwLL r, int x, int y) { printf("zxdg null\n"); } - r->wayland.event_queue = wl_display_create_queue(r->wayland.display); - - egl_resetup(r); + /*egl_resetup(r); MwLLDispatch(r, draw, NULL); - recursive_draw(r); + recursive_draw(r);*/ } /* Sublevel setup function */ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) { - struct wl_compositor* compositor = parent->wayland.compositor; - struct wl_subcompositor* subcompositor = parent->wayland.subcompositor; - struct wl_surface* parent_surface = parent->wayland.surface; - struct wl_region* region; - { - MwLL topmost_parent = parent; + struct wl_compositor* compositor = parent->wayland.compositor; + struct wl_surface* parent_surface = parent->wayland.surface; - while(topmost_parent->wayland.type != MWLL_WAYLAND_TOPLEVEL) { - topmost_parent = topmost_parent->wayland.parent; - } - r->wayland.topmost_parent = topmost_parent; - } + r->wayland.sublevel = malloc(sizeof(struct _MwLLWaylandSublevel)); r->wayland.type = MWLL_WAYLAND_SUBLEVEL; @@ -759,17 +649,12 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) { r->wayland.surface = wl_compositor_create_surface(compositor); - region = wl_compositor_create_region(compositor); - wl_region_add(region, 0, 0, r->wayland.ww, r->wayland.wh); - wl_surface_set_opaque_region(r->wayland.surface, region); - wl_surface_commit(r->wayland.surface); - event_loop(r); - wl_region_destroy(region); - setup_callbacks(&r->wayland); - r->wayland.registry = wl_display_get_registry(r->wayland.topmost_parent->wayland.display); - r->wayland.display = r->wayland.topmost_parent->wayland.display; + // printf("position %d %d\n", x, y); + + r->wayland.registry = wl_display_get_registry(parent->wayland.display); + r->wayland.display = parent->wayland.display; wl_registry_add_listener(r->wayland.registry, &r->wayland.registry_listener, r); if(wl_display_roundtrip(r->wayland.display) == -1) { @@ -778,23 +663,11 @@ static void setup_sublevel(MwLL parent, MwLL r, int x, int y) { return; } + r->wayland.sublevel->subsurface = wl_subcompositor_get_subsurface(r->wayland.sublevel->subcompositor, r->wayland.surface, parent_surface); + + wl_subsurface_set_position(r->wayland.sublevel->subsurface, x, y); + r->wayland.configured = MwTRUE; - if(!r->wayland.egl_setup) { - r->wayland.egl_setup = egl_setup(r, r->wayland.x, r->wayland.y, r->wayland.ww, r->wayland.wh); - egl_resetup(r); - MwLLDispatch(r, draw, NULL); - recursive_draw(r); - }; - - r->wayland.event_queue = parent->wayland.event_queue; - - arrpush(parent->wayland.sublevels, r); - - wl_surface_damage(parent->wayland.surface, 0, 0, parent->wayland.ww, parent->wayland.wh); - - egl_resetup(r->wayland.topmost_parent); - MwLLDispatch(r->wayland.topmost_parent, draw, NULL); - recursive_draw(r->wayland.topmost_parent); } static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { @@ -819,12 +692,6 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->wayland.x = x; r->wayland.y = y; - r->wayland.parent = parent; - - r->wayland.cooldown_timer = 0; - r->wayland.has_set_xy = MwFALSE; - r->wayland.resize_counter = 0; - r->wayland.sublevels = NULL; if(parent == NULL) { @@ -833,12 +700,21 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { setup_sublevel(parent, r, x, y); } + /* example of writing to the buffer */ + memset(r->wayland.mapped_shm_buf, 127, r->wayland.mapped_shm_buf_size); + update_buffer(r); + return r; } static void MwLLDestroyImpl(MwLL handle) { MwLLDestroyCommon(handle); + munmap(handle->wayland.mapped_shm_buf, handle->wayland.mapped_shm_buf_size); + wl_buffer_destroy(handle->wayland.mapped_shm_buf); + wl_shm_pool_destroy(handle->wayland.shm_pool); + close(handle->wayland.shm_fd); + free(handle); } @@ -853,111 +729,64 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) { if(handle->wayland.type != MWLL_WAYLAND_TOPLEVEL) { handle->wayland.x = x; handle->wayland.y = y; - if(handle->wayland.has_set_xy) { + /*if(handle->wayland.has_set_xy) { timed_redraw_by_epoch(handle->wayland.topmost_parent, 25); - /* recursive_draw(handle->wayland.topmost_parent); */ } else if(x != 0 && y != 0) { handle->wayland.has_set_xy = MwTRUE; - } + }*/ } } static void MwLLSetWHImpl(MwLL handle, int w, int h) { /* Prevent an integer underflow when the w/h is too low */ if((w < 10 || h < 10)) { - handle->wayland.ww = handle->wayland.lw = 10; - handle->wayland.wh = handle->wayland.lh = 10; + handle->wayland.ww = 10; + handle->wayland.wh = 10; return; } - handle->wayland.ww = handle->wayland.lw = w; - handle->wayland.wh = handle->wayland.lh = h; + handle->wayland.ww = w; + handle->wayland.wh = h; if(handle->wayland.type == MWLL_WAYLAND_TOPLEVEL) { xdg_surface_set_window_geometry(handle->wayland.toplevel->xdg_surface, 0, 0, handle->wayland.ww, handle->wayland.wh); } else { - timed_redraw_by_epoch(handle->wayland.topmost_parent, 25); - /* recursive_draw(handle->wayland.topmost_parent); */ + /* timed_redraw_by_epoch(handle->wayland.topmost_parent, 25); + recursive_draw(handle->wayland.topmost_parent); */ } } static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - int i, n; - float maxX = 0, maxY = 0; - float centerX, centerY; - float w, h; - - if(handle->wayland.parent == NULL) { - w = handle->wayland.ww; - h = handle->wayland.wh; - } else { - w = handle->wayland.topmost_parent->wayland.ww; - h = handle->wayland.topmost_parent->wayland.wh; - } - - glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); - - glBegin(GL_POLYGON); - - for(i = 0; i < points_count; i++) { - float x = ((float)(handle->wayland.x + points[i].x) / (w / 2)) - 1.0; - float y = 1.0 - ((float)(handle->wayland.y + points[i].y) / (h / 2)); - - glVertex2f(x, y); - } - glEnd(); - glColor3f(0, 0, 0); + /* todo */ } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - int i; - float w, h; - - if(handle->wayland.topmost_parent == NULL) { - w = handle->wayland.ww; - h = handle->wayland.wh; - } else { - w = handle->wayland.topmost_parent->wayland.ww; - h = handle->wayland.topmost_parent->wayland.wh; - } - - glLineWidth(1); - glColor3f(color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); - - glBegin(GL_LINES); - for(i = 0; i < 2; i++) { - float x = ((float)(handle->wayland.x + points[i].x) / (w / 2)) - 1.0; - float y = 1.0 - ((float)(handle->wayland.y + points[i].y) / (h / 2)); - - glVertex2f(x, y); - } - glEnd(); - glColor3f(0, 0, 0); + /* todo */ } static void MwLLBeginDrawImpl(MwLL handle) { - if(handle->wayland.parent == NULL) { - if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) { - printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); - return; - } - } + /* if(handle->wayland.parent == NULL) { + if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) { + printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); + return; + } + }*/ } static void MwLLEndDrawImpl(MwLL handle) { int w, h; - recursive_draw(handle); + /*recursive_draw(handle);*/ /* glClear(GL_COLOR_BUFFER_BIT); */ /* glClearColor(1.0, 0, 0, 1); */ - if(handle->wayland.parent == NULL) { + /* if(handle->wayland.parent == NULL) { if(!eglSwapBuffers(handle->wayland.egl_display, handle->wayland.egl_surface)) { - printf("error swapping buffers! %0X\n", eglGetError()); - } else { - wl_surface_commit(handle->wayland.surface); - } - } + printf("error swapping buffers! %0X\n", eglGetError()); + } else { + wl_surface_commit(handle->wayland.surface); + } +}*/ } static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { @@ -981,8 +810,6 @@ static void MwLLFreeColorImpl(MwLLColor color) { } static int MwLLPendingImpl(MwLL handle) { - if(wl_display_dispatch_pending(handle->wayland.display) == 0) { - } return event_loop(handle); } @@ -1029,35 +856,7 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - float x, y, w, h; - - if(handle->wayland.topmost_parent == NULL) { - w = handle->wayland.ww; - h = handle->wayland.wh; - } else { - w = handle->wayland.topmost_parent->wayland.ww; - h = handle->wayland.topmost_parent->wayland.wh; - } - - x = ((float)(handle->wayland.x + rect->x) / (w / 2)) - 1.0; - y = 1.0 - ((float)(handle->wayland.y + rect->y) / (h / 2)); - - glColor3f(1.0, 1.0, 1.0); - - glBindTexture(GL_TEXTURE_2D, pixmap->wayland.texture); - glActiveTexture(pixmap->wayland.texture); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0); - glVertex2f(x, y); - glTexCoord2f(1, 0); - glVertex2f(x + (rect->width / (w / 2)), y); - glTexCoord2f(1, 1); - glVertex2f(x + (rect->width / (w / 2)), y - (rect->height / (h / 2))); - glTexCoord2f(0.0f, 1); - glVertex2f(x, y - (rect->height / (h / 2))); - glEnd(); - glFinish(); + /* todo */ } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { } @@ -1065,9 +864,11 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { static void MwLLForceRenderImpl(MwLL handle) { wl_surface_damage(handle->wayland.surface, 0, 0, handle->wayland.ww, handle->wayland.wh); + /* if(handle->wayland.egl_setup) { timed_redraw_by_epoch(handle, 25); } + */ } static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { diff --git a/src/widget/opengl.c b/src/widget/opengl.c index f6cc369..9552ae4 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -1,12 +1,6 @@ #include #include -#ifdef USE_WAYLAND -#include -#include -#include -#endif - #ifdef USE_GDI typedef HGLRC(WINAPI* MWwglCreateContext)(HDC); typedef BOOL(WINAPI* MWwglMakeCurrent)(HDC, HGLRC); @@ -110,8 +104,8 @@ static int create(MwWidget handle) { } #endif #ifdef USE_WAYLAND - /* Wayland uses OpenGL as its backend so its already initialized */ if(handle->lowlevel->common.type == MwLLBackendWayland) { + /* todo */ } #endif @@ -146,7 +140,9 @@ static void destroy(MwWidget handle) { } #endif #ifdef USE_WAYLAND -/* Wayland uses OpenGL as its backend so its destroyed accordingly */ + if(handle->lowlevel->common.type == MwLLBackendWayland) { + /* todo */ + } #endif free(handle->internal); @@ -169,6 +165,7 @@ static void mwOpenGLMakeCurrentImpl(MwWidget handle) { #endif #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { + /* todo */ } #endif } @@ -189,14 +186,9 @@ static void mwOpenGLSwapBufferImpl(MwWidget handle) { } #endif #ifdef USE_WAYLAND -#define tp handle->lowlevel->wayland.topmost_parent->wayland if(handle->lowlevel->common.type == MwLLBackendWayland) { - if(!eglSwapBuffers( - tp.egl_display, tp.egl_surface)) { - printf("Userland error: eglSwapBuffers, %0X\n", eglGetError()); - } + /* todo */ } -#undef topmost_parent #endif } @@ -217,7 +209,7 @@ static void* mwOpenGLGetProcAddressImpl(MwWidget handle, const char* name) { #endif #ifdef USE_WAYLAND if(handle->lowlevel->common.type == MwLLBackendWayland) { - return eglGetProcAddress(name); + /* todo */ } #endif return NULL; From 4951e8995e4fd63dd6461544cf2c66a6ad7d5cc5 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 15 Dec 2025 09:31:33 +0900 Subject: [PATCH 2/6] remove egl dependency --- include/Mw/LowLevel/Wayland.h | 6 ------ src/backend/wayland.c | 18 +++--------------- 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index 394facf..cc334e0 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -12,10 +12,6 @@ #include #include -#include -#include -#include -#include #include #include @@ -115,8 +111,6 @@ struct _MwLLWaylandColor { struct _MwLLWaylandPixmap { struct _MwLLCommonPixmap common; - GLuint texture; - MwBool texture_deleted; }; #endif diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 016456b..be24dbc 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -827,17 +827,8 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid r->common.width = width; r->common.height = height; - r->common.raw = data; - r->wayland.texture = 0; - - glGenTextures(1, &r->wayland.texture); - - glBindTexture(GL_TEXTURE_2D, r->wayland.texture); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glBindTexture(GL_TEXTURE_2D, 0); + r->common.raw = malloc(4 * width * height); + memcpy(r->common.raw, data, 4 * width * height); MwLLPixmapUpdate(r); @@ -845,13 +836,10 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid } static void MwLLPixmapUpdateImpl(MwLLPixmap r) { - glBindTexture(GL_TEXTURE_2D, r->wayland.texture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, r->common.width, r->common.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, r->common.raw); - glBindTexture(GL_TEXTURE_2D, 0); + /* TODO */ } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { - glDeleteTextures(1, &pixmap->wayland.texture); free(pixmap); } From 7a81af99225da838bc7859eb8cc128c75e4d9ef8 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 15 Dec 2025 11:05:20 +0900 Subject: [PATCH 3/6] some stuffs work --- Makefile.pl | 7 ++- include/Mw/BaseTypes.h | 4 +- include/Mw/LowLevel/Wayland.h | 4 ++ pl/ostype/Linux.pl | 7 ++- pl/rules.pl | 4 +- src/backend/wayland.c | 108 ++++++++++++++++++++++------------ src/draw.c | 4 +- src/widget/frame.c | 1 - src/widget/listbox.c | 1 - src/widget/opengl.c | 3 +- src/widget/scrollbar.c | 8 +-- 11 files changed, 96 insertions(+), 55 deletions(-) diff --git a/Makefile.pl b/Makefile.pl index 2d42299..4f5d5d5 100755 --- a/Makefile.pl +++ b/Makefile.pl @@ -173,8 +173,11 @@ print(OUT "\n"); print(OUT "all: lib examples\n"); print(OUT "\n"); print(OUT "install: lib\n"); -print(OUT " mkdir -p \$(DESTDIR)\$(PREFIX)/lib \$(DESTDIR)\$(PREFIX)/include\n"); -print(OUT " -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n"); +print(OUT + " mkdir -p \$(DESTDIR)\$(PREFIX)/lib \$(DESTDIR)\$(PREFIX)/include\n"); +print(OUT +" -cp src/${library_prefix}Mw${library_suffix} \$(DESTDIR)\$(PREFIX)/lib/\n" +); print(OUT " -cp src/libMw.a \$(DESTDIR)\$(PREFIX)/lib/\n"); print(OUT " cp -rf include \$(DESTDIR)\$(PREFIX)/\n"); print(OUT "\n"); diff --git a/include/Mw/BaseTypes.h b/include/Mw/BaseTypes.h index ca718ea..1014869 100644 --- a/include/Mw/BaseTypes.h +++ b/include/Mw/BaseTypes.h @@ -58,8 +58,8 @@ typedef unsigned long MwU64; #ifdef MW_OTHER_TYPES_DEFINED #undef MW_OTHER_TYPES_DEFINED #else -typedef int MwI32; -typedef unsigned int MwU32; +typedef int MwI32; +typedef unsigned int MwU32; typedef short MwI16; typedef unsigned short MwU16; diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index cc334e0..b37bd45 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -15,6 +15,7 @@ #include #include +#include MWDECL int MwLLWaylandCallInit(void); @@ -103,6 +104,9 @@ struct _MwLLWayland { void* mapped_shm_buf; MwU64 mapped_shm_buf_size; int shm_fd; + + cairo_surface_t* cs; + cairo_t* cairo; }; struct _MwLLWaylandColor { diff --git a/pl/ostype/Linux.pl b/pl/ostype/Linux.pl index d87b738..155cd4a 100644 --- a/pl/ostype/Linux.pl +++ b/pl/ostype/Linux.pl @@ -1,6 +1,7 @@ -if(param_get("experimental-wayland")) { - use_backend("wayland","x11"); -} else { +if (param_get("experimental-wayland")) { + use_backend("wayland", "x11"); +} +else { use_backend("x11"); } diff --git a/pl/rules.pl b/pl/rules.pl index 96d7a8e..fc88c10 100644 --- a/pl/rules.pl +++ b/pl/rules.pl @@ -29,8 +29,8 @@ if (grep(/^gdi$/, @backends)) { if (grep(/^wayland$/, @backends)) { add_cflags("-DUSE_WAYLAND"); new_object("src/backend/wayland.c"); - add_cflags(`pkg-config --cflags wayland-client xkbcommon`); - add_libs(`pkg-config --libs wayland-client xkbcommon`); + add_cflags(`pkg-config --cflags cairo wayland-client xkbcommon`); + add_libs(`pkg-config --libs cairo wayland-client xkbcommon`); scan_wayland_protocol("stable", "xdg-shell", ""); scan_wayland_protocol("stable", "tablet", "-v2"); diff --git a/src/backend/wayland.c b/src/backend/wayland.c index be24dbc..b034ab4 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -38,20 +38,18 @@ static void new_protocol(void* data, struct wl_registry* registry, /* `wl_registry.global_remove` callback */ static void protocol_removed(void* data, struct wl_registry* registry, - MwU32 name) { + MwU32 name){ }; /* `wl_pointer.enter` callback */ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 serial, struct wl_surface* surface, wl_fixed_t surface_x, - wl_fixed_t surface_y) { -}; + wl_fixed_t surface_y){}; /* `wl_pointer.leave` callback */ static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial, - struct wl_surface* surface) { -}; + struct wl_surface* surface){}; /* `wl_pointer.motion` callback */ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time, @@ -93,12 +91,13 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri break; } } + MwLLDispatch(self, draw, NULL); }; /* `wl_pointer.axis` callback */ static void pointer_axis(void* data, struct wl_pointer* wl_pointer, MwU32 time, - MwU32 axis, wl_fixed_t value) {}; + MwU32 axis, wl_fixed_t value){}; struct wl_pointer_listener pointer_listener = { .enter = pointer_enter, @@ -267,7 +266,7 @@ static void keyboard_modifiers(void* data, MwU32 mods_depressed, MwU32 mods_latched, MwU32 mods_locked, - MwU32 group) {}; + MwU32 group){}; struct wl_keyboard_listener keyboard_listener = { .keymap = keyboard_keymap, @@ -279,7 +278,7 @@ struct wl_keyboard_listener keyboard_listener = { /* `wl_seat.name` callback */ static void -wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {}; +wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name){}; /* `wl_seat.capabilities` callback */ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat, @@ -393,7 +392,13 @@ static void xdg_toplevel_configure(void* data, self->wayland.wh = height; xdg_surface_set_window_geometry(self->wayland.toplevel->xdg_surface, 0, 0, self->wayland.ww, self->wayland.wh); + cairo_destroy(self->wayland.cairo); + cairo_surface_destroy(self->wayland.cs); + self->wayland.cs = cairo_image_surface_create_for_data(self->wayland.mapped_shm_buf, CAIRO_FORMAT_ARGB32, width, height, 4 * width); + self->wayland.cairo = cairo_create(self->wayland.cs); + MwLLDispatch(self, resize, NULL); + MwLLDispatch(self, draw, NULL); /*if(!self->wayland.egl_setup) { self->wayland.egl_setup = egl_setup(self, self->wayland.x, self->wayland.y, width, height); @@ -544,7 +549,6 @@ static int event_loop(MwLL handle) { /* Function for setting up the callbacks/structs that will be registered upon the relevant interfaces being found. */ static void setup_callbacks(struct _MwLLWayland* wayland) { - /* Convience macro for adding the interface functions to the setup map */ #define WL_INTERFACE(interface) \ shput(wayland->wl_protocol_setup_map, interface##_interface.name, (wl_setup_func*)interface##_setup); @@ -677,8 +681,8 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { r->common.type = MwLLBackendWayland; - if(width == 0) width = 1; - if(height == 0) height = 1; + if(width < 2) width = 2; + if(height < 2) height = 2; if(x == MwDEFAULT) { x = 0; @@ -701,15 +705,23 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { } /* example of writing to the buffer */ - memset(r->wayland.mapped_shm_buf, 127, r->wayland.mapped_shm_buf_size); + memset(r->wayland.mapped_shm_buf, 255, r->wayland.mapped_shm_buf_size); update_buffer(r); + r->wayland.cs = cairo_image_surface_create_for_data(r->wayland.mapped_shm_buf, CAIRO_FORMAT_ARGB32, width, height, 4 * width); + r->wayland.cairo = cairo_create(r->wayland.cs); + + MwLLForceRender(r); + return r; } static void MwLLDestroyImpl(MwLL handle) { MwLLDestroyCommon(handle); + cairo_destroy(handle->wayland.cairo); + cairo_surface_destroy(handle->wayland.cs); + munmap(handle->wayland.mapped_shm_buf, handle->wayland.mapped_shm_buf_size); wl_buffer_destroy(handle->wayland.mapped_shm_buf); wl_shm_pool_destroy(handle->wayland.shm_pool); @@ -734,7 +746,10 @@ static void MwLLSetXYImpl(MwLL handle, int x, int y) { } else if(x != 0 && y != 0) { handle->wayland.has_set_xy = MwTRUE; }*/ + + wl_subsurface_set_position(handle->wayland.sublevel->subsurface, x, y); } + MwLLDispatch(handle, draw, NULL); } static void MwLLSetWHImpl(MwLL handle, int w, int h) { @@ -753,40 +768,47 @@ static void MwLLSetWHImpl(MwLL handle, int w, int h) { /* timed_redraw_by_epoch(handle->wayland.topmost_parent, 25); recursive_draw(handle->wayland.topmost_parent); */ } + MwLLDispatch(handle, draw, NULL); } static void MwLLPolygonImpl(MwLL handle, MwPoint* points, int points_count, MwLLColor color) { - /* todo */ + int i; + + cairo_set_source_rgb(handle->wayland.cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); + cairo_new_path(handle->wayland.cairo); + for(i = 0; i < points_count; i++) { + if(i == 0) { + cairo_move_to(handle->wayland.cairo, points[i].x, points[i].y); + } else { + cairo_line_to(handle->wayland.cairo, points[i].x, points[i].y); + } + } + cairo_close_path(handle->wayland.cairo); + cairo_fill(handle->wayland.cairo); } static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) { - /* todo */ + int i; + + cairo_set_line_cap(handle->wayland.cairo, CAIRO_LINE_CAP_SQUARE); + cairo_set_source_rgb(handle->wayland.cairo, color->common.red / 255.0, color->common.green / 255.0, color->common.blue / 255.0); + cairo_new_path(handle->wayland.cairo); + for(i = 0; i < 2; i++) { + if(i == 0) { + cairo_move_to(handle->wayland.cairo, points[i].x, points[i].y); + } else { + cairo_line_to(handle->wayland.cairo, points[i].x, points[i].y); + } + } + cairo_close_path(handle->wayland.cairo); + cairo_stroke(handle->wayland.cairo); } static void MwLLBeginDrawImpl(MwLL handle) { - /* if(handle->wayland.parent == NULL) { - if(!eglMakeCurrent(handle->wayland.egl_display, handle->wayland.egl_surface, handle->wayland.egl_surface, handle->wayland.egl_context)) { - printf("ERROR: eglMakeCurrent, %0X\n", eglGetError()); - return; - } - }*/ } static void MwLLEndDrawImpl(MwLL handle) { - int w, h; - - /*recursive_draw(handle);*/ - - /* glClear(GL_COLOR_BUFFER_BIT); */ - /* glClearColor(1.0, 0, 0, 1); */ - - /* if(handle->wayland.parent == NULL) { - if(!eglSwapBuffers(handle->wayland.egl_display, handle->wayland.egl_surface)) { - printf("error swapping buffers! %0X\n", eglGetError()); - } else { - wl_surface_commit(handle->wayland.surface); - } -}*/ + update_buffer(handle); } static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { @@ -825,9 +847,9 @@ 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)); - r->common.width = width; - r->common.height = height; - r->common.raw = malloc(4 * width * height); + r->common.width = width; + r->common.height = height; + r->common.raw = malloc(4 * width * height); memcpy(r->common.raw, data, 4 * width * height); MwLLPixmapUpdate(r); @@ -840,11 +862,21 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) { } static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { + free(pixmap->common.raw); free(pixmap); } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - /* todo */ + int y, x; + for(y = rect->y; y < rect->y + rect->height; y++) { + if(y < 0 || y >= handle->wayland.wh) continue; + for(x = rect->x; x < rect->x + rect->width; x++) { + if(x < 0 || x >= handle->wayland.ww) continue; + + /* TODO */ + //((unsigned char*)handle->wayland.mapped_shm_buf)[(x + y * handle->wayland.ww) * 4 + 0] = 0x80; + } + } } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { } diff --git a/src/draw.c b/src/draw.c index 636dc78..f8489dc 100644 --- a/src/draw.c +++ b/src/draw.c @@ -109,7 +109,9 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { int ColorDiff = get_color_diff(handle); double darkenStep = (ColorDiff / 2.) / rect->height; unsigned long sz = rect->width * rect->height * 4; - unsigned char* data = malloc(sz); + unsigned char* data; + + data = malloc(sz); memset(data, 0, sz); for(y = 0; y < rect->height; y++) { diff --git a/src/widget/frame.c b/src/widget/frame.c index 38ff990..294f110 100644 --- a/src/widget/frame.c +++ b/src/widget/frame.c @@ -29,7 +29,6 @@ static void draw(MwWidget handle) { rr.width = MwGetInteger(handle, MwNwidth) - (MwDefaultBorderWidth(handle) * 2); rr.height = MwGetInteger(handle, MwNheight) - (MwDefaultBorderWidth(handle) * 2); } else { - rr.x = 0; rr.y = 0; rr.width = MwGetInteger(handle, MwNwidth); diff --git a/src/widget/listbox.c b/src/widget/listbox.c index 784594b..1841594 100644 --- a/src/widget/listbox.c +++ b/src/widget/listbox.c @@ -258,7 +258,6 @@ static void frame_draw(MwWidget handle) { if(j == (arrlen(lb->list[i].name) - 1)) p.x -= MwDefaultBorderWidth(handle); if(arrlen(lb->alignment) <= j || lb->alignment[j] == MwALIGNMENT_BEGINNING) { - p.x += 4; MwDrawText(handle, &p, str, 0, MwALIGNMENT_BEGINNING, selected ? base2 : text2); p.x -= 4; diff --git a/src/widget/opengl.c b/src/widget/opengl.c index 9552ae4..8c3b1ac 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -89,7 +89,8 @@ static int create(MwWidget handle) { attribs[3] = 24; attribs[4] = None; - while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL); + while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL) + ; o->glXChooseVisual = (MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual"); o->glXCreateContext = (MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext"); diff --git a/src/widget/scrollbar.c b/src/widget/scrollbar.c index e00d0b5..4058c81 100644 --- a/src/widget/scrollbar.c +++ b/src/widget/scrollbar.c @@ -144,7 +144,7 @@ static void draw(MwWidget handle) { } static void mouse_move(MwWidget handle) { - int or = MwGetInteger(handle, MwNorientation); + int or = MwGetInteger(handle, MwNorientation); scrollbar_t* scr = handle->internal; if(!handle->pressed) return; @@ -172,9 +172,9 @@ static void mouse_move(MwWidget handle) { } static void mouse_down(MwWidget handle, void* ptr) { - int ww = MwGetInteger(handle, MwNwidth); - int wh = MwGetInteger(handle, MwNheight); - int or = MwGetInteger(handle, MwNorientation); + int ww = MwGetInteger(handle, MwNwidth); + int wh = MwGetInteger(handle, MwNheight); + int or = MwGetInteger(handle, MwNorientation); scrollbar_t* scr = handle->internal; MwLLMouse* m = ptr; From bee6cb81cad42d6dae18810d765a56a8d9a76a36 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 15 Dec 2025 11:07:58 +0900 Subject: [PATCH 4/6] now ACTUALLY format --- include/Mw/BaseTypes.h | 4 ++-- src/backend/wayland.c | 12 ++++++------ src/widget/opengl.c | 3 +-- src/widget/scrollbar.c | 8 ++++---- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/include/Mw/BaseTypes.h b/include/Mw/BaseTypes.h index 1014869..ca718ea 100644 --- a/include/Mw/BaseTypes.h +++ b/include/Mw/BaseTypes.h @@ -58,8 +58,8 @@ typedef unsigned long MwU64; #ifdef MW_OTHER_TYPES_DEFINED #undef MW_OTHER_TYPES_DEFINED #else -typedef int MwI32; -typedef unsigned int MwU32; +typedef int MwI32; +typedef unsigned int MwU32; typedef short MwI16; typedef unsigned short MwU16; diff --git a/src/backend/wayland.c b/src/backend/wayland.c index b034ab4..48ce0c4 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -38,18 +38,18 @@ static void new_protocol(void* data, struct wl_registry* registry, /* `wl_registry.global_remove` callback */ static void protocol_removed(void* data, struct wl_registry* registry, - MwU32 name){ + MwU32 name) { }; /* `wl_pointer.enter` callback */ static void pointer_enter(void* data, struct wl_pointer* wl_pointer, MwU32 serial, struct wl_surface* surface, wl_fixed_t surface_x, - wl_fixed_t surface_y){}; + wl_fixed_t surface_y) {}; /* `wl_pointer.leave` callback */ static void pointer_leave(void* data, struct wl_pointer* wl_pointer, MwU32 serial, - struct wl_surface* surface){}; + struct wl_surface* surface) {}; /* `wl_pointer.motion` callback */ static void pointer_motion(void* data, struct wl_pointer* wl_pointer, MwU32 time, @@ -97,7 +97,7 @@ static void pointer_button(void* data, struct wl_pointer* wl_pointer, MwU32 seri /* `wl_pointer.axis` callback */ static void pointer_axis(void* data, struct wl_pointer* wl_pointer, MwU32 time, - MwU32 axis, wl_fixed_t value){}; + MwU32 axis, wl_fixed_t value) {}; struct wl_pointer_listener pointer_listener = { .enter = pointer_enter, @@ -266,7 +266,7 @@ static void keyboard_modifiers(void* data, MwU32 mods_depressed, MwU32 mods_latched, MwU32 mods_locked, - MwU32 group){}; + MwU32 group) {}; struct wl_keyboard_listener keyboard_listener = { .keymap = keyboard_keymap, @@ -278,7 +278,7 @@ struct wl_keyboard_listener keyboard_listener = { /* `wl_seat.name` callback */ static void -wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name){}; +wl_seat_name(void* data, struct wl_seat* wl_seat, const char* name) {}; /* `wl_seat.capabilities` callback */ static void wl_seat_capabilities(void* data, struct wl_seat* wl_seat, diff --git a/src/widget/opengl.c b/src/widget/opengl.c index 8c3b1ac..9552ae4 100644 --- a/src/widget/opengl.c +++ b/src/widget/opengl.c @@ -89,8 +89,7 @@ static int create(MwWidget handle) { attribs[3] = 24; attribs[4] = None; - while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL) - ; + while(glpath[glincr] != NULL && (o->lib = MwDynamicOpen(glpath[glincr++])) == NULL); o->glXChooseVisual = (MWglXChooseVisual)MwDynamicSymbol(o->lib, "glXChooseVisual"); o->glXCreateContext = (MWglXCreateContext)MwDynamicSymbol(o->lib, "glXCreateContext"); diff --git a/src/widget/scrollbar.c b/src/widget/scrollbar.c index 4058c81..e00d0b5 100644 --- a/src/widget/scrollbar.c +++ b/src/widget/scrollbar.c @@ -144,7 +144,7 @@ static void draw(MwWidget handle) { } static void mouse_move(MwWidget handle) { - int or = MwGetInteger(handle, MwNorientation); + int or = MwGetInteger(handle, MwNorientation); scrollbar_t* scr = handle->internal; if(!handle->pressed) return; @@ -172,9 +172,9 @@ static void mouse_move(MwWidget handle) { } static void mouse_down(MwWidget handle, void* ptr) { - int ww = MwGetInteger(handle, MwNwidth); - int wh = MwGetInteger(handle, MwNheight); - int or = MwGetInteger(handle, MwNorientation); + int ww = MwGetInteger(handle, MwNwidth); + int wh = MwGetInteger(handle, MwNheight); + int or = MwGetInteger(handle, MwNorientation); scrollbar_t* scr = handle->internal; MwLLMouse* m = ptr; From 7f43a974cd9cdee870909c95c0afbae41b01e339 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 15 Dec 2025 12:21:14 +0900 Subject: [PATCH 5/6] pixmap works --- include/Mw/LowLevel/Wayland.h | 2 ++ src/backend/wayland.c | 45 +++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/include/Mw/LowLevel/Wayland.h b/include/Mw/LowLevel/Wayland.h index b37bd45..32f6547 100644 --- a/include/Mw/LowLevel/Wayland.h +++ b/include/Mw/LowLevel/Wayland.h @@ -115,6 +115,8 @@ struct _MwLLWaylandColor { struct _MwLLWaylandPixmap { struct _MwLLCommonPixmap common; + + cairo_surface_t* cs; }; #endif diff --git a/src/backend/wayland.c b/src/backend/wayland.c index 48ce0c4..d0e0e25 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -852,31 +852,56 @@ 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); + r->wayland.cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height); + MwLLPixmapUpdate(r); return r; } static void MwLLPixmapUpdateImpl(MwLLPixmap r) { - /* TODO */ + 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]; + } + cairo_surface_mark_dirty(r->wayland.cs); } 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) { - int y, x; - for(y = rect->y; y < rect->y + rect->height; y++) { - if(y < 0 || y >= handle->wayland.wh) continue; - for(x = rect->x; x < rect->x + rect->width; x++) { - if(x < 0 || x >= handle->wayland.ww) continue; + cairo_t* c; + cairo_surface_t* cs; - /* TODO */ - //((unsigned char*)handle->wayland.mapped_shm_buf)[(x + y * handle->wayland.ww) * 4 + 0] = 0x80; - } - } + cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height); + c = cairo_create(cs); + + 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_paint(c); + + cairo_set_source_rgb(handle->wayland.cairo, 1, 1, 1); + cairo_set_source_surface(handle->wayland.cairo, cs, rect->x, rect->y); + cairo_paint(handle->wayland.cairo); + + cairo_destroy(c); + cairo_surface_destroy(cs); } static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { } From 7f823e2d34fcdb9b28976ab03066b979a3cc65c0 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Mon, 15 Dec 2025 12:22:01 +0900 Subject: [PATCH 6/6] format --- src/backend/wayland.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/wayland.c b/src/backend/wayland.c index d0e0e25..83e7439 100644 --- a/src/backend/wayland.c +++ b/src/backend/wayland.c @@ -860,12 +860,12 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid } static void MwLLPixmapUpdateImpl(MwLLPixmap r) { - int i; + 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){ + 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]; @@ -886,11 +886,11 @@ static void MwLLDestroyPixmapImpl(MwLLPixmap pixmap) { } static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) { - cairo_t* c; + cairo_t* c; cairo_surface_t* cs; cs = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, rect->width, rect->height); - c = cairo_create(cs); + c = cairo_create(cs); 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);