summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-06-05 05:10:25 +0000
committerAlyssa Ross <hi@alyssa.is>2020-06-05 05:10:25 +0000
commit226e4ebf56c8191ad38e789d4c0f2714531d2853 (patch)
tree779246ea0d1686852ae2864ca7f55595a1e99b30
parenta1f01bb6ca7c14bb2aa14d1930525dd20e0d0ece (diff)
downloadnixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.tar
nixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.tar.gz
nixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.tar.bz2
nixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.tar.lz
nixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.tar.xz
nixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.tar.zst
nixpkgs-226e4ebf56c8191ad38e789d4c0f2714531d2853.zip
wlroots: support virtio_wl shm allocation
-rw-r--r--pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch6
-rw-r--r--pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch281
-rw-r--r--pkgs/development/libraries/wlroots/default.nix5
-rw-r--r--pkgs/top-level/all-packages.nix4
4 files changed, 290 insertions, 6 deletions
diff --git a/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch b/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch
index bec35f4d20c..c0d87cb2a80 100644
--- a/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch
+++ b/pkgs/development/libraries/wlroots/0001-backend-wayland-downgrade-to-wl_compositor-v3.patch
@@ -1,7 +1,7 @@
-From 3b37c19286b621f266e6d447cd16f1f59a3cc24c Mon Sep 17 00:00:00 2001
+From 2b266b85c8bd07cfc4d6427081ca0eaff4410511 Mon Sep 17 00:00:00 2001
 From: Alyssa Ross <hi@alyssa.is>
 Date: Thu, 23 Jan 2020 14:35:41 +0000
-Subject: [PATCH] backend/wayland: downgrade to wl_compositor v3
+Subject: [PATCH 1/2] backend/wayland: downgrade to wl_compositor v3
 
 Sommelier does not support v4.
 
@@ -52,5 +52,5 @@ index 7a3a08d0..f332ad93 100644
  
  			output->pending_buffer = NULL;
 -- 
-2.24.1
+2.26.2
 
diff --git a/pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch b/pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch
new file mode 100644
index 00000000000..ef9526af213
--- /dev/null
+++ b/pkgs/development/libraries/wlroots/0002-util-support-virtio_wl-shm-allocation.patch
@@ -0,0 +1,281 @@
+From 6262ddb96410fd2fd21edbd96d79f1149e698948 Mon Sep 17 00:00:00 2001
+From: Alyssa Ross <hi@alyssa.is>
+Date: Sat, 23 May 2020 03:42:33 +0000
+Subject: [PATCH 2/2] util: support virtio_wl shm allocation
+
+---
+ include/util/virtio_wl.h     | 14 ++++++
+ include/util/virtio_wl_shm.h |  8 +++
+ util/meson.build             |  2 +
+ util/shm.c                   | 12 +++++
+ util/virtio_wl.c             | 96 ++++++++++++++++++++++++++++++++++++
+ util/virtio_wl_shm.c         | 65 ++++++++++++++++++++++++
+ 6 files changed, 197 insertions(+)
+ create mode 100644 include/util/virtio_wl.h
+ create mode 100644 include/util/virtio_wl_shm.h
+ create mode 100644 util/virtio_wl.c
+ create mode 100644 util/virtio_wl_shm.c
+
+diff --git a/include/util/virtio_wl.h b/include/util/virtio_wl.h
+new file mode 100644
+index 00000000..ae5c19b5
+--- /dev/null
++++ b/include/util/virtio_wl.h
+@@ -0,0 +1,14 @@
++#ifndef UTIL_VIRTIO_WL_H
++#define UTIL_VIRTIO_WL_H
++
++struct virtwl_ioctl_txn;
++
++int virtio_wl_connect(const char *name, uint32_t flags);
++
++int32_t virtio_wl_sendmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn);
++int32_t virtio_wl_send(int sockfd, const void *buf, uint32_t len);
++
++int32_t virtio_wl_recvmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn);
++int32_t virtio_wl_recv(int sockfd, void *buf, uint32_t len);
++
++#endif
+diff --git a/include/util/virtio_wl_shm.h b/include/util/virtio_wl_shm.h
+new file mode 100644
+index 00000000..d9f9f045
+--- /dev/null
++++ b/include/util/virtio_wl_shm.h
+@@ -0,0 +1,8 @@
++#ifndef UTIL_VIRTIO_WL_SHM_H
++#define UTIL_VIRTIO_WL_SHM_H
++
++#include <stddef.h>
++
++int allocate_virtio_wl_shm_file(size_t size);
++
++#endif
+diff --git a/util/meson.build b/util/meson.build
+index c6614275..6ec6182b 100644
+--- a/util/meson.build
++++ b/util/meson.build
+@@ -4,4 +4,6 @@ wlr_files += files(
+ 	'region.c',
+ 	'shm.c',
+ 	'signal.c',
++	'virtio_wl.c',
++	'virtio_wl_shm.c',
+ )
+diff --git a/util/shm.c b/util/shm.c
+index f7c7303e..d8110904 100644
+--- a/util/shm.c
++++ b/util/shm.c
+@@ -2,11 +2,14 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <string.h>
++#include <stdlib.h>
+ #include <sys/mman.h>
+ #include <time.h>
+ #include <unistd.h>
+ #include <wlr/config.h>
++#include <wlr/util/log.h>
+ #include "util/shm.h"
++#include "util/virtio_wl_shm.h"
+ 
+ static void randname(char *buf) {
+ 	struct timespec ts;
+@@ -19,6 +22,11 @@ static void randname(char *buf) {
+ }
+ 
+ int create_shm_file(void) {
++	if (getenv("WLR_VIRTIO_WL")) {
++		wlr_log(WLR_ERROR, "cannot use create_shm_file with virtio_wl");
++		return -1;
++	}
++
+ 	int retries = 100;
+ 	do {
+ 		char name[] = "/wlroots-XXXXXX";
+@@ -37,6 +45,10 @@ int create_shm_file(void) {
+ }
+ 
+ int allocate_shm_file(size_t size) {
++	if (getenv("WLR_VIRTIO_WL")) {
++		return allocate_virtio_wl_shm_file(size);
++	}
++
+ 	int fd = create_shm_file();
+ 	if (fd < 0) {
+ 		return -1;
+diff --git a/util/virtio_wl.c b/util/virtio_wl.c
+new file mode 100644
+index 00000000..e7ee58ac
+--- /dev/null
++++ b/util/virtio_wl.c
+@@ -0,0 +1,96 @@
++#define _POSIX_C_SOURCE 200809L
++
++#include <fcntl.h>
++#include <linux/virtwl.h>
++#include <stdint.h>
++#include <string.h>
++#include <sys/ioctl.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include "util/virtio_wl.h"
++
++// This is essentially vendored reusable library code, so I consider
++// it exempt from the wlroots style guide. :)
++
++int virtio_wl_connect(const char *name, uint32_t flags)
++{
++	static int wl_fd = -1;
++	if (wl_fd < 0)
++		wl_fd = open("/dev/wl0", O_RDWR | O_CLOEXEC);
++	if (wl_fd < 0)
++		return wl_fd;
++
++	struct virtwl_ioctl_new new_ctx = {
++		.type = name ? VIRTWL_IOCTL_NEW_CTX_NAMED : VIRTWL_IOCTL_NEW_CTX,
++		.fd = -1,
++		.flags = flags,
++	};
++	// Device assumes name 32 bytes long if not null terminated.
++#pragma GCC diagnostic push
++#pragma GCC diagnostic ignored "-Wstringop-truncation"
++	if (name)
++		strncpy(new_ctx.name, name, sizeof(new_ctx.name));
++#pragma GCC diagnostic pop
++
++	if (ioctl(wl_fd, VIRTWL_IOCTL_NEW, &new_ctx))
++		return -1;
++
++	return new_ctx.fd;
++}
++
++int32_t virtio_wl_sendmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn)
++{
++	int r = ioctl(sockfd, VIRTWL_IOCTL_SEND, ioctl_txn);
++	if (!r)
++		r = ioctl_txn->len > INT32_MAX ? INT32_MAX : ioctl_txn->len;
++	return r;
++}
++
++int32_t virtio_wl_send(int sockfd, const void *buf, uint32_t len)
++{
++	struct virtwl_ioctl_txn *ioctl_txn = malloc(sizeof(*ioctl_txn) + len);
++	if (!ioctl_txn)
++		return -1;
++
++	for (size_t i = 0; i < VIRTWL_SEND_MAX_ALLOCS; i++)
++		ioctl_txn->fds[i] = -1;
++
++	ioctl_txn->len = len;
++	memcpy((uint8_t *)ioctl_txn + sizeof(*ioctl_txn), buf, len);
++
++	int r = virtio_wl_sendmsg(sockfd, ioctl_txn);
++
++	free(ioctl_txn);
++	return r;
++}
++
++int32_t virtio_wl_recvmsg(int sockfd, struct virtwl_ioctl_txn *ioctl_txn)
++{
++	if (ioctl(sockfd, VIRTWL_IOCTL_RECV, ioctl_txn))
++		return -1;
++
++	return ioctl_txn->len > INT32_MAX ? INT32_MAX : ioctl_txn->len;
++}
++
++int32_t virtio_wl_recv(int sockfd, void *buf, uint32_t len)
++{
++	struct virtwl_ioctl_txn *ioctl_txn = malloc(sizeof(*ioctl_txn) + len);
++	if (!ioctl_txn)
++		return -1;
++
++	ioctl_txn->len = len;
++
++	int rv = virtio_wl_recvmsg(sockfd, ioctl_txn);
++	if (rv < 0)
++		goto cleanup;
++
++	memcpy(buf, (uint8_t *)ioctl_txn + sizeof(*ioctl_txn), ioctl_txn->len);
++
++	for (size_t i = 0; i < VIRTWL_SEND_MAX_ALLOCS; i++)
++		if (ioctl_txn->fds[i] >= 0)
++			close(ioctl_txn->fds[i]);
++
++ cleanup:
++	free(ioctl_txn);
++	return rv;
++}
+diff --git a/util/virtio_wl_shm.c b/util/virtio_wl_shm.c
+new file mode 100644
+index 00000000..b2109310
+--- /dev/null
++++ b/util/virtio_wl_shm.c
+@@ -0,0 +1,65 @@
++#include <assert.h>
++#include <errno.h>
++#include <linux/virtwl.h>
++#include <stdint.h>
++#include <stdlib.h>
++#include <string.h>
++#include "util/virtio_wl.h"
++#include "util/virtio_wl_shm.h"
++
++// This is essentially vendored reusable library code, so I consider
++// it exempt from the wlroots style guide. :)
++
++int allocate_virtio_wl_shm_file(size_t size)
++{
++	static const size_t NAME_SIZE = 224;
++	static const char *NAME = "wlroots";
++
++	int r;
++	uint8_t *message = NULL;
++	struct virtwl_ioctl_txn *ioctl_txn = NULL;
++
++	int conn = virtio_wl_connect("__crosvm_memfd", 0);
++	if (conn < 0)
++		return conn;
++
++	message = calloc(NAME_SIZE + 8, 1);
++	if (!message) {
++		r = -1;
++		goto cleanup;
++	}
++	strcpy((char *)message, NAME);
++
++	// Encode size as 64-bit little-endian unsigned integer.
++	for (uint8_t i = 0; i < 8; i++)
++		message[NAME_SIZE + i] = (uint8_t)((uint64_t)size >> (8 * i));
++
++	if ((r = virtio_wl_send(conn, message, NAME_SIZE + 8)) < 0)
++		 goto cleanup;
++
++	int32_t len = 1;
++	if (!(ioctl_txn = malloc(sizeof(*ioctl_txn) + len))) {
++		r = -1;
++		goto cleanup;
++	}
++	ioctl_txn->len = len;
++
++	if ((r = virtio_wl_recvmsg(conn, ioctl_txn)) < 0)
++		goto cleanup;
++
++	if (((uint8_t *)ioctl_txn + sizeof(*ioctl_txn))[0]) {
++		// We don't actually know why we didn't get the
++		// memory, but out of memory is a reasonable guess.
++		errno = ENOMEM;
++		r = -1;
++		goto cleanup;
++	}
++
++	r = ioctl_txn->fds[0];
++	assert(r >= 0);
++
++ cleanup:
++	free(message);
++	free(ioctl_txn);
++	return r;
++}
+-- 
+2.26.2
+
diff --git a/pkgs/development/libraries/wlroots/default.nix b/pkgs/development/libraries/wlroots/default.nix
index da3876737e9..a2a8f42be16 100644
--- a/pkgs/development/libraries/wlroots/default.nix
+++ b/pkgs/development/libraries/wlroots/default.nix
@@ -1,7 +1,7 @@
 { stdenv, fetchFromGitHub, meson, ninja, pkg-config, wayland
 , libGL, wayland-protocols, libinput, libxkbcommon, pixman
 , xcbutilwm, libX11, libcap, xcbutilimage, xcbutilerrors, mesa
-, libpng, ffmpeg_4
+, libpng, ffmpeg_4, linuxHeaders
 }:
 
 stdenv.mkDerivation rec {
@@ -17,6 +17,7 @@ stdenv.mkDerivation rec {
 
   patches = [
     ./0001-backend-wayland-downgrade-to-wl_compositor-v3.patch
+    ./0002-util-support-virtio_wl-shm-allocation.patch
   ];
 
   # $out for the library and $examples for the example programs (in examples):
@@ -27,7 +28,7 @@ stdenv.mkDerivation rec {
   buildInputs = [
     libGL wayland-protocols libinput libxkbcommon pixman
     xcbutilwm libX11 libcap xcbutilimage xcbutilerrors mesa
-    libpng ffmpeg_4
+    libpng ffmpeg_4 linuxHeaders
   ];
 
   postInstall = ''
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 3264216784c..3a28cb521ef 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -20027,7 +20027,9 @@ in
 
   wlr-randr = callPackage ../tools/misc/wlr-randr { };
 
-  wlroots = callPackage ../development/libraries/wlroots { };
+  wlroots = callPackage ../development/libraries/wlroots {
+    inherit (chromiumOSPackages) linuxHeaders;
+  };
 
   sway-unwrapped = callPackage ../applications/window-managers/sway { };
   sway = callPackage ../applications/window-managers/sway/wrapper.nix { };