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
A swc
+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