commit b07b53c5fd2814c4fa43bdf4c053637526395914
parent d773b21fba02fd65f8e9c0ab480b1aba0c84c04b
Author: Luke Willis <lukejw@loquat.dev>
Date:   Fri, 27 Mar 2026 00:32:38 -0400

Basic working configuration

Diffstat:
Mguix.scm | 3++-
Mmeson.build | 8+++++++-
Ascm/wig.scm | 60++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/main.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
4 files changed, 138 insertions(+), 29 deletions(-)

diff --git a/guix.scm b/guix.scm @@ -17,7 +17,8 @@ (native-inputs (list pkg-config wayland-protocols wlr-protocols)) - (inputs (list wayland)) + (inputs (list wayland + guile-3.0)) (synopsis "Widgets in Guile") (description #f) (home-page "https://git.monastech.xyz/wig") diff --git a/meson.build b/meson.build @@ -6,8 +6,9 @@ cc = meson.get_compiler('c') m_dep = cc.find_library('m', required : false) deps = [ + m_dep, dependency('wayland-client'), - m_dep + dependency('guile-3.0'), ] # Set up wayland protocols @@ -20,6 +21,11 @@ wayland_protocols = [ wl_mod.scan_xml(join_paths(wlr_protocols_data, 'unstable/wlr-layer-shell-unstable-v1.xml')) ] +# Set up devenv +devenv = environment() +devenv.append('GUILE_LOAD_PATH', join_paths(meson.current_source_dir(), 'scm')) +meson.add_devenv(devenv) + common_sources = files( 'src/wl.c' ) diff --git a/scm/wig.scm b/scm/wig.scm @@ -0,0 +1,60 @@ +(define-module (wig) + #:use-module (srfi srfi-9) + #:export (anchors + anchors? + anchors-top + anchors-bottom + anchors-left + anchors-right + window + window? + window-label + window-anchors + window-width + window-height)) + +(define-record-type <anchors> + (make-anchors top bottom left right) + anchors? + (top anchors-top) + (bottom anchors-bottom) + (left anchors-left) + (right anchors-right)) + +(define* (anchors #:key + (top #f) + (bottom #f) + (left #f) + (right #f)) + (unless (and (boolean? top) + (boolean? bottom) + (boolean? left) + (boolean? right)) + (error "Invalid anchors!")) + (make-anchors top bottom left right)) + +(define-record-type <window> + (make-window label anchors exclusive width height margin) + window? + (label window-label) + (anchors window-anchors) + (exclusive window-exclusive) + (width window-width) + (height window-height) + (margin window-margin)) + +(define* (window #:key + (label "wig_window") + (anchors (anchors)) + (exclusive #f) + (width 0) + (height 0) + (margin 0)) + (unless (and (string? label) + (anchors? anchors) + (boolean? exclusive) + (integer? width) + (integer? height) + (integer? margin)) + (error "Invalid window!")) + (make-window label anchors exclusive width height margin)) diff --git a/src/main.c b/src/main.c @@ -5,6 +5,7 @@ #include <unistd.h> #include <wayland-client.h> +#include <libguile.h> #include "wlr-layer-shell-unstable-v1-client-protocol.h" @@ -57,7 +58,7 @@ static struct wl_buffer *draw_frame(struct wig_state *state, int width, struct wl_buffer *buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, - WL_SHM_FORMAT_ARGB8888); + WL_SHM_FORMAT_XRGB8888); wl_shm_pool_destroy(pool); close(fd); @@ -136,11 +137,74 @@ registry_handle_global_remove(void *data, struct wl_registry *registry, } static const struct wl_registry_listener registry_listener = { -.global = registry_handle_global,.global_remove = - registry_handle_global_remove,}; + .global = registry_handle_global, + .global_remove = registry_handle_global_remove, +}; /* Main */ +static void +inner_main (void *data, int argc, char **argv) +{ + struct wig_state *state = data; + + /* Evaluate configuration */ + SCM wig_window_type = scm_c_private_ref("wig", "<window>"); + + SCM config = scm_c_primitive_load("wig.scm"); + + if (scm_is_false(scm_eq_p(scm_struct_vtable(config), wig_window_type))) { + fprintf(stderr, "Invalid configuration!\n"); + return; + } + + /* The configuration is validated on the Scheme side of things. */ + + char *label = scm_to_utf8_stringn(scm_struct_ref(config, scm_from_int(0)), + NULL); + SCM anchors = scm_struct_ref(config, scm_from_int(1)); + uint32_t anchor = 0; + for (uint32_t i = 0; i < 4; i++) + if (scm_is_true(scm_struct_ref(anchors, scm_from_uint32(i)))) + anchor |= (1 << i); + + int exclusive = scm_is_true(scm_struct_ref(config, scm_from_int(2))); + + uint32_t width = scm_to_uint32(scm_struct_ref(config, scm_from_int(3))); + uint32_t height = scm_to_uint32(scm_struct_ref(config, scm_from_int(4))); + uint32_t margin = scm_to_uint32(scm_struct_ref(config, scm_from_int(5))); + + /* Create surface */ + state->surface = wl_compositor_create_surface(state->compositor); + state->layer_surface = + zwlr_layer_shell_v1_get_layer_surface(state->layer_shell, + state->surface, + NULL, + ZWLR_LAYER_SHELL_V1_LAYER_TOP, + label); + zwlr_layer_surface_v1_add_listener(state->layer_surface, + &layer_surface_listener, state); + zwlr_layer_surface_v1_set_size(state->layer_surface, width, height); + zwlr_layer_surface_v1_set_anchor(state->layer_surface, anchor); + + /* TODO: Select correct dimensions */ + if (exclusive) + zwlr_layer_surface_v1_set_exclusive_zone(state->layer_surface, height); + + zwlr_layer_surface_v1_set_margin(state->layer_surface, margin, margin, margin, margin); + wl_surface_commit(state->surface); + + /* Loop */ + while (wl_display_dispatch(state->display) != -1) { + /* TODO */ + } + + /* Cleanup */ + wl_display_disconnect(state->display); + + free(label); +} + int main(int argc, char *argv[]) { struct wig_state state = { NULL }; @@ -155,30 +219,8 @@ int main(int argc, char *argv[]) wl_registry_add_listener(state.registry, &registry_listener, &state); wl_display_roundtrip(state.display); - /* Create surface */ - state.surface = wl_compositor_create_surface(state.compositor); - state.layer_surface = - zwlr_layer_shell_v1_get_layer_surface(state.layer_shell, - state.surface, - NULL, - ZWLR_LAYER_SHELL_V1_LAYER_TOP, - "wig_shell"); - zwlr_layer_surface_v1_add_listener(state.layer_surface, - &layer_surface_listener, &state); - zwlr_layer_surface_v1_set_size(state.layer_surface, 0, 64); - zwlr_layer_surface_v1_set_anchor(state.layer_surface, - ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | - ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM); - zwlr_layer_surface_v1_set_exclusive_zone(state.layer_surface, 64); - zwlr_layer_surface_v1_set_margin(state.layer_surface, 8, 8, 8, 8); - wl_surface_commit(state.surface); - - /* Loop */ - while (wl_display_dispatch(state.display) != -1) { - /* TODO */ - } + /* TODO: Validate registry */ - wl_display_disconnect(state.display); + scm_boot_guile(argc, argv, inner_main, &state); return 0; }