commit e4bb1fc
shrub
·
2025-12-15 19:06:24 +0000 UTC
parent 19893a5
initial neuswc commit! added: - a overlay helper so compositor's can draw arbitrary boxes - swc_pointer_send_button helper, for compositor's that intercept button events - swc_cursor_position helper, for tracking cursor position
8 files changed,
+170,
-30
+0,
-26
1@@ -1,26 +0,0 @@
2-*.o
3-*.lo
4-.*.sw*
5-
6-protocol/server-decoration-protocol.c
7-protocol/server-decoration-server-protocol.h
8-protocol/swc-protocol.c
9-protocol/swc-server-protocol.h
10-protocol/wayland-drm-protocol.c
11-protocol/wayland-drm-server-protocol.h
12-protocol/xdg-decoration-unstable-v1-protocol.c
13-protocol/xdg-decoration-unstable-v1-server-protocol.h
14-protocol/xdg-shell-protocol.c
15-protocol/xdg-shell-server-protocol.h
16-protocol/linux-dmabuf-unstable-v1-protocol.c
17-protocol/linux-dmabuf-unstable-v1-server-protocol.h
18-
19-/.deps/
20-/swc.pc
21-/libswc/libswc.a
22-/libswc/libswc.so*
23-/launch/swc-launch
24-/cursor/convert_font
25-/cursor/cursor_data.h
26-/example/wm
27-
+1,
-2
1@@ -15,7 +15,6 @@
2
3 ENABLE_DEBUG = 1
4 ENABLE_STATIC = 1
5-ENABLE_SHARED = 1
6+ENABLE_SHARED = 0
7 ENABLE_LIBUDEV = 1
8 ENABLE_XWAYLAND = 1
9-
+89,
-0
1@@ -84,6 +84,14 @@ static struct {
2 struct wl_global *global;
3 } compositor;
4
5+static struct {
6+ bool active;
7+ int32_t x, y;
8+ uint32_t width, height;
9+ uint32_t color;
10+ uint32_t border_width;
11+} overlay;
12+
13 struct swc_compositor swc_compositor = {
14 .pointer_handler = &pointer_handler,
15 };
16@@ -216,6 +224,7 @@ static void
17 renderer_repaint(struct target *target, pixman_region32_t *damage, pixman_region32_t *base_damage, struct wl_list *views)
18 {
19 struct compositor_view *view;
20+ const struct swc_rectangle *target_geom = &target->view->geometry;
21
22 DEBUG("Rendering to target { x: %d, y: %d, w: %u, h: %u }\n",
23 target->view->geometry.x, target->view->geometry.y,
24@@ -234,6 +243,42 @@ renderer_repaint(struct target *target, pixman_region32_t *damage, pixman_region
25 repaint_view(target, view, damage);
26 }
27
28+ if (overlay.active && overlay.border_width > 0) {
29+ int32_t x = overlay.x - target_geom->x;
30+ int32_t y = overlay.y - target_geom->y;
31+ uint32_t w = overlay.width, h = overlay.height, bw = overlay.border_width;
32+ int32_t tx = (int32_t)target_geom->width;
33+ int32_t ty = (int32_t)target_geom->height;
34+
35+ /* draw box as 4 rectangles with wld */
36+ #define CLAMP_LOW(v, lo) ((v) < (lo) ? (lo) : (v))
37+ #define CLAMP_HIGH(v, hi) ((v) > (hi) ? (hi) : (v))
38+ #define DRAW_CLIPPED(rx, ry, rw, rh) do { \
39+ int32_t _x1 = CLAMP_LOW((rx), 0); \
40+ int32_t _y1 = CLAMP_LOW((ry), 0); \
41+ int32_t _x2 = CLAMP_HIGH((rx) + (int32_t)(rw), tx); \
42+ int32_t _y2 = CLAMP_HIGH((ry) + (int32_t)(rh), ty); \
43+ if (_x2 > _x1 && _y2 > _y1) \
44+ wld_fill_rectangle(swc.drm->renderer, overlay.color, _x1, _y1, (uint32_t)(_x2 - _x1), (uint32_t)(_y2 - _y1)); \
45+ } while (0)
46+
47+ if (w > 0 && h > 0) {
48+ if (bw > w)
49+ bw = w;
50+ if (bw > h)
51+ bw = h;
52+
53+ DRAW_CLIPPED(x, y, (int32_t)w, (int32_t)bw); /* top */
54+ DRAW_CLIPPED(x, y + (int32_t)h - (int32_t)bw, (int32_t)w, (int32_t)bw); /* bottom */
55+ DRAW_CLIPPED(x, y, (int32_t)bw, (int32_t)h); /* left */
56+ DRAW_CLIPPED(x + (int32_t)w - (int32_t)bw, y, (int32_t)bw, (int32_t)h); /* right */
57+ }
58+
59+ #undef DRAW_CLIPPED
60+ #undef CLAMP_HIGH
61+ #undef CLAMP_LOW
62+ }
63+
64 wld_flush(swc.drm->renderer);
65 }
66
67@@ -345,6 +390,50 @@ schedule_updates(uint32_t screens)
68 compositor.scheduled_updates |= screens;
69 }
70
71+static void
72+overlay_damage_region(int32_t x, int32_t y, uint32_t width, uint32_t height, uint32_t border_width)
73+{
74+ (void)border_width;
75+ pixman_region32_union_rect(&compositor.damage, &compositor.damage, x, y, width, height);
76+}
77+
78+EXPORT void
79+swc_overlay_set_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color, uint32_t border_width)
80+{
81+ int32_t x = x1 < x2 ? x1 : x2;
82+ int32_t y = y1 < y2 ? y1 : y2;
83+ uint32_t width = (uint32_t)abs(x2 - x1);
84+ uint32_t height = (uint32_t)abs(y2 - y1);
85+
86+ if (border_width == 0)
87+ border_width = 1;
88+
89+ if (overlay.active)
90+ overlay_damage_region(overlay.x, overlay.y, overlay.width, overlay.height, overlay.border_width);
91+
92+ overlay.active = true;
93+ overlay.x = x;
94+ overlay.y = y;
95+ overlay.width = width;
96+ overlay.height = height;
97+ overlay.color = color;
98+ overlay.border_width = border_width;
99+
100+ overlay_damage_region(overlay.x, overlay.y, overlay.width, overlay.height, overlay.border_width);
101+ schedule_updates(-1);
102+}
103+
104+EXPORT void
105+swc_overlay_clear(void)
106+{
107+ if (!overlay.active)
108+ return;
109+
110+ overlay_damage_region(overlay.x, overlay.y, overlay.width, overlay.height, overlay.border_width);
111+ overlay.active = false;
112+ schedule_updates(-1);
113+}
114+
115 static bool
116 update(struct view *base)
117 {
+21,
-0
1@@ -27,6 +27,7 @@
2 #include "internal.h"
3 #include "plane.h"
4 #include "screen.h"
5+#include "seat.h"
6 #include "shm.h"
7 #include "surface.h"
8 #include "util.h"
9@@ -36,6 +37,26 @@
10 #include <stdio.h>
11 #include <wld/wld.h>
12
13+EXPORT void
14+swc_pointer_send_button(uint32_t time, uint32_t button, uint32_t state)
15+{
16+ struct pointer *pointer = swc.seat ? swc.seat->pointer : NULL;
17+ struct wl_resource *resource;
18+ uint32_t serial;
19+
20+ if (!pointer || wl_list_empty(&pointer->focus.active))
21+ return;
22+
23+ serial = wl_display_next_serial(swc.display);
24+ wl_resource_for_each (resource, &pointer->focus.active)
25+ wl_pointer_send_button(resource, serial, time, button, state);
26+ wl_resource_for_each (resource, &pointer->focus.active) {
27+ if (wl_resource_get_version(resource) >= WL_POINTER_FRAME_SINCE_VERSION)
28+ wl_pointer_send_frame(resource);
29+ }
30+ pointer->client_axis_source = -1;
31+}
32+
33 static void
34 enter(struct input_focus_handler *handler, struct wl_list *resources, struct compositor_view *view)
35 {
+19,
-0
1@@ -108,6 +108,25 @@ swc_deactivate(void)
2 swc.manager->deactivate();
3 }
4
5+EXPORT bool
6+swc_cursor_position(int32_t *x, int32_t *y)
7+{
8+ if (x)
9+ *x = 0;
10+ if (y)
11+ *y = 0;
12+
13+ if (!swc.seat || !swc.seat->pointer)
14+ return false;
15+
16+ if (x)
17+ *x = swc.seat->pointer->x;
18+ if (y)
19+ *y = swc.seat->pointer->y;
20+
21+ return true;
22+}
23+
24 EXPORT bool
25 swc_initialize(struct wl_display *display, struct wl_event_loop *event_loop, const struct swc_manager *manager)
26 {
+32,
-0
1@@ -35,6 +35,38 @@ struct libinput_device;
2 struct wl_display;
3 struct wl_event_loop;
4
5+/**
6+ * gett the current cursor position
7+ *
8+ * The returned coordinates are in compositor-global space, in wl_fixed_t
9+ * (24.8) fixed-point units, but exposed as raw int32_t to avoid needing
10+ * wayland headers
11+ *
12+ */
13+bool swc_cursor_position(int32_t *x, int32_t *y);
14+
15+/**
16+ * Send a pointer button event to the currently focused client.
17+ *
18+ * This is intended for window managers which intercept button events (for
19+ * example for mouse chords) but want normal clicks to still reach clients.
20+ */
21+void swc_pointer_send_button(uint32_t time, uint32_t button, uint32_t state);
22+
23+/**
24+ * draw [or update] a simple box overlay
25+ *
26+ * box is defined by two diagonally opposite corners in compositor-global
27+ * coordinates. this draws only the border. Call swc_overlay_clear() to remove
28+ * it
29+ */
30+void swc_overlay_set_box(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color, uint32_t border_width);
31+
32+/**
33+ * Clear the current overlay, if any.
34+ */
35+void swc_overlay_clear(void);
36+
37 /* Rectangles {{{ */
38
39 struct swc_rectangle {
+7,
-2
1@@ -286,18 +286,23 @@ static void
2 focus(struct window *window)
3 {
4 struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
5+ uint32_t width = window->view->base.geometry.width;
6+ uint32_t height = window->view->base.geometry.height;
7
8 add_state(toplevel, XDG_TOPLEVEL_STATE_ACTIVATED);
9- send_configure(toplevel, -1, -1);
10+ /* dont send 0x0 on focus change */
11+ send_configure(toplevel, width ? (int32_t)width : -1, height ? (int32_t)height : -1);
12 }
13
14 static void
15 unfocus(struct window *window)
16 {
17 struct xdg_toplevel *toplevel = wl_container_of(window, toplevel, window);
18+ uint32_t width = window->view->base.geometry.width;
19+ uint32_t height = window->view->base.geometry.height;
20
21 remove_state(toplevel, XDG_TOPLEVEL_STATE_ACTIVATED);
22- send_configure(toplevel, -1, -1);
23+ send_configure(toplevel, width ? (int32_t)width : -1, height ? (int32_t)height : -1);
24 }
25
26 static void
A
swc
+1,
-0
1@@ -0,0 +1 @@
2+Subproject commit 19893a5ca3239082b904a04fdb9ac7c3a1fb62e2