commit b07b53c5fd2814c4fa43bdf4c053637526395914
parent d773b21fba02fd65f8e9c0ab480b1aba0c84c04b
Author: Luke Willis <lukejw@loquat.dev>
Date: Fri, 27 Mar 2026 00:32:38 -0400
Basic working configuration
Diffstat:
| M | guix.scm | | | 3 | ++- |
| M | meson.build | | | 8 | +++++++- |
| A | scm/wig.scm | | | 60 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | src/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, ®istry_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;
}