commit 86a6462

uint  ·  2026-02-05 22:33:04 +0000 UTC
parent 39f9198
OpenBSD patches

Tested and working with Hevel

NOTES:
- changed signature of swc_mremap
- using regular cp instead of objcpy for openbsd
- ...
6 files changed,  +246, -17
+6, -0
 1@@ -159,6 +159,8 @@ cursor/convert_font.o: cursor/convert_font.c
 2 LAUNCH_DEVMAJOR=launch/devmajor-linux.c
 3 .if ${UNAME} == "NetBSD"
 4 LAUNCH_DEVMAJOR=launch/devmajor-netbsd.c
 5+.elif ${UNAME} == "OpenBSD"
 6+LAUNCH_DEVMAJOR=launch/devmajor-openbsd.c
 7 .endif
 8 
 9 launch/swc-launch: launch/launch.o launch/protocol.o launch/${LAUNCH_DEVMAJOR:T:R}.o
10@@ -244,7 +246,11 @@ libswc/libswc-internal.o: ${SWC_OBJECTS}
11 
12 libswc/libswc.o: libswc/libswc-internal.o
13 	@echo "  OBJCOPY $@"
14+.if ${UNAME} == "OpenBSD"
15+	@cp ${.ALLSRC} ${.TARGET}
16+.else
17 	@${OBJCOPY} --localize-hidden ${.ALLSRC} ${.TARGET}
18+.endif
19 
20 libswc/libswc.a: libswc/libswc.o
21 	@echo "  AR $@"
+74, -0
 1@@ -0,0 +1,74 @@
 2+/* swc: launch/devmajor-openbsd.c
 3+ *
 4+ * Copyright (c) 2020 Nia Alarie
 5+ * Copyright (c) 2026 uint
 6+ *
 7+ * Permission is hereby granted, free of charge, to any person obtaining a copy
 8+ * of this software and associated documentation files (the "Software"), to deal
 9+ * in the Software without restriction, including without limitation the rights
10+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+ * copies of the Software, and to permit persons to whom the Software is
12+ * furnished to do so, subject to the following conditions:
13+ *
14+ * The above copyright notice and this permission notice shall be included in
15+ * all copies or substantial portions of the Software.
16+ *
17+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23+ * SOFTWARE.
24+ */
25+#include <sys/stat.h>
26+#include <stdlib.h>
27+#include <string.h>
28+#include "devmajor.h"
29+
30+static bool
31+devname_is(dev_t rdev, const char *prefix)
32+{
33+	const char *name;
34+	size_t len;
35+
36+	name = devname(rdev, S_IFCHR);
37+	if (!name || name[0] == '?' || name[1] == '?')
38+		return false;
39+
40+	len = strlen(prefix);
41+	return strncmp(name, prefix, len) == 0;
42+}
43+
44+bool
45+device_is_input(dev_t rdev)
46+{
47+	if (devname_is(rdev, "wskbd"))
48+		return true;
49+	if (devname_is(rdev, "wsmouse"))
50+		return true;
51+	if (devname_is(rdev, "wsmux"))
52+		return true;
53+	return false;
54+}
55+
56+bool
57+device_is_tty(dev_t rdev)
58+{
59+	return devname_is(rdev, "ttyC");
60+}
61+
62+bool
63+device_is_drm(dev_t rdev)
64+{
65+	const char *n;
66+
67+	n = devname(rdev, S_IFCHR);
68+	if (!n)
69+		return false;
70+
71+	return
72+		strncmp(n, "drm", 3) == 0 ||
73+		strncmp(n, "dri/card", 8) == 0 ||
74+		strncmp(n, "dri/renderD", 11) == 0;
75+}
+93, -11
  1@@ -46,20 +46,32 @@
  2 #include <sys/wait.h>
  3 #include <sys/ioctl.h>
  4 #include <sys/types.h>
  5-#ifndef minor
  6+#ifdef __linux__
  7 #include <sys/sysmacros.h>
  8 #endif
  9-#ifdef __NetBSD__
 10+
 11+#if defined(__NetBSD__)
 12 #include <dev/wscons/wsdisplay_usl_io.h>
 13-#else
 14+
 15+#elif defined(__OpenBSD__)
 16+#include <dev/wscons/wsdisplay_usl_io.h>
 17+
 18+#elif defined(__linux__)
 19 #include <linux/input.h>
 20 #include <linux/kd.h>
 21 #include <linux/vt.h>
 22+
 23+#else
 24+#include <dev/wscons/wsdisplay_usl_io.h>
 25 #endif
 26+
 27 #include <xf86drm.h>
 28 
 29 #define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array)[0])
 30 
 31+static void activate(void);
 32+static void deactivate(void);
 33+
 34 static bool nflag;
 35 static int sigfd[2], sock[2];
 36 static int input_fds[128], num_input_fds;
 37@@ -132,20 +144,27 @@ stop_devices(bool fatal)
 38 static void
 39 cleanup(void)
 40 {
 41+#ifndef __OpenBSD__
 42 	struct vt_mode mode = {.mode = VT_AUTO};
 43+#endif
 44 
 45 	if (!original_vt_state.altered)
 46 		return;
 47 
 48+	/* Stop devices before switching the VT to make sure we have released the DRM
 49+	 * device before the next session tries to claim it. */
 50+	stop_devices(false);
 51+
 52 	/* Cleanup VT */
 53+#ifndef __OpenBSD__
 54 	ioctl(tty_fd, VT_SETMODE, &mode);
 55-	ioctl(tty_fd, KDSETMODE, original_vt_state.console_mode);
 56 	ioctl(tty_fd, KDSKBMODE, original_vt_state.kb_mode);
 57+#endif
 58+	ioctl(tty_fd, KDSETMODE, original_vt_state.console_mode);
 59 
 60-	/* Stop devices before switching the VT to make sure we have released the DRM
 61-	 * device before the next session tries to claim it. */
 62-	stop_devices(false);
 63+#ifndef __OpenBSD__
 64 	ioctl(tty_fd, VT_ACTIVATE, original_vt_state.vt);
 65+#endif
 66 
 67 	kill(0, SIGTERM);
 68 }
 69@@ -268,9 +287,16 @@ done:
 70 static void
 71 find_vt(char *vt, size_t size)
 72 {
 73-#ifdef __NetBSD__
 74+#if defined(__NetBSD__)
 75 	if (snprintf(vt, size, "/dev/ttyE1") >= size)
 76 		die("VT number is too large");
 77+#elif defined(__OpenBSD__)
 78+	const char *tty;
 79+	tty = ttyname(STDIN_FILENO);
 80+	if (!tty || strncmp(tty, "/dev/ttyC", 8) != 0)
 81+		die("must be run from wscons VT (/dev/ttyC*)");
 82+	if (snprintf(vt, size, "%s", tty) >= size)
 83+		die("VT number is too large");
 84 #else
 85 	char *vtnr;
 86 	int tty0_fd, vt_num;
 87@@ -315,23 +341,40 @@ setup_tty(int fd)
 88 {
 89 	struct stat st;
 90 	int vt;
 91+#ifndef __OpenBSD__
 92 	struct vt_stat state;
 93 	struct vt_mode mode = {
 94 		.mode = VT_PROCESS,
 95 		.relsig = SIGUSR1,
 96 		.acqsig = SIGUSR2
 97 	};
 98+#endif
 99 
100 	if (fstat(fd, &st) == -1)
101 		die("failed to stat TTY fd:");
102 	vt = minor(st.st_rdev);
103 
104+#ifdef __OpenBSD__
105+	if (!device_is_tty(st.st_rdev))
106+		die("not a valid VT");
107+#else
108 	if (!device_is_tty(st.st_rdev) || vt == 0)
109 		die("not a valid VT");
110+#endif
111 
112+#ifdef __OpenBSD__
113+	/* OpenBSD wscons has no VT_GETSTATE */
114+#else
115 	if (ioctl(fd, VT_GETSTATE, &state) == -1)
116 		die("failed to get the current VT state:");
117+#endif
118+
119+#ifndef __OpenBSD__
120 	original_vt_state.vt = state.v_active;
121+#else
122+	original_vt_state.vt = vt;
123+#endif
124+
125 #ifdef KDGETMODE
126 	if (ioctl(fd, KDGKBMODE, &original_vt_state.kb_mode))
127 		die("failed to get keyboard mode:");
128@@ -347,14 +390,40 @@ setup_tty(int fd)
129 		die("failed to set keyboard mode to K_OFF:");
130 #endif
131 	if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) {
132-		perror("failed to set console mode to KD_GRAPHICS");
133+		perror("KDSETMODE KD_GRAPHICS");
134 		goto error0;
135 	}
136+
137+#ifndef __OpenBSD__
138 	if (ioctl(fd, VT_SETMODE, &mode) == -1) {
139 		perror("failed to set VT mode");
140 		goto error1;
141 	}
142+#endif
143+
144+#ifdef __OpenBSD__
145+	/* OpenBSD wscons has no VT_PROCESS mode; just cont. on current ttyC* */
146+	activate();
147+#else
148+	if (vt == original_vt_state.vt) {
149+		activate();
150+	} else if (!nflag) {
151+		if (ioctl(fd, VT_ACTIVATE, vt) == -1) {
152+			perror("failed to activate VT");
153+			goto error2;
154+		}
155+
156+		if (ioctl(fd, VT_WAITACTIVE, vt) == -1) {
157+			perror("failed to wait for VT to become active");
158+			goto error2;
159+		}
160+	}
161+#endif
162 
163+#ifdef __OpenBSD__
164+	/* OpenBSD wscons already on active VT */
165+	activate();
166+#else
167 	if (vt == original_vt_state.vt) {
168 		activate();
169 	} else if (!nflag) {
170@@ -368,18 +437,21 @@ setup_tty(int fd)
171 			goto error2;
172 		}
173 	}
174+#endif
175 
176 	original_vt_state.altered = true;
177 
178 	return;
179 
180+#ifndef __OpenBSD__
181 error2:
182 	mode = (struct vt_mode){.mode = VT_AUTO };
183 	ioctl(fd, VT_SETMODE, &mode);
184 error1:
185-	ioctl(fd, KDSETMODE, original_vt_state.console_mode);
186-error0:
187 	ioctl(fd, KDSKBMODE, original_vt_state.kb_mode);
188+#endif
189+error0:
190+	ioctl(fd, KDSETMODE, original_vt_state.console_mode);
191 	exit(EXIT_FAILURE);
192 }
193 
194@@ -483,6 +555,16 @@ main(int argc, char *argv[])
195 	sprintf(buf, "%d", sock[1]);
196 	setenv(SWC_LAUNCH_SOCKET_ENV, buf, 1);
197 
198+	/* make sure XDG_RUNTIME_DIR is set */
199+	if (!getenv("XDG_RUNTIME_DIR")) {
200+		uid_t uid = getuid();
201+		snprintf(buf, sizeof(buf), "/tmp/XDG_RUNTIME_DIR_%d", uid);
202+		if (mkdir(buf, 0700) == -1 && errno != EEXIST)
203+			die("mkdir %s:", buf);
204+		setenv("XDG_RUNTIME_DIR", buf, 1);
205+		fprintf(stderr, "set XDG_RUNTIME_DIR=%s\n", buf);
206+	}
207+
208 	if ((errno = posix_spawnattr_init(&attr)))
209 		die("posix_spawnattr_init:");
210 	if ((errno = posix_spawnattr_setflags(&attr, POSIX_SPAWN_RESETIDS|POSIX_SPAWN_SETSIGMASK)))
+9, -0
 1@@ -150,11 +150,20 @@ update_keymap(struct xkb *xkb)
 2 
 3 	unlink(keymap_path);
 4 
 5+#ifdef __linux__
 6+	/* preallocate if available */
 7 	if (posix_fallocate(xkb->keymap.fd, 0, xkb->keymap.size) != 0 &&
 8 	    ftruncate(xkb->keymap.fd, xkb->keymap.size) != 0) {
 9 		WARNING("Could not resize XKB keymap file\n");
10 		goto error2;
11 	}
12+#else
13+	/* otherwise, ftruncate() is fine */
14+	if (ftruncate(xkb->keymap.fd, xkb->keymap.size) != 0) {
15+		WARNING("Could not resize XKB keymap file\n");
16+		goto error2;
17+	}
18+#endif
19 
20 	xkb->keymap.area = mmap(NULL, xkb->keymap.size, PROT_READ | PROT_WRITE, MAP_SHARED, xkb->keymap.fd, 0);
21 
+42, -2
  1@@ -40,6 +40,7 @@
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 #include <string.h>
  5+#include <errno.h>
  6 #include <fcntl.h>
  7 #include <unistd.h>
  8 
  9@@ -56,11 +57,15 @@ struct ws_xkb_map {
 10 static const struct ws_xkb_map ws_xkb_encodings[] = {
 11 	{ KB_UK, "gb" },
 12 	{ KB_BE, "be" },
 13+#ifdef KB_CZ
 14 	{ KB_CZ, "cz" },
 15+#endif
 16 	{ KB_DK, "dk" },
 17 	{ KB_NL, "nl" },
 18 	{ KB_DE, "de" },
 19+#ifdef KB_GR
 20 	{ KB_GR, "gr" },
 21+#endif
 22 	{ KB_HU, "hu" },
 23 	{ KB_IT, "it" },
 24 	{ KB_JP, "jp" },
 25@@ -207,8 +212,11 @@ ws_to_xkb(unsigned type, int key)
 26 	case WSKBD_TYPE_PC_AT:
 27 		return wsXtMap[key];
 28 	case WSKBD_TYPE_USB:
 29+#ifdef WSKBD_TYPE_MAPLE
 30 	case WSKBD_TYPE_MAPLE:
 31 		return wsUsbMap[key];
 32+#endif
 33+		return wsUsbMap[key];
 34 	default:
 35 		fprintf(stderr, "Unknown wskbd type %d\n", type);
 36 		return key;
 37@@ -296,23 +304,54 @@ handle_ws_data(int fd, uint32_t mask, void *data)
 38 static bool
 39 initialize_wscons(struct seat *seat)
 40 {
 41+#ifdef WSMOUSE_EVENT_VERSION
 42 	int mouse_ver = WSMOUSE_EVENT_VERSION;
 43+#endif
 44+#ifdef WSKBDIO_EVENT_VERSION
 45 	int kbd_ver = WSKBDIO_EVENT_VERSION;
 46+#endif
 47 	int encoding_layout;
 48 	kbd_t encoding;
 49 	unsigned i;
 50 
 51-	if ((seat->mouse_fd = launch_open_device("/dev/wsmouse", O_RDONLY | O_NONBLOCK)) == -1) {
 52+#ifdef WSMOUSE_EVENT_VERSION
 53+	int mouse_ver = WSMOUSE_EVENT_VERSION;
 54+#endif
 55+#ifdef WSKBDIO_EVENT_VERSION
 56+	int kbd_ver = WSKBDIO_EVENT_VERSION;
 57+#endif
 58+
 59+	if ((seat->mouse_fd = launch_open_device("/dev/wsmouse", O_RDWR | O_NONBLOCK)) == -1) {
 60 		ERROR("Could not open mouse device\n");
 61 		goto error0;
 62 	}
 63-	if ((seat->kbd_fd = launch_open_device("/dev/wskbd", O_RDONLY | O_NONBLOCK)) == -1) {
 64+	if ((seat->kbd_fd = launch_open_device("/dev/wskbd", O_RDWR | O_NONBLOCK)) == -1) {
 65 		ERROR("Could not open keyboard device\n");
 66 		goto error1;
 67 	}
 68 
 69+#ifdef WSMOUSEIO_SETVERSION
 70 	(void)ioctl(seat->mouse_fd, WSMOUSEIO_SETVERSION, &mouse_ver);
 71+#endif
 72+#ifdef WSKBDIO_SETVERSION
 73 	(void)ioctl(seat->kbd_fd, WSKBDIO_SETVERSION, &kbd_ver);
 74+#endif
 75+
 76+	/* set devices to nativemode to receive events */
 77+#ifdef WSMOUSEIO_SETMODE
 78+	{
 79+		int mode = WSMOUSE_COMPAT;  /* use compat mode; it sends events */
 80+		if (ioctl(seat->mouse_fd, WSMOUSEIO_SETMODE, &mode) == -1)
 81+			fprintf(stderr, "wscons: WSMOUSEIO_SETMODE failed: %s\n", strerror(errno));
 82+	}
 83+#endif /* WSMOUSEIO_SETMODE */
 84+#ifdef WSKBDIO_SETMODE
 85+	{
 86+		int mode = WSKBD_TRANSLATED;  /* use translated mode for key events */
 87+		if (ioctl(seat->kbd_fd, WSKBDIO_SETMODE, &mode) == -1)
 88+			fprintf(stderr, "wscons: WSKBDIO_SETMODE failed: %s\n", strerror(errno));
 89+	}
 90+#endif /* WSKBDIO_SETMODE */
 91 
 92 	if (ioctl(seat->kbd_fd, WSKBDIO_GTYPE, &seat->kbd_type) == -1) {
 93 		ERROR("Could not get keyboard type\n");
 94@@ -361,6 +400,7 @@ seat_create(struct wl_display *display, const char *seat_name)
 95 	if (!seat)
 96 		goto error0;
 97 
 98+	seat->ignore = false;
 99 	memset(&seat->names, 0, sizeof(seat->names));
100 	seat->names.rules = "base";
101 	seat->names.model = "pc105";
+22, -4
 1@@ -32,6 +32,7 @@
 2 
 3 #include <errno.h>
 4 #include <stdlib.h>
 5+#include <string.h>
 6 #include <sys/mman.h>
 7 #include <unistd.h>
 8 #include <wayland-server.h>
 9@@ -43,6 +44,7 @@ struct pool {
10 	struct swc_shm *shm;
11 	void *data;
12 	uint32_t size;
13+	int fd;
14 	unsigned references;
15 };
16 
17@@ -52,12 +54,21 @@ struct pool_reference {
18 };
19 
20 static void *
21-swc_mremap(void *oldp, size_t oldsize, size_t newsize)
22+swc_mremap(struct pool *pool, void *oldp, size_t oldsize, size_t newsize)
23 {
24 #ifdef __NetBSD__
25 	return mremap(oldp, oldsize, NULL, newsize, 0);
26-#else /* Linux-style mremap */
27+#elif defined(__linux__)
28 	return mremap(oldp, oldsize, newsize, MREMAP_MAYMOVE);
29+#else
30+	void *newp;
31+
32+	newp = mmap(NULL, newsize, PROT_READ, MAP_SHARED, pool->fd, 0);
33+	if (newp == MAP_FAILED)
34+		return MAP_FAILED;
35+
36+	(void)munmap(oldp, oldsize);
37+	return newp;
38 #endif
39 }
40 
41@@ -68,6 +79,7 @@ unref_pool(struct pool *pool)
42 		return;
43 
44 	munmap(pool->data, pool->size);
45+	close(pool->fd);
46 	free(pool);
47 }
48 
49@@ -148,7 +160,12 @@ resize(struct wl_client *client, struct wl_resource *resource, int32_t size)
50 	struct pool *pool = wl_resource_get_user_data(resource);
51 	void *data;
52 
53-	data = swc_mremap(pool->data, pool->size, size);
54+	if (ftruncate(pool->fd, size) != 0) {
55+		wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "ftruncate failed: %s", strerror(errno));
56+		return;
57+	}
58+
59+	data = swc_mremap(pool, pool->data, pool->size, size);
60 	if (data == MAP_FAILED) {
61 		wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mremap failed: %s", strerror(errno));
62 		return;
63@@ -186,9 +203,10 @@ create_pool(struct wl_client *client, struct wl_resource *resource, uint32_t id,
64 		wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mmap failed: %s", strerror(errno));
65 		goto error2;
66 	}
67-	close(fd);
68+	/* close(fd); */
69 	pool->size = size;
70 	pool->references = 1;
71+	pool->fd = fd;
72 	return;
73 
74 error2: