[mutter] wayland/keyboard: Use MetaAnonymousFile to share keymap files
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] wayland/keyboard: Use MetaAnonymousFile to share keymap files
- Date: Tue, 21 Apr 2020 16:22:51 +0000 (UTC)
commit 988da215c8e66c20240b0a23a19fcf8e405e64d6
Author: Jonas Dreßler <verdre v0yd nl>
Date: Fri Jan 17 23:54:31 2020 +0100
wayland/keyboard: Use MetaAnonymousFile to share keymap files
Since protocol version 7 clients must use MAP_PRIVATE to map the keymap
fd, that means we can use memfd_create() to create the fd by using
meta_anonymous_file_open_fd() with META_ANONYMOUS_FILE_MAPMODE_PRIVATE,
for older versions we use META_ANONYMOUS_FILE_MAPMODE_SHARED to be
compatibile with MAP_SHARED.
Pretty much all of this code was written for Weston by Sebastian Wick,
see https://gitlab.freedesktop.org/wayland/weston/merge_requests/240.
Co-authored-by: Sebastian Wick <sebastian sebastianwick net>
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/1734
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1012
src/wayland/meta-wayland-keyboard.c | 103 +++++++++++-------------------------
src/wayland/meta-wayland-keyboard.h | 4 +-
2 files changed, 33 insertions(+), 74 deletions(-)
---
diff --git a/src/wayland/meta-wayland-keyboard.c b/src/wayland/meta-wayland-keyboard.c
index 6b6c1f778..cc569faf7 100644
--- a/src/wayland/meta-wayland-keyboard.c
+++ b/src/wayland/meta-wayland-keyboard.c
@@ -48,15 +48,14 @@
#include "config.h"
#include <errno.h>
-#include <fcntl.h>
#include <glib.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/mman.h>
#include <unistd.h>
#include "backends/meta-backend-private.h"
#include "core/display-private.h"
+#include "core/meta-anonymous-file.h"
#include "wayland/meta-wayland-private.h"
#ifdef HAVE_NATIVE_BACKEND
@@ -79,86 +78,34 @@ unbind_resource (struct wl_resource *resource)
wl_list_remove (wl_resource_get_link (resource));
}
-static int
-create_anonymous_file (off_t size,
- GError **error)
-{
- static const char template[] = "mutter-shared-XXXXXX";
- char *path;
- int fd, flags;
-
- fd = g_file_open_tmp (template, &path, error);
-
- if (fd == -1)
- return -1;
-
- unlink (path);
- g_free (path);
-
- flags = fcntl (fd, F_GETFD);
- if (flags == -1)
- goto err;
-
- if (fcntl (fd, F_SETFD, flags | FD_CLOEXEC) == -1)
- goto err;
-
- if (ftruncate (fd, size) < 0)
- goto err;
-
- return fd;
-
- err:
- g_set_error_literal (error,
- G_FILE_ERROR,
- g_file_error_from_errno (errno),
- strerror (errno));
- close (fd);
-
- return -1;
-}
-
static void
send_keymap (MetaWaylandKeyboard *keyboard,
struct wl_resource *resource)
{
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
- GError *error = NULL;
int fd;
- char *keymap_area;
-
- if (!xkb_info->keymap_string)
- return;
+ size_t size;
+ MetaAnonymousFileMapmode mapmode;
- fd = create_anonymous_file (xkb_info->keymap_size, &error);
- if (fd < 0)
- {
- g_warning ("Creating a keymap file for %lu bytes failed: %s",
- (unsigned long) xkb_info->keymap_size,
- error->message);
- g_clear_error (&error);
- return;
- }
+ if (wl_resource_get_version (resource) < 7)
+ mapmode = META_ANONYMOUS_FILE_MAPMODE_SHARED;
+ else
+ mapmode = META_ANONYMOUS_FILE_MAPMODE_PRIVATE;
+ fd = meta_anonymous_file_open_fd (xkb_info->keymap_rofile, mapmode);
+ size = meta_anonymous_file_size (xkb_info->keymap_rofile);
- keymap_area = mmap (NULL, xkb_info->keymap_size,
- PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
- if (keymap_area == MAP_FAILED)
+ if (fd == -1)
{
- g_warning ("Failed to mmap() %lu bytes\n",
- (unsigned long) xkb_info->keymap_size);
- close (fd);
+ g_warning ("Creating a keymap file failed: %s", strerror (errno));
return;
}
- strcpy (keymap_area, xkb_info->keymap_string);
-
- munmap (keymap_area, xkb_info->keymap_size);
-
wl_keyboard_send_keymap (resource,
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
- fd,
- keyboard->xkb_info.keymap_size);
- close (fd);
+ fd, size);
+
+ meta_anonymous_file_close_fd (fd);
}
static void
@@ -177,6 +124,8 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
struct xkb_keymap *keymap)
{
MetaWaylandXkbInfo *xkb_info = &keyboard->xkb_info;
+ char *keymap_string;
+ size_t keymap_size;
if (keymap == NULL)
{
@@ -184,20 +133,30 @@ meta_wayland_keyboard_take_keymap (MetaWaylandKeyboard *keyboard,
return;
}
- g_clear_pointer (&xkb_info->keymap_string, g_free);
xkb_keymap_unref (xkb_info->keymap);
xkb_info->keymap = xkb_keymap_ref (keymap);
meta_wayland_keyboard_update_xkb_state (keyboard);
- xkb_info->keymap_string =
+ keymap_string =
xkb_keymap_get_as_string (xkb_info->keymap, XKB_KEYMAP_FORMAT_TEXT_V1);
- if (!xkb_info->keymap_string)
+ if (!keymap_string)
{
g_warning ("Failed to get string version of keymap");
return;
}
- xkb_info->keymap_size = strlen (xkb_info->keymap_string) + 1;
+ keymap_size = strlen (keymap_string) + 1;
+
+ xkb_info->keymap_rofile =
+ meta_anonymous_file_new (keymap_size, (const uint8_t *) keymap_string);
+
+ free (keymap_string);
+
+ if (!xkb_info->keymap_rofile)
+ {
+ g_warning ("Failed to create anonymous file for keymap");
+ return;
+ }
inform_clients_of_new_keymap (keyboard);
@@ -590,7 +549,7 @@ meta_wayland_xkb_info_destroy (MetaWaylandXkbInfo *xkb_info)
{
g_clear_pointer (&xkb_info->keymap, xkb_keymap_unref);
g_clear_pointer (&xkb_info->state, xkb_state_unref);
- g_clear_pointer (&xkb_info->keymap_string, g_free);
+ meta_anonymous_file_free (xkb_info->keymap_rofile);
}
void
diff --git a/src/wayland/meta-wayland-keyboard.h b/src/wayland/meta-wayland-keyboard.h
index 1dd3b12ba..ac57d7677 100644
--- a/src/wayland/meta-wayland-keyboard.h
+++ b/src/wayland/meta-wayland-keyboard.h
@@ -49,6 +49,7 @@
#include <xkbcommon/xkbcommon.h>
#include "clutter/clutter.h"
+#include "core/meta-anonymous-file.h"
#include "wayland/meta-wayland-types.h"
#define META_TYPE_WAYLAND_KEYBOARD (meta_wayland_keyboard_get_type ())
@@ -74,8 +75,7 @@ typedef struct
{
struct xkb_keymap *keymap;
struct xkb_state *state;
- size_t keymap_size;
- char *keymap_string;
+ MetaAnonymousFile *keymap_rofile;
} MetaWaylandXkbInfo;
struct _MetaWaylandKeyboard
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]