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
M
Makefile
+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: