pkgsrc-WIP-changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

add swc version 0.0.20190810



Module Name:	pkgsrc-wip
Committed By:	Maya Rashish <maya%NetBSD.org@localhost>
Pushed By:	coypu
Date:		Sat Aug 10 23:02:16 2019 +0300
Changeset:	1f37bf207bd7ee576b09bab5829fe25bcbf57f1d

Added Files:
	swc/DESCR
	swc/Makefile
	swc/PLIST
	swc/buildlink3.mk
	swc/distinfo
	swc/patches/patch-Makefile
	swc/patches/patch-config.mk
	swc/patches/patch-launch_launch.c
	swc/patches/patch-launch_protocol.h
	swc/patches/patch-libswc_drm.c
	swc/patches/patch-libswc_local.mk
	swc/patches/patch-libswc_seat-ws.c
	swc/patches/patch-libswc_seat.c
	swc/patches/patch-libswc_shm.c

Log Message:
add swc version 0.0.20190810

heavily patched for netbsd support by nia, thanks!
(XXX - more to do!)

swc is a small Wayland compositor implemented as a library.

It has been designed primary with tiling window managers in mind.
Additionally, notable features include:

    Easy to follow code base
    XWayland support
    Can place borders around windows

To see a diff of this commit:
https://wip.pkgsrc.org/cgi-bin/gitweb.cgi?p=pkgsrc-wip.git;a=commitdiff;h=1f37bf207bd7ee576b09bab5829fe25bcbf57f1d

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

diffstat:
 swc/DESCR                           |   8 +
 swc/Makefile                        |  28 ++
 swc/PLIST                           |   9 +
 swc/buildlink3.mk                   |  17 ++
 swc/distinfo                        |  15 ++
 swc/patches/patch-Makefile          |  20 ++
 swc/patches/patch-config.mk         |  11 +
 swc/patches/patch-launch_launch.c   | 493 ++++++++++++++++++++++++++++++++++++
 swc/patches/patch-launch_protocol.h |  16 ++
 swc/patches/patch-libswc_drm.c      |  13 +
 swc/patches/patch-libswc_local.mk   |  22 ++
 swc/patches/patch-libswc_seat-ws.c  | 337 ++++++++++++++++++++++++
 swc/patches/patch-libswc_seat.c     | 411 ++++++++++++++++++++++++++++++
 swc/patches/patch-libswc_shm.c      |  40 +++
 14 files changed, 1440 insertions(+)

diffs:
diff --git a/swc/DESCR b/swc/DESCR
new file mode 100644
index 0000000000..5b6adf7046
--- /dev/null
+++ b/swc/DESCR
@@ -0,0 +1,8 @@
+swc is a small Wayland compositor implemented as a library.
+
+It has been designed primary with tiling window managers in mind.
+Additionally, notable features include:
+
+    Easy to follow code base
+    XWayland support
+    Can place borders around windows
diff --git a/swc/Makefile b/swc/Makefile
new file mode 100644
index 0000000000..554ef2f79b
--- /dev/null
+++ b/swc/Makefile
@@ -0,0 +1,28 @@
+# $NetBSD: Makefile,v 1.3 2018/08/22 09:43:57 wiz Exp $
+
+GIT_COMMIT=	a98426ae69b43396cb22bb62316e270fb1f9d8f1
+DISTNAME=	${GIT_COMMIT}
+PKGNAME=	swc-0.0.20190810
+CATEGORIES=	wm
+MASTER_SITES=	${MASTER_SITE_GITHUB:=michaelforney/swc/archive/}
+EXTRACT_SUFX=	.zip
+DIST_SUBDIR=	swc-${GIT_COMMIT}
+
+MAINTAINER=	pkgsrc-users%NetBSD.org@localhost
+HOMEPAGE=	https://github.com/michaelforney/swc
+COMMENT=	small Wayland compositor implemented as a library
+LICENSE=	mit
+
+USE_TOOLS+=	gmake pkg-config
+
+WRKSRC=		${WRKDIR}/swc-${GIT_COMMIT}
+
+PKGCONFIG_OVERRIDE+=	swc.pc.in
+
+.include "../../x11/pixman/buildlink3.mk"
+.include "../../x11/libdrm/buildlink3.mk"
+.include "../../x11/libxkbcommon/buildlink3.mk"
+.include "../../wip/wayland/buildlink3.mk"
+.include "../../wip/wayland-protocols/buildlink3.mk"
+.include "../../wip/wld/buildlink3.mk"
+.include "../../mk/bsd.pkg.mk"
diff --git a/swc/PLIST b/swc/PLIST
new file mode 100644
index 0000000000..24e128ca86
--- /dev/null
+++ b/swc/PLIST
@@ -0,0 +1,9 @@
+@comment $NetBSD$
+bin/swc-launch
+include/swc.h
+lib/libswc.a
+lib/libswc.so
+lib/libswc.so.0
+lib/libswc.so.0.0
+lib/pkgconfig/swc.pc
+share/swc/swc.xml
diff --git a/swc/buildlink3.mk b/swc/buildlink3.mk
new file mode 100644
index 0000000000..563ac7910e
--- /dev/null
+++ b/swc/buildlink3.mk
@@ -0,0 +1,17 @@
+# $NetBSD$
+
+BUILDLINK_TREE+=	swc
+
+.if !defined(SWC_BUILDLINK3_MK)
+SWC_BUILDLINK3_MK:=
+
+BUILDLINK_API_DEPENDS.swc+=	swc>=0.0.20190810
+BUILDLINK_PKGSRCDIR.swc?=	../../wip/swc
+
+.include "../../x11/pixman/buildlink3.mk"
+.include "../../x11/libxkbcommon/buildlink3.mk"
+.include "../../wip/wayland/buildlink3.mk"
+.include "../../wip/wld/buildlink3.mk"
+.endif	# SWC_BUILDLINK3_MK
+
+BUILDLINK_TREE+=	-swc
diff --git a/swc/distinfo b/swc/distinfo
new file mode 100644
index 0000000000..e2c0174dad
--- /dev/null
+++ b/swc/distinfo
@@ -0,0 +1,15 @@
+$NetBSD$
+
+SHA1 (swc-a98426ae69b43396cb22bb62316e270fb1f9d8f1/a98426ae69b43396cb22bb62316e270fb1f9d8f1.zip) = 5d2e9830510a70b53019ddc8ffc20bd82495be02
+RMD160 (swc-a98426ae69b43396cb22bb62316e270fb1f9d8f1/a98426ae69b43396cb22bb62316e270fb1f9d8f1.zip) = 6c51e820cae04d81ec6879575340632a483d9317
+SHA512 (swc-a98426ae69b43396cb22bb62316e270fb1f9d8f1/a98426ae69b43396cb22bb62316e270fb1f9d8f1.zip) = aa68875ee90a1e815684d67e12b4373071cd6bb81761117b513be0aa872f93948fc48ee5ada5e2e5fdda9a8d9b25db003bb1c4b4995879344a516df44a37326a
+Size (swc-a98426ae69b43396cb22bb62316e270fb1f9d8f1/a98426ae69b43396cb22bb62316e270fb1f9d8f1.zip) = 146116 bytes
+SHA1 (patch-Makefile) = 7b79ca023fb6986fff44967169edd6499ffeb825
+SHA1 (patch-config.mk) = df6ba39cbd0cb082ec29cd7e917dde061dd0ba54
+SHA1 (patch-launch_launch.c) = 3f2a3197b8cf567cf91af684a40145241030f3ba
+SHA1 (patch-launch_protocol.h) = b9c8ef5acfc177178f630ac97c27d8b2914c9499
+SHA1 (patch-libswc_drm.c) = a1df17103b418a0ff8980ff5e6ce7becda1eaf55
+SHA1 (patch-libswc_local.mk) = d42b7958c058d0a67008d21b869c0ebfc2908beb
+SHA1 (patch-libswc_seat-ws.c) = 2fabdff5e3db5fa005b34731a6312201d544420c
+SHA1 (patch-libswc_seat.c) = d63660b6dc358b2c9d6d5437323af4dc8e2d8548
+SHA1 (patch-libswc_shm.c) = 6f524957bcd863e8112470160f3d0b07562b1437
diff --git a/swc/patches/patch-Makefile b/swc/patches/patch-Makefile
new file mode 100644
index 0000000000..8f94b763d0
--- /dev/null
+++ b/swc/patches/patch-Makefile
@@ -0,0 +1,20 @@
+$NetBSD$
+
+--- Makefile.orig	2019-07-11 06:33:41.000000000 +0000
++++ Makefile
+@@ -28,7 +28,6 @@ include config.mk
+ # Dependencies
+ PACKAGES :=           \
+     libdrm            \
+-    libinput          \
+     pixman-1          \
+     wayland-server    \
+     wayland-protocols \
+@@ -39,7 +38,6 @@ ifeq ($(ENABLE_LIBUDEV),1)
+ PACKAGES += libudev
+ endif
+ 
+-libinput_CONSTRAINTS        := --atleast-version=0.4
+ wayland-server_CONSTRAINTS  := --atleast-version=1.6.0
+ 
+ define check
diff --git a/swc/patches/patch-config.mk b/swc/patches/patch-config.mk
new file mode 100644
index 0000000000..eefc64b82f
--- /dev/null
+++ b/swc/patches/patch-config.mk
@@ -0,0 +1,11 @@
+$NetBSD$
+
+--- config.mk.orig	2019-07-11 06:33:41.000000000 +0000
++++ config.mk
+@@ -16,5 +16,5 @@
+ ENABLE_DEBUG    = 1
+ ENABLE_STATIC   = 1
+ ENABLE_SHARED   = 1
+-ENABLE_LIBUDEV  = 1
++ENABLE_LIBUDEV  = 0
+ 
diff --git a/swc/patches/patch-launch_launch.c b/swc/patches/patch-launch_launch.c
new file mode 100644
index 0000000000..9261c4c1f1
--- /dev/null
+++ b/swc/patches/patch-launch_launch.c
@@ -0,0 +1,493 @@
+$NetBSD$
+
+--- launch/launch.c.orig	2019-07-11 06:33:41.000000000 +0000
++++ launch/launch.c
+@@ -1,488 +1,10 @@
+ /* swc: launch/launch.c
+- *
+- * Copyright (c) 2013, 2014, 2016 Michael Forney
+- *
+- * Based in part upon weston-launch.c from weston which is:
+- *
+- *     Copyright © 2012 Benjamin Franzke
+- *
+- * Permission is hereby granted, free of charge, to any person obtaining a copy
+- * of this software and associated documentation files (the "Software"), to deal
+- * in the Software without restriction, including without limitation the rights
+- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+- * copies of the Software, and to permit persons to whom the Software is
+- * furnished to do so, subject to the following conditions:
+- *
+- * The above copyright notice and this permission notice shall be included in
+- * all copies or substantial portions of the Software.
+- *
+- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+- * SOFTWARE.
+  */
+ 
+-#include "protocol.h"
+-
+-#include <errno.h>
+-#include <fcntl.h>
+-#include <limits.h>
+-#include <poll.h>
+-#include <spawn.h>
+-#include <stdbool.h>
+-#include <stdio.h>
+ #include <stdlib.h>
+-#include <stdnoreturn.h>
+-#include <string.h>
+-#include <unistd.h>
+-
+-#include <sys/socket.h>
+-#include <sys/stat.h>
+-#include <sys/wait.h>
+-#include <sys/ioctl.h>
+-#include <sys/sysmacros.h>
+-#include <linux/input.h>
+-#include <linux/kd.h>
+-#include <linux/major.h>
+-#include <linux/vt.h>
+-#include <xf86drm.h>
+-
+-#ifndef DRM_MAJOR
+-#define DRM_MAJOR 226
+-#endif
+-
+-#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array)[0])
+-
+-static bool nflag;
+-static int sigfd[2], sock[2];
+-static int input_fds[128], num_input_fds;
+-static int drm_fds[16], num_drm_fds;
+-static int tty_fd;
+-static bool active;
+-
+-static struct {
+-	bool altered;
+-	int vt;
+-	long kb_mode;
+-	long console_mode;
+-} original_vt_state;
+-
+-static void cleanup(void);
+-
+-static noreturn void usage(const char *name)
+-{
+-	fprintf(stderr, "usage: %s [-n] [-t tty] [--] server [args...]\n", name);
+-	exit(2);
+-}
+-
+-static noreturn void __attribute__((format(printf, 1, 2)))
+-die(const char *format, ...)
+-{
+-	va_list args;
+-
+-	va_start(args, format);
+-	vfprintf(stderr, format, args);
+-	va_end(args);
+-
+-	if (format[0] && format[strlen(format) - 1] == ':')
+-		fprintf(stderr, " %s", strerror(errno));
+-	fputc('\n', stderr);
+-
+-	cleanup();
+-	exit(EXIT_FAILURE);
+-}
+-
+-static void
+-start_devices(void)
+-{
+-	int i;
+-
+-	for (i = 0; i < num_drm_fds; ++i) {
+-		if (drmSetMaster(drm_fds[i]) < 0)
+-			die("failed to set DRM master");
+-	}
+-}
+-
+-static void
+-stop_devices(bool fatal)
+-{
+-	int i;
+-
+-	for (i = 0; i < num_drm_fds; ++i) {
+-		if (drmDropMaster(drm_fds[i]) < 0 && fatal)
+-			die("drmDropMaster:");
+-	}
+-	for (i = 0; i < num_input_fds; ++i) {
+-		if (ioctl(input_fds[i], EVIOCREVOKE, 0) < 0 && errno != ENODEV && fatal)
+-			die("ioctl EVIOCREVOKE:");
+-		close(input_fds[i]);
+-	}
+-	num_input_fds = 0;
+-}
+-
+-static void
+-cleanup(void)
+-{
+-	struct vt_mode mode = {.mode = VT_AUTO};
+-
+-	if (!original_vt_state.altered)
+-		return;
+-
+-	/* Cleanup VT */
+-	ioctl(tty_fd, VT_SETMODE, &mode);
+-	ioctl(tty_fd, KDSETMODE, original_vt_state.console_mode);
+-	ioctl(tty_fd, KDSKBMODE, original_vt_state.kb_mode);
+-
+-	/* Stop devices before switching the VT to make sure we have released the DRM
+-	 * device before the next session tries to claim it. */
+-	stop_devices(false);
+-	ioctl(tty_fd, VT_ACTIVATE, original_vt_state.vt);
+-
+-	kill(0, SIGTERM);
+-}
+-
+-static void
+-activate(void)
+-{
+-	struct swc_launch_event event = {.type = SWC_LAUNCH_EVENT_ACTIVATE};
+-
+-	start_devices();
+-	send(sock[0], &event, sizeof(event), 0);
+-	active = true;
+-}
+-
+-static void
+-deactivate(void)
+-{
+-	struct swc_launch_event event = {.type = SWC_LAUNCH_EVENT_DEACTIVATE};
+-
+-	send(sock[0], &event, sizeof(event), 0);
+-	stop_devices(true);
+-	active = false;
+-}
+-
+-static void
+-handle_signal(int sig)
+-{
+-	write(sigfd[1], (char[]){sig}, 1);
+-}
+-
+-static void
+-handle_socket_data(int socket)
+-{
+-	struct swc_launch_request request;
+-	struct swc_launch_event response;
+-	char path[PATH_MAX];
+-	struct iovec request_iov[2] = {
+-		{.iov_base = &request, .iov_len = sizeof(request)},
+-		{.iov_base = path, .iov_len = sizeof(path)},
+-	};
+-	struct iovec response_iov[1] = {
+-		{.iov_base = &response, .iov_len = sizeof(response)},
+-	};
+-	int fd = -1;
+-	struct stat st;
+-	ssize_t size;
+-
+-	size = receive_fd(socket, &fd, request_iov, 2);
+-	if (size == -1 || size == 0 || size < sizeof(request))
+-		return;
+-	size -= sizeof(request);
+-
+-	response.type = SWC_LAUNCH_EVENT_RESPONSE;
+-	response.serial = request.serial;
+-
+-	switch (request.type) {
+-	case SWC_LAUNCH_REQUEST_OPEN_DEVICE:
+-		if (size == 0 || path[size - 1] != '\0') {
+-			fprintf(stderr, "path is not NULL terminated\n");
+-			goto fail;
+-		}
+-
+-		if (stat(path, &st) == -1) {
+-			fprintf(stderr, "stat %s: %s\n", path, strerror(errno));
+-			goto fail;
+-		}
+-
+-		switch (major(st.st_rdev)) {
+-		case INPUT_MAJOR:
+-			if (!active)
+-				goto fail;
+-			if (num_input_fds == ARRAY_LENGTH(input_fds)) {
+-				fprintf(stderr, "too many input devices opened\n");
+-				goto fail;
+-			}
+-			break;
+-		case DRM_MAJOR:
+-			if (num_drm_fds == ARRAY_LENGTH(drm_fds)) {
+-				fprintf(stderr, "too many DRM devices opened\n");
+-				goto fail;
+-			}
+-			break;
+-		default:
+-			fprintf(stderr, "device is not an input device\n");
+-			goto fail;
+-		}
+-
+-		fd = open(path, request.flags);
+-
+-		if (fd == -1) {
+-			fprintf(stderr, "open %s: %s\n", path, strerror(errno));
+-			goto fail;
+-		}
+-
+-		switch (major(st.st_rdev)) {
+-		case INPUT_MAJOR:
+-			input_fds[num_input_fds++] = fd;
+-			break;
+-		case DRM_MAJOR:
+-			drm_fds[num_drm_fds++] = fd;
+-			break;
+-		}
+-
+-		break;
+-	case SWC_LAUNCH_REQUEST_ACTIVATE_VT:
+-		if (!active)
+-			goto fail;
+-
+-		if (ioctl(tty_fd, VT_ACTIVATE, request.vt) == -1)
+-			fprintf(stderr, "failed to activate VT %d: %s\n", request.vt, strerror(errno));
+-		break;
+-	default:
+-		fprintf(stderr, "unknown request %u\n", request.type);
+-		goto fail;
+-	}
+-
+-	response.success = true;
+-	goto done;
+-
+-fail:
+-	response.success = false;
+-	fd = -1;
+-done:
+-	send_fd(socket, fd, response_iov, 1);
+-}
+-
+-static void
+-find_vt(char *vt, size_t size)
+-{
+-	char *vtnr;
+-	int tty0_fd, vt_num;
+-
+-	/* If we are running from an existing X or wayland session, always open a new
+-	 * VT instead of using the current one. */
+-	if (getenv("DISPLAY") || getenv("WAYLAND_DISPLAY") || !(vtnr = getenv("XDG_VTNR"))) {
+-		tty0_fd = open("/dev/tty0", O_RDWR);
+-		if (tty0_fd == -1)
+-			die("open /dev/tty0:");
+-		if (ioctl(tty0_fd, VT_OPENQRY, &vt_num) != 0)
+-			die("VT open query failed:");
+-		close(tty0_fd);
+-		if (snprintf(vt, size, "/dev/tty%d", vt_num) >= size)
+-			die("VT number is too large");
+-	} else {
+-		if (snprintf(vt, size, "/dev/tty%s", vtnr) >= size)
+-			die("XDG_VTNR is too long");
+-	}
+-}
+-
+-static int
+-open_tty(const char *tty_name)
+-{
+-	char *stdin_tty;
+-	int fd;
+-
+-	/* Check if we are already running on the desired VT */
+-	if ((stdin_tty = ttyname(STDIN_FILENO)) && strcmp(tty_name, stdin_tty) == 0)
+-		return STDIN_FILENO;
+-
+-	fd = open(tty_name, O_RDWR | O_NOCTTY);
+-	if (fd < 0)
+-		die("open %s:", tty_name);
+-
+-	return fd;
+-}
+-
+-static void
+-setup_tty(int fd)
+-{
+-	struct stat st;
+-	int vt;
+-	struct vt_stat state;
+-	struct vt_mode mode = {
+-		.mode = VT_PROCESS,
+-		.relsig = SIGUSR1,
+-		.acqsig = SIGUSR2
+-	};
+-
+-	if (fstat(fd, &st) == -1)
+-		die("failed to stat TTY fd:");
+-	vt = minor(st.st_rdev);
+-	if (major(st.st_rdev) != TTY_MAJOR || vt == 0)
+-		die("not a valid VT");
+-
+-	if (ioctl(fd, VT_GETSTATE, &state) == -1)
+-		die("failed to get the current VT state:");
+-	original_vt_state.vt = state.v_active;
+-	if (ioctl(fd, KDGKBMODE, &original_vt_state.kb_mode))
+-		die("failed to get keyboard mode:");
+-	if (ioctl(fd, KDGETMODE, &original_vt_state.console_mode))
+-		die("failed to get console mode:");
+-
+-	if (ioctl(fd, KDSKBMODE, K_OFF) == -1)
+-		die("failed to set keyboard mode to K_OFF:");
+-	if (ioctl(fd, KDSETMODE, KD_GRAPHICS) == -1) {
+-		perror("failed to set console mode to KD_GRAPHICS");
+-		goto error0;
+-	}
+-	if (ioctl(fd, VT_SETMODE, &mode) == -1) {
+-		perror("failed to set VT mode");
+-		goto error1;
+-	}
+-
+-	if (vt == original_vt_state.vt) {
+-		activate();
+-	} else if (!nflag) {
+-		if (ioctl(fd, VT_ACTIVATE, vt) == -1) {
+-			perror("failed to activate VT");
+-			goto error2;
+-		}
+-
+-		if (ioctl(fd, VT_WAITACTIVE, vt) == -1) {
+-			perror("failed to wait for VT to become active");
+-			goto error2;
+-		}
+-	}
+-
+-	original_vt_state.altered = true;
+-
+-	return;
+-
+-error2:
+-	mode = (struct vt_mode){.mode = VT_AUTO };
+-	ioctl(fd, VT_SETMODE, &mode);
+-error1:
+-	ioctl(fd, KDSETMODE, original_vt_state.console_mode);
+-error0:
+-	ioctl(fd, KDSKBMODE, original_vt_state.kb_mode);
+-	exit(EXIT_FAILURE);
+-}
+-
+-static void
+-run(int fd) {
+-	struct pollfd fds[] = {
+-		{.fd = fd, .events = POLLIN},
+-		{.fd = sigfd[0], .events = POLLIN},
+-	};
+-	int status;
+-	char sig;
+-
+-	for (;;) {
+-		if (poll(fds, ARRAY_LENGTH(fds), -1) < 0) {
+-			if (errno == EINTR)
+-				continue;
+-			die("poll:");
+-		}
+-		if (fds[0].revents)
+-			handle_socket_data(fd);
+-		if (fds[1].revents) {
+-			if (read(sigfd[0], &sig, 1) <= 0)
+-				continue;
+-			switch (sig) {
+-			case SIGCHLD:
+-				wait(&status);
+-				cleanup();
+-				exit(WEXITSTATUS(status));
+-			case SIGUSR1:
+-				deactivate();
+-				ioctl(tty_fd, VT_RELDISP, 1);
+-				break;
+-			case SIGUSR2:
+-				ioctl(tty_fd, VT_RELDISP, VT_ACKACQ);
+-				activate();
+-				break;
+-			}
+-		}
+-	}
+-}
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	int option;
+-	char *vt = NULL, buf[64];
+-	struct sigaction action = {
+-		.sa_handler = handle_signal,
+-		.sa_flags = SA_RESTART,
+-	};
+-	sigset_t set;
+-	pid_t pid;
+-	posix_spawnattr_t attr;
+-
+-	while ((option = getopt(argc, argv, "nt:")) != -1) {
+-		switch (option) {
+-		case 'n':
+-			nflag = true;
+-			break;
+-		case 't':
+-			vt = optarg;
+-			break;
+-		default:
+-			usage(argv[0]);
+-		}
+-	}
+-
+-	if (argc - optind < 1)
+-		usage(argv[0]);
+-
+-	if (socketpair(AF_LOCAL, SOCK_SEQPACKET, 0, sock) == -1)
+-		die("socketpair:");
+-	if (fcntl(sock[0], F_SETFD, FD_CLOEXEC) == -1)
+-		die("failed set CLOEXEC on socket:");
+-
+-	if (pipe2(sigfd, O_CLOEXEC) == -1)
+-		die("pipe:");
+-	if (sigaction(SIGCHLD, &action, NULL) == -1)
+-		die("sigaction SIGCHLD:");
+-	if (sigaction(SIGUSR1, &action, NULL) == -1)
+-		die("sigaction SIGUSR1:");
+-	if (sigaction(SIGUSR2, &action, NULL) == -1)
+-		die("sigaction SIGUSR2:");
+-
+-	sigfillset(&set);
+-	sigdelset(&set, SIGCHLD);
+-	sigdelset(&set, SIGUSR1);
+-	sigdelset(&set, SIGUSR2);
+-	sigprocmask(SIG_SETMASK, &set, NULL);
+-
+-	if (!vt) {
+-		find_vt(buf, sizeof(buf));
+-		vt = buf;
+-	}
+-
+-	fprintf(stderr, "running on %s\n", vt);
+-	tty_fd = open_tty(vt);
+-	setup_tty(tty_fd);
+-
+-	sprintf(buf, "%d", sock[1]);
+-	setenv(SWC_LAUNCH_SOCKET_ENV, buf, 1);
+-
+-	if ((errno = posix_spawnattr_init(&attr)))
+-		die("posix_spawnattr_init:");
+-	if ((errno = posix_spawnattr_setflags(&attr, POSIX_SPAWN_RESETIDS|POSIX_SPAWN_SETSIGMASK)))
+-		die("posix_spawnattr_setflags:");
+-	sigemptyset(&set);
+-	if ((errno = posix_spawnattr_setsigmask(&attr, &set)))
+-		die("posix_spawnattr_setsigmask:");
+-	if ((errno = posix_spawnp(&pid, argv[optind], NULL, &attr, argv + optind, environ)))
+-		die("posix_spawnp %s:", argv[optind]);
+-	posix_spawnattr_destroy(&attr);
+-
+-	close(sock[1]);
+-	run(sock[0]);
+-
+ 	return EXIT_SUCCESS;
+ }
diff --git a/swc/patches/patch-launch_protocol.h b/swc/patches/patch-launch_protocol.h
new file mode 100644
index 0000000000..7ee6803341
--- /dev/null
+++ b/swc/patches/patch-launch_protocol.h
@@ -0,0 +1,16 @@
+$NetBSD$
+
+--- launch/protocol.h.orig	2019-07-11 06:33:41.000000000 +0000
++++ launch/protocol.h
+@@ -24,9 +24,10 @@
+ #ifndef SWC_LAUNCH_PROTOCOL_H
+ #define SWC_LAUNCH_PROTOCOL_H
+ 
++#include <sys/types.h>
++#include <sys/uio.h>
+ #include <stdbool.h>
+ #include <stdint.h>
+-#include <sys/types.h>
+ 
+ #define SWC_LAUNCH_SOCKET_ENV "SWC_LAUNCH_SOCKET"
+ 
diff --git a/swc/patches/patch-libswc_drm.c b/swc/patches/patch-libswc_drm.c
new file mode 100644
index 0000000000..af31696577
--- /dev/null
+++ b/swc/patches/patch-libswc_drm.c
@@ -0,0 +1,13 @@
+$NetBSD$
+
+--- libswc/drm.c.orig	2019-07-11 06:33:41.000000000 +0000
++++ libswc/drm.c
+@@ -196,7 +196,7 @@ find_available_crtc(drmModeRes *resource
+ static bool
+ find_available_id(uint32_t *id)
+ {
+-	int index = ffsl(~drm.taken_ids);
++	int index = __builtin_ffsl(~drm.taken_ids);
+ 
+ 	if (index == 0)
+ 		return false;
diff --git a/swc/patches/patch-libswc_local.mk b/swc/patches/patch-libswc_local.mk
new file mode 100644
index 0000000000..5c90bebb07
--- /dev/null
+++ b/swc/patches/patch-libswc_local.mk
@@ -0,0 +1,22 @@
+$NetBSD$
+
+--- libswc/local.mk.orig	2019-07-11 06:33:41.000000000 +0000
++++ libswc/local.mk
+@@ -17,7 +17,7 @@ $(dir)_TARGETS +=                   \
+     $(dir)/$(LIBSWC_LINK)
+ endif
+ 
+-$(dir)_PACKAGES := libdrm libinput pixman-1 wayland-server wld xkbcommon
++$(dir)_PACKAGES := libdrm pixman-1 wayland-server wld xkbcommon
+ $(dir)_CFLAGS += -Iprotocol
+ 
+ SWC_SOURCES =                       \
+@@ -40,7 +40,7 @@ SWC_SOURCES =                       \
+     libswc/primary_plane.c          \
+     libswc/region.c                 \
+     libswc/screen.c                 \
+-    libswc/seat.c                   \
++    libswc/seat-ws.c                \
+     libswc/shell.c                  \
+     libswc/shell_surface.c          \
+     libswc/shm.c                    \
diff --git a/swc/patches/patch-libswc_seat-ws.c b/swc/patches/patch-libswc_seat-ws.c
new file mode 100644
index 0000000000..1de6e4ae36
--- /dev/null
+++ b/swc/patches/patch-libswc_seat-ws.c
@@ -0,0 +1,337 @@
+$NetBSD$
+
+--- libswc/seat-ws.c.orig	2019-08-10 19:52:23.379366995 +0000
++++ libswc/seat-ws.c
+@@ -0,0 +1,332 @@
++/* swc: libswc/seat-ws.c
++ *
++ * Copyright (c) 2013, 2014 Michael Forney
++ * Copyright (c) 2019 Nia Alarie
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a copy
++ * of this software and associated documentation files (the "Software"), to deal
++ * in the Software without restriction, including without limitation the rights
++ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
++ * copies of the Software, and to permit persons to whom the Software is
++ * furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
++ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
++ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
++ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
++ * SOFTWARE.
++ */
++
++#include "seat.h"
++#include "compositor.h"
++#include "data_device.h"
++#include "event.h"
++#include "internal.h"
++#include "keyboard.h"
++#include "launch.h"
++#include "pointer.h"
++#include "screen.h"
++#include "surface.h"
++#include "util.h"
++
++#include <dev/wscons/wsconsio.h>
++
++#include <stdbool.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <fcntl.h>
++#include <unistd.h>
++
++static struct {
++	char *name;
++	uint32_t capabilities;
++
++	int mouse_fd;
++	int kbd_fd;
++	bool ignore;
++
++	struct wl_event_source *mouse_source;
++	struct wl_event_source *kbd_source;
++
++	struct wl_listener swc_listener;
++
++	struct keyboard keyboard;
++	struct pointer pointer;
++	struct data_device data_device;
++
++	struct wl_global *global;
++	struct wl_list resources;
++} seat;
++
++const struct swc_seat swc_seat = {
++	.pointer = &seat.pointer,
++	.keyboard = &seat.keyboard,
++	.data_device = &seat.data_device,
++};
++
++static void
++handle_keyboard_focus_event(struct wl_listener *listener, void *data)
++{
++	struct event *ev = data;
++	struct input_focus_event_data *event_data = ev->data;
++
++	if (ev->type != INPUT_FOCUS_EVENT_CHANGED)
++		return;
++
++	if (event_data->new) {
++		struct wl_client *client = wl_resource_get_client(event_data->new->surface->resource);
++
++		/* Offer the selection to the new focus. */
++		data_device_offer_selection(&seat.data_device, client);
++	}
++}
++
++static struct wl_listener keyboard_focus_listener = {
++	.notify = handle_keyboard_focus_event,
++};
++
++static void
++handle_data_device_event(struct wl_listener *listener, void *data)
++{
++	struct event *ev = data;
++
++	if (ev->type != DATA_DEVICE_EVENT_SELECTION_CHANGED)
++		return;
++
++	if (seat.keyboard.focus.client)
++		data_device_offer_selection(&seat.data_device, seat.keyboard.focus.client);
++}
++
++static struct wl_listener data_device_listener = {
++	.notify = handle_data_device_event,
++};
++
++static void
++handle_swc_event(struct wl_listener *listener, void *data)
++{
++	struct event *ev = data;
++
++	switch (ev->type) {
++	case SWC_EVENT_DEACTIVATED:
++		seat.ignore = true;
++		keyboard_reset(&seat.keyboard);
++		break;
++	case SWC_EVENT_ACTIVATED:
++		seat.ignore = false;
++		break;
++	}
++}
++
++/* Wayland Seat Interface */
++static void
++get_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id)
++{
++	pointer_bind(&seat.pointer, client, wl_resource_get_version(resource), id);
++}
++
++static void
++get_keyboard(struct wl_client *client, struct wl_resource *resource, uint32_t id)
++{
++	keyboard_bind(&seat.keyboard, client, wl_resource_get_version(resource), id);
++}
++
++static void
++get_touch(struct wl_client *client, struct wl_resource *resource, uint32_t id)
++{
++	/* XXX: Implement */
++}
++
++static struct wl_seat_interface seat_implementation = {
++	.get_pointer = get_pointer,
++	.get_keyboard = get_keyboard,
++	.get_touch = get_touch,
++};
++
++static void
++bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
++{
++	struct wl_resource *resource;
++
++	if (version > 4)
++		version = 4;
++
++	resource = wl_resource_create(client, &wl_seat_interface, version, id);
++	wl_resource_set_implementation(resource, &seat_implementation, NULL, &remove_resource);
++	wl_list_insert(&seat.resources, wl_resource_get_link(resource));
++
++	if (version >= 2)
++		wl_seat_send_name(resource, seat.name);
++
++	wl_seat_send_capabilities(resource, seat.capabilities);
++}
++
++static int
++handle_ws_data(int fd, uint32_t mask, void *data)
++{
++	struct wscons_event ev;
++
++	while (!seat.ignore && (read(fd, &ev, sizeof(ev))) != -1) {
++		uint32_t state, time;
++		int key;
++		wl_fixed_t pos;
++
++		time = ev.time.tv_sec + (ev.time.tv_nsec / 1000000L);
++		switch (ev.type) {
++		case WSCONS_EVENT_KEY_UP:
++			state = WL_KEYBOARD_KEY_STATE_RELEASED;
++			key = ev.value;
++			keyboard_handle_key(&seat.keyboard, time, key, state);
++			break;
++		case WSCONS_EVENT_KEY_DOWN:
++			state = WL_KEYBOARD_KEY_STATE_PRESSED;
++			key = ev.value;
++			keyboard_handle_key(&seat.keyboard, time, key, state);
++			break;
++		case WSCONS_EVENT_ALL_KEYS_UP:
++			break;
++		case WSCONS_EVENT_MOUSE_UP:
++			state = WL_POINTER_BUTTON_STATE_RELEASED;
++			key = ev.value;
++			pointer_handle_button(&seat.pointer, time, key, state);
++			break;
++		case WSCONS_EVENT_MOUSE_DOWN:
++			state = WL_POINTER_BUTTON_STATE_PRESSED;
++			key = ev.value;
++			pointer_handle_button(&seat.pointer, time, key, state);
++			break;
++		case WSCONS_EVENT_MOUSE_DELTA_X:
++			pos = wl_fixed_from_int(ev.value);
++			pointer_handle_relative_motion(&seat.pointer, time, pos, 0);
++			break;
++		case WSCONS_EVENT_MOUSE_DELTA_Y:
++			pos = wl_fixed_from_int(ev.value);
++			pointer_handle_relative_motion(&seat.pointer, time, 0, pos);
++			break;
++		case WSCONS_EVENT_MOUSE_DELTA_Z:
++			pos = wl_fixed_from_int(ev.value);
++			break;
++		case WSCONS_EVENT_MOUSE_DELTA_W:
++			pos = wl_fixed_from_int(ev.value);
++			break;
++		case WSCONS_EVENT_MOUSE_ABSOLUTE_X:
++			pos = wl_fixed_from_int(ev.value);
++			pointer_handle_absolute_motion(&seat.pointer, time, pos, 0);
++			break;
++		case WSCONS_EVENT_MOUSE_ABSOLUTE_Y:
++			pos = wl_fixed_from_int(ev.value);
++			pointer_handle_absolute_motion(&seat.pointer, time, 0, pos);
++			break;	
++		case WSCONS_EVENT_MOUSE_ABSOLUTE_Z:
++			pos = wl_fixed_from_int(ev.value);
++			break;	
++		case WSCONS_EVENT_MOUSE_ABSOLUTE_W:
++			pos = wl_fixed_from_int(ev.value);
++			break;	
++		
++		}
++	}
++	return 0;
++}
++
++static bool
++initialize_wscons(void)
++{
++	if ((seat.mouse_fd = open("/dev/wsmouse", O_RDONLY | O_NONBLOCK)) == -1) {
++		goto error0;
++	}
++	if ((seat.kbd_fd = open("/dev/wskbd", O_RDONLY | O_NONBLOCK)) == -1) {
++		goto error1;
++	}
++
++	seat.kbd_source = wl_event_loop_add_fd
++		(swc.event_loop, seat.kbd_fd, WL_EVENT_READABLE,
++		 &handle_ws_data, NULL);
++	seat.mouse_source = wl_event_loop_add_fd
++		(swc.event_loop, seat.mouse_fd, WL_EVENT_READABLE,
++		 &handle_ws_data, NULL);
++	return true;
++error1:
++	close(seat.mouse_fd);
++error0:
++	return false;
++}
++
++bool
++seat_initialize(const char *seat_name)
++{
++	if (!(seat.name = strdup(seat_name))) {
++		ERROR("Could not allocate seat name string\n");
++		goto error0;
++	}
++
++	seat.capabilities = WL_SEAT_CAPABILITY_KEYBOARD | WL_SEAT_CAPABILITY_POINTER;
++	seat.global = wl_global_create(swc.display, &wl_seat_interface, 4, NULL, &bind_seat);
++
++	if (!seat.global)
++		goto error1;
++
++	wl_list_init(&seat.resources);
++	seat.swc_listener.notify = &handle_swc_event;
++	wl_signal_add(&swc.event_signal, &seat.swc_listener);
++
++	if (!data_device_initialize(&seat.data_device)) {
++		ERROR("Could not initialize data device\n");
++		goto error2;
++	}
++
++	wl_signal_add(&seat.data_device.event_signal, &data_device_listener);
++
++	if (!keyboard_initialize(&seat.keyboard)) {
++		ERROR("Could not initialize keyboard\n");
++		goto error3;
++	}
++
++	wl_signal_add(&seat.keyboard.focus.event_signal, &keyboard_focus_listener);
++
++	if (!pointer_initialize(&seat.pointer)) {
++		ERROR("Could not initialize pointer\n");
++		goto error4;
++	}
++
++	if (!initialize_wscons())
++		goto error5;
++
++	return true;
++
++error5:
++	pointer_finalize(&seat.pointer);
++error4:
++	keyboard_finalize(&seat.keyboard);
++error3:
++	data_device_finalize(&seat.data_device);
++error2:
++	wl_global_destroy(seat.global);
++error1:
++	free(seat.name);
++error0:
++	return false;
++}
++
++void
++seat_finalize(void)
++{
++	wl_event_source_remove(seat.mouse_source);
++	wl_event_source_remove(seat.kbd_source);
++	close(seat.mouse_fd);
++	seat.mouse_fd = -1;
++	close(seat.kbd_fd);
++	seat.kbd_fd = -1;
++
++	pointer_finalize(&seat.pointer);
++	keyboard_finalize(&seat.keyboard);
++	data_device_finalize(&seat.data_device);
++
++	wl_global_destroy(seat.global);
++	free(seat.name);
++}
diff --git a/swc/patches/patch-libswc_seat.c b/swc/patches/patch-libswc_seat.c
new file mode 100644
index 0000000000..da61b804fd
--- /dev/null
+++ b/swc/patches/patch-libswc_seat.c
@@ -0,0 +1,411 @@
+$NetBSD$
+
+--- libswc/seat.c.orig	2019-07-11 06:33:41.000000000 +0000
++++ libswc/seat.c
+@@ -40,403 +40,26 @@
+ #include <string.h>
+ #include <unistd.h>
+ 
+-#include <libinput.h>
+-#include <linux/input.h>
+-#ifdef ENABLE_LIBUDEV
+-# include <libudev.h>
+-#endif
+-
+-static struct {
+-	char *name;
+-	uint32_t capabilities;
+-
+-	struct libinput *libinput;
+-	struct wl_event_source *libinput_source;
+-
+-#ifdef ENABLE_LIBUDEV
+-	struct udev *udev;
+-#endif
+-
+-	struct wl_listener swc_listener;
+-
+-	struct keyboard keyboard;
+-	struct pointer pointer;
+-	struct data_device data_device;
+-
+-	struct wl_global *global;
+-	struct wl_list resources;
+-} seat;
+-
+ const struct swc_seat swc_seat = {
+-	.pointer = &seat.pointer,
+-	.keyboard = &seat.keyboard,
+-	.data_device = &seat.data_device,
+-};
+-
+-static void
+-handle_keyboard_focus_event(struct wl_listener *listener, void *data)
+-{
+-	struct event *ev = data;
+-	struct input_focus_event_data *event_data = ev->data;
+-
+-	if (ev->type != INPUT_FOCUS_EVENT_CHANGED)
+-		return;
+-
+-	if (event_data->new) {
+-		struct wl_client *client = wl_resource_get_client(event_data->new->surface->resource);
+-
+-		/* Offer the selection to the new focus. */
+-		data_device_offer_selection(&seat.data_device, client);
+-	}
+-}
+-
+-static struct wl_listener keyboard_focus_listener = {
+-	.notify = handle_keyboard_focus_event,
+-};
+-
+-static void
+-handle_data_device_event(struct wl_listener *listener, void *data)
+-{
+-	struct event *ev = data;
+-
+-	if (ev->type != DATA_DEVICE_EVENT_SELECTION_CHANGED)
+-		return;
+-
+-	if (seat.keyboard.focus.client)
+-		data_device_offer_selection(&seat.data_device, seat.keyboard.focus.client);
+-}
+-
+-static struct wl_listener data_device_listener = {
+-	.notify = handle_data_device_event,
+-};
+-
+-static void
+-handle_swc_event(struct wl_listener *listener, void *data)
+-{
+-	struct event *ev = data;
+-
+-	switch (ev->type) {
+-	case SWC_EVENT_DEACTIVATED:
+-		libinput_suspend(seat.libinput);
+-		keyboard_reset(&seat.keyboard);
+-		break;
+-	case SWC_EVENT_ACTIVATED:
+-		if (libinput_resume(seat.libinput) != 0)
+-			WARNING("Failed to resume libinput context\n");
+-		break;
+-	}
+-}
+-
+-/* Wayland Seat Interface */
+-static void
+-get_pointer(struct wl_client *client, struct wl_resource *resource, uint32_t id)
+-{
+-	pointer_bind(&seat.pointer, client, wl_resource_get_version(resource), id);
+-}
+-
+-static void
+-get_keyboard(struct wl_client *client, struct wl_resource *resource, uint32_t id)
+-{
+-	keyboard_bind(&seat.keyboard, client, wl_resource_get_version(resource), id);
+-}
+-
+-static void
+-get_touch(struct wl_client *client, struct wl_resource *resource, uint32_t id)
+-{
+-	/* XXX: Implement */
+-}
+-
+-static struct wl_seat_interface seat_implementation = {
+-	.get_pointer = get_pointer,
+-	.get_keyboard = get_keyboard,
+-	.get_touch = get_touch,
+-};
+-
+-static void
+-bind_seat(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+-{
+-	struct wl_resource *resource;
+-
+-	if (version > 4)
+-		version = 4;
+-
+-	resource = wl_resource_create(client, &wl_seat_interface, version, id);
+-	wl_resource_set_implementation(resource, &seat_implementation, NULL, &remove_resource);
+-	wl_list_insert(&seat.resources, wl_resource_get_link(resource));
+-
+-	if (version >= 2)
+-		wl_seat_send_name(resource, seat.name);
+-
+-	wl_seat_send_capabilities(resource, seat.capabilities);
+-}
+-
+-static void
+-update_capabilities(uint32_t capabilities)
+-{
+-	struct wl_resource *resource;
+-
+-	if (!(~seat.capabilities & capabilities))
+-		return;
+-
+-	seat.capabilities |= capabilities;
+-	wl_list_for_each(resource, &seat.resources, link)
+-		wl_seat_send_capabilities(resource, seat.capabilities);
+-}
+-
+-static int
+-open_restricted(const char *path, int flags, void *user_data)
+-{
+-	return launch_open_device(path, flags);
+-}
+-
+-static void
+-close_restricted(int fd, void *user_data)
+-{
+-	close(fd);
+-}
+-
+-const struct libinput_interface libinput_interface = {
+-	.open_restricted = open_restricted,
+-	.close_restricted = close_restricted,
++	.pointer = NULL,
++	.keyboard = NULL,
++	.data_device = NULL,
+ };
+ 
+-static uint32_t
+-device_capabilities(struct libinput_device *device)
+-{
+-	uint32_t capabilities = 0;
+-
+-	if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD))
+-		capabilities |= WL_SEAT_CAPABILITY_KEYBOARD;
+-	if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))
+-		capabilities |= WL_SEAT_CAPABILITY_POINTER;
+-	/* TODO: Add touch device support
+-	 * if (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH))
+-	 * 	capabilities |= WL_SEAT_CAPABILITY_TOUCH;
+-	 */
+-
+-	return capabilities;
+-}
+-
+-static void
+-handle_libinput_axis_event(struct libinput_event_pointer *event, enum libinput_pointer_axis axis)
+-{
+-	wl_fixed_t amount;
+-
+-	if (!libinput_event_pointer_has_axis(event, axis))
+-		return;
+-
+-	amount = wl_fixed_from_double(libinput_event_pointer_get_axis_value(event, axis));
+-	pointer_handle_axis(&seat.pointer, libinput_event_pointer_get_time(event), axis, amount);
+-}
+-
+-static int
+-handle_libinput_data(int fd, uint32_t mask, void *data)
+-{
+-	struct screen *screen;
+-	struct swc_rectangle *rect;
+-	struct libinput_event *generic_event;
+-	struct libinput_device *device;
+-	union {
+-		struct libinput_event_keyboard *k;
+-		struct libinput_event_pointer *p;
+-	} event;
+-	wl_fixed_t x, y;
+-	uint32_t time, key, state;
+-
+-	if (libinput_dispatch(seat.libinput) != 0) {
+-		WARNING("libinput_dispatch failed: %s\n", strerror(errno));
+-		return 0;
+-	}
+-
+-	while ((generic_event = libinput_get_event(seat.libinput))) {
+-		switch (libinput_event_get_type(generic_event)) {
+-		case LIBINPUT_EVENT_DEVICE_ADDED:
+-			device = libinput_event_get_device(generic_event);
+-			update_capabilities(device_capabilities(device));
+-			if (swc.manager->new_device)
+-				swc.manager->new_device(device);
+-			break;
+-		case LIBINPUT_EVENT_KEYBOARD_KEY:
+-			event.k = libinput_event_get_keyboard_event(generic_event);
+-			time = libinput_event_keyboard_get_time(event.k);
+-			key = libinput_event_keyboard_get_key(event.k);
+-			state = libinput_event_keyboard_get_key_state(event.k);
+-			keyboard_handle_key(&seat.keyboard, time, key, state);
+-			break;
+-		case LIBINPUT_EVENT_POINTER_MOTION:
+-			event.p = libinput_event_get_pointer_event(generic_event);
+-			time = libinput_event_pointer_get_time(event.p);
+-			x = wl_fixed_from_double(libinput_event_pointer_get_dx(event.p));
+-			y = wl_fixed_from_double(libinput_event_pointer_get_dy(event.p));
+-			pointer_handle_relative_motion(&seat.pointer, time, x, y);
+-			break;
+-		case LIBINPUT_EVENT_POINTER_MOTION_ABSOLUTE:
+-			screen = wl_container_of(swc.screens.next, screen, link);
+-			rect = &screen->base.geometry;
+-			event.p = libinput_event_get_pointer_event(generic_event);
+-			time = libinput_event_pointer_get_time(event.p);
+-			x = wl_fixed_from_double(libinput_event_pointer_get_absolute_x_transformed(event.p, rect->width));
+-			y = wl_fixed_from_double(libinput_event_pointer_get_absolute_y_transformed(event.p, rect->height));
+-			pointer_handle_absolute_motion(&seat.pointer, time, x, y);
+-			break;
+-		case LIBINPUT_EVENT_POINTER_BUTTON:
+-			event.p = libinput_event_get_pointer_event(generic_event);
+-			time = libinput_event_pointer_get_time(event.p);
+-			key = libinput_event_pointer_get_button(event.p);
+-			state = libinput_event_pointer_get_button_state(event.p);
+-			pointer_handle_button(&seat.pointer, time, key, state);
+-			if (state == LIBINPUT_BUTTON_STATE_PRESSED) {
+-		                /* qemu generates GEAR_UP/GEAR_DOWN events on scroll, so pass
+-				 * those through as axis events. */
+-				switch (key) {
+-				case BTN_GEAR_DOWN:
+-					pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(10));
+-					break;
+-				case BTN_GEAR_UP:
+-					pointer_handle_axis(&seat.pointer, time, WL_POINTER_AXIS_VERTICAL_SCROLL, wl_fixed_from_int(-10));
+-					break;
+-				}
+-			}
+-			break;
+-		case LIBINPUT_EVENT_POINTER_AXIS:
+-			event.p = libinput_event_get_pointer_event(generic_event);
+-			handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
+-			handle_libinput_axis_event(event.p, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
+-			break;
+-		default:
+-			break;
+-		}
+-
+-		libinput_event_destroy(generic_event);
+-	}
+-
+-	return 0;
+-}
+-
+ bool
+ initialize_libinput(const char *seat_name)
+ {
+-#ifdef ENABLE_LIBUDEV
+-	if (!(seat.udev = udev_new())) {
+-		ERROR("Could not create udev context\n");
+-		goto error0;
+-	}
+-
+-	seat.libinput = libinput_udev_create_context(&libinput_interface, NULL, seat.udev);
+-#else
+-	seat.libinput = libinput_netlink_create_context(&libinput_interface, NULL);
+-#endif
+-
+-	if (!seat.libinput) {
+-		ERROR("Could not create libinput context\n");
+-		goto error1;
+-	}
+-
+-#ifdef ENABLE_LIBUDEV
+-	if (libinput_udev_assign_seat(seat.libinput, seat_name) != 0) {
+-		ERROR("Failed to assign seat to libinput context\n");
+-		goto error2;
+-	}
+-#else
+-	if (libinput_netlink_assign_seat(seat.libinput, seat_name) != 0) {
+-		ERROR("Failed to assign seat to libinput context\n");
+-		goto error2;
+-	}
+-#endif
+-
+-	seat.libinput_source = wl_event_loop_add_fd
+-		(swc.event_loop, libinput_get_fd(seat.libinput), WL_EVENT_READABLE,
+-		 &handle_libinput_data, NULL);
+-
+-	if (!seat.libinput_source) {
+-		ERROR("Could not create event source for libinput\n");
+-		goto error2;
+-	}
+-
+-	if (!swc.active)
+-		libinput_suspend(seat.libinput);
+-
+-	return true;
+-
+-error2:
+-	libinput_unref(seat.libinput);
+-error1:
+-#ifdef ENABLE_LIBUDEV
+-	udev_unref(seat.udev);
+-error0:
+-#endif
+ 	return false;
+ }
+ 
+ bool
+ seat_initialize(const char *seat_name)
+ {
+-	if (!(seat.name = strdup(seat_name))) {
+-		ERROR("Could not allocate seat name string\n");
+-		goto error0;
+-	}
+-
+-	seat.global = wl_global_create(swc.display, &wl_seat_interface, 4, NULL, &bind_seat);
+-
+-	if (!seat.global)
+-		goto error1;
+-
+-	seat.capabilities = 0;
+-	wl_list_init(&seat.resources);
+-	seat.swc_listener.notify = &handle_swc_event;
+-	wl_signal_add(&swc.event_signal, &seat.swc_listener);
+-
+-	if (!data_device_initialize(&seat.data_device)) {
+-		ERROR("Could not initialize data device\n");
+-		goto error2;
+-	}
+-
+-	wl_signal_add(&seat.data_device.event_signal, &data_device_listener);
+-
+-	if (!keyboard_initialize(&seat.keyboard)) {
+-		ERROR("Could not initialize keyboard\n");
+-		goto error3;
+-	}
+-
+-	wl_signal_add(&seat.keyboard.focus.event_signal, &keyboard_focus_listener);
+-
+-	if (!pointer_initialize(&seat.pointer)) {
+-		ERROR("Could not initialize pointer\n");
+-		goto error4;
+-	}
+-
+-	if (!initialize_libinput(seat.name))
+-		goto error5;
+-
+-	return true;
+-
+-error5:
+-	pointer_finalize(&seat.pointer);
+-error4:
+-	keyboard_finalize(&seat.keyboard);
+-error3:
+-	data_device_finalize(&seat.data_device);
+-error2:
+-	wl_global_destroy(seat.global);
+-error1:
+-	free(seat.name);
+-error0:
+ 	return false;
+ }
+ 
+ void
+ seat_finalize(void)
+ {
+-	wl_event_source_remove(seat.libinput_source);
+-	libinput_unref(seat.libinput);
+-#ifdef ENABLE_LIBUDEV
+-	udev_unref(seat.udev);
+-#endif
+-
+-	pointer_finalize(&seat.pointer);
+-	keyboard_finalize(&seat.keyboard);
+-	data_device_finalize(&seat.data_device);
+ 
+-	wl_global_destroy(seat.global);
+-	free(seat.name);
+ }
diff --git a/swc/patches/patch-libswc_shm.c b/swc/patches/patch-libswc_shm.c
new file mode 100644
index 0000000000..0c76bf1fab
--- /dev/null
+++ b/swc/patches/patch-libswc_shm.c
@@ -0,0 +1,40 @@
+$NetBSD$
+
+--- libswc/shm.c.orig	2019-07-11 06:33:41.000000000 +0000
++++ libswc/shm.c
+@@ -47,7 +47,7 @@ static struct {
+ struct pool {
+ 	struct wl_resource *resource;
+ 	void *data;
+-	uint32_t size;
++	size_t size;
+ 	unsigned references;
+ };
+ 
+@@ -144,12 +144,15 @@ destroy(struct wl_client *client, struct
+ }
+ 
+ static void
+-resize(struct wl_client *client, struct wl_resource *resource, int32_t size)
++resize(struct wl_client *client, struct wl_resource *resource, size_t size)
+ {
+ 	struct pool *pool = wl_resource_get_user_data(resource);
+ 	void *data;
+ 
+-	data = mremap(pool->data, pool->size, size, MREMAP_MAYMOVE);
++#ifndef MREMAP_MAYMOVE
++#define MREMAP_MAYMOVE 0
++#endif
++	data = mremap(pool->data, pool->size, size, MREMAP_MAYMOVE, NULL);
+ 
+ 	if (data == MAP_FAILED) {
+ 		wl_resource_post_error(resource, WL_SHM_ERROR_INVALID_FD, "mremap failed: %s", strerror(errno));
+@@ -167,7 +170,7 @@ static struct wl_shm_pool_interface shm_
+ };
+ 
+ static void
+-create_pool(struct wl_client *client, struct wl_resource *resource, uint32_t id, int32_t fd, int32_t size)
++create_pool(struct wl_client *client, struct wl_resource *resource, uint32_t id, int32_t fd, size_t size)
+ {
+ 	struct pool *pool;
+ 



Home | Main Index | Thread Index | Old Index