window.c (3879B)
1 /* 2 * Wig --- Widgets in Guile 3 * Copyright © 2026 Luke Willis <lukejw@monastech.xyz> 4 * 5 * This file is part of Wig. 6 * 7 * Wig is free software: you can redistribute it and/or modify it under 8 * the terms of the GNU General Public License as published by the Free 9 * Software Foundation, either version 3 of the License, or (at your option) 10 * any later version. 11 * 12 * Wig is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with Wig. If not, see <https://www.gnu.org/licenses/>. 19 */ 20 21 #include <stdint.h> 22 #include <stdio.h> 23 24 #include "wlr-layer-shell-unstable-v1-client-protocol.h" 25 #include <pixman.h> 26 #include <wayland-client.h> 27 28 #include "globals.h" 29 #include "surface.h" 30 #include "window.h" 31 32 static inline uint32_t 33 min_u32(uint32_t a, uint32_t b) 34 { 35 return (a < b) ? a : b; 36 } 37 38 static inline uint32_t 39 max_u32(uint32_t a, uint32_t b) 40 { 41 return (a > b) ? a : b; 42 } 43 44 static void 45 zwlr_layer_surface_v1_configure( 46 void *data, struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, 47 uint32_t serial, uint32_t width, uint32_t height) 48 { 49 zwlr_layer_surface_v1_ack_configure(zwlr_layer_surface_v1, serial); 50 51 struct wig_window *window = data; 52 53 /* Skip pointless reconfiguration */ 54 if (window->surface.configured && width == window->surface.width && 55 height == window->surface.height) { 56 return; 57 } 58 59 int result = wig_surface_reconfigure(&window->surface, width, height); 60 61 if (result) { 62 fprintf(stderr, "Failed to reconfigure %s's surface\n", 63 window->label); 64 return; 65 } 66 67 size_t num_widgets = 68 scm_to_size_t(scm_wig_count_widgets(window->widgets)); 69 size_t size = num_widgets * sizeof(struct wig_widget); 70 struct wig_widget *widgets = malloc(size); 71 SCM bv = scm_c_pointer_to_bytevector(widgets, size); 72 73 scm_wig_compile_widgets(window->widgets, window->surface.width, 74 window->surface.height, bv); 75 76 for (size_t i = 0; i < num_widgets; i++) { 77 struct wig_widget widget = widgets[i]; 78 79 fprintf(stderr, "Widget %zu\n", i); 80 fprintf(stderr, " X: %u\n", widget.x); 81 fprintf(stderr, " Y: %u\n", widget.y); 82 fprintf(stderr, " W: %u\n", widget.width); 83 fprintf(stderr, " H: %u\n", widget.height); 84 fprintf(stderr, " Color: %08X\n", widget.color); 85 fprintf(stderr, " Flags: %08X\n", widget.flags); 86 87 if (widget.flags & WIDGET_GHOST) { 88 fprintf(stderr, " Ghost!\n"); 89 continue; 90 } 91 92 if (widget.x >= width || widget.y >= height) { 93 fprintf(stderr, " Out of bounds! Skipping...\n"); 94 continue; 95 } 96 97 pixman_fill(window->surface.buffer, width, 32, widget.x, 98 widget.y, min_u32(widget.width, width - widget.x), 99 min_u32(widget.height, height - widget.y), 100 widget.color | 0xFF000000); 101 } 102 103 wig_surface_commit(&window->surface); 104 } 105 106 static void 107 zwlr_layer_surface_v1_closed( 108 void *data, struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1) 109 { 110 /* TODO */ 111 } 112 113 static const struct zwlr_layer_surface_v1_listener 114 zwlr_layer_surface_v1_listener = { 115 .configure = zwlr_layer_surface_v1_configure, 116 .closed = zwlr_layer_surface_v1_closed, 117 }; 118 119 int 120 wig_window_init(struct wig_window *window, char *label, 121 struct wig_surface surface, 122 struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1) 123 { 124 window->label = label; 125 window->surface = surface; 126 127 window->zwlr_layer_surface_v1 = zwlr_layer_shell_v1_get_layer_surface( 128 zwlr_layer_shell_v1, window->surface.wl_surface, NULL, 129 ZWLR_LAYER_SHELL_V1_LAYER_TOP, label); 130 zwlr_layer_surface_v1_add_listener(window->zwlr_layer_surface_v1, 131 &zwlr_layer_surface_v1_listener, 132 window); 133 134 return 0; 135 }