input: use ro_anonymous_file to minimize duplication of keymap files
Since version 7 clients must use MAP_PRIVATE to map the keymap fd so we can use memfd_create in os_ro_anonymous_file_get_ref using RO_ANONYMOUS_FILE_MAPMODE_PRIVATE, for older version we use RO_ANONYMOUS_FILE_MAPMODE_SHARED to be compatibile with MAP_SHARED. Signed-off-by: Sebastian Wick <sebastian@sebastianwick.net>
This commit is contained in:
@@ -78,6 +78,7 @@ struct weston_pointer;
|
|||||||
struct linux_dmabuf_buffer;
|
struct linux_dmabuf_buffer;
|
||||||
struct weston_recorder;
|
struct weston_recorder;
|
||||||
struct weston_pointer_constraint;
|
struct weston_pointer_constraint;
|
||||||
|
struct ro_anonymous_file;
|
||||||
|
|
||||||
enum weston_keyboard_modifier {
|
enum weston_keyboard_modifier {
|
||||||
MODIFIER_CTRL = (1 << 0),
|
MODIFIER_CTRL = (1 << 0),
|
||||||
@@ -704,8 +705,7 @@ weston_pointer_start_drag(struct weston_pointer *pointer,
|
|||||||
struct wl_client *client);
|
struct wl_client *client);
|
||||||
struct weston_xkb_info {
|
struct weston_xkb_info {
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
size_t keymap_size;
|
struct ro_anonymous_file *keymap_rofile;
|
||||||
char *keymap_string;
|
|
||||||
int32_t ref_count;
|
int32_t ref_count;
|
||||||
xkb_mod_index_t shift_mod;
|
xkb_mod_index_t shift_mod;
|
||||||
xkb_mod_index_t caps_mod;
|
xkb_mod_index_t caps_mod;
|
||||||
|
|||||||
+32
-23
@@ -2086,32 +2086,30 @@ WL_EXPORT void
|
|||||||
weston_keyboard_send_keymap(struct weston_keyboard *kbd, struct wl_resource *resource)
|
weston_keyboard_send_keymap(struct weston_keyboard *kbd, struct wl_resource *resource)
|
||||||
{
|
{
|
||||||
struct weston_xkb_info *xkb_info = kbd->xkb_info;
|
struct weston_xkb_info *xkb_info = kbd->xkb_info;
|
||||||
void *area;
|
|
||||||
int fd;
|
int fd;
|
||||||
|
size_t size;
|
||||||
|
enum ro_anonymous_file_mapmode mapmode;
|
||||||
|
|
||||||
fd = os_create_anonymous_file(xkb_info->keymap_size);
|
if (wl_resource_get_version(resource) < 7)
|
||||||
if (fd < 0) {
|
mapmode = RO_ANONYMOUS_FILE_MAPMODE_SHARED;
|
||||||
weston_log("creating a keymap file for %lu bytes failed: %s\n",
|
else
|
||||||
(unsigned long) xkb_info->keymap_size,
|
mapmode = RO_ANONYMOUS_FILE_MAPMODE_PRIVATE;
|
||||||
|
|
||||||
|
fd = os_ro_anonymous_file_get_fd(xkb_info->keymap_rofile, mapmode);
|
||||||
|
size = os_ro_anonymous_file_size(xkb_info->keymap_rofile);
|
||||||
|
|
||||||
|
if (fd == -1) {
|
||||||
|
weston_log("creating a keymap file failed: %s\n",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
area = mmap(NULL, xkb_info->keymap_size, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_SHARED, fd, 0);
|
|
||||||
if (area == MAP_FAILED) {
|
|
||||||
weston_log("failed to mmap() %lu bytes\n",
|
|
||||||
(unsigned long) xkb_info->keymap_size);
|
|
||||||
goto err_mmap;
|
|
||||||
}
|
|
||||||
strcpy(area, xkb_info->keymap_string);
|
|
||||||
munmap(area, xkb_info->keymap_size);
|
|
||||||
wl_keyboard_send_keymap(resource,
|
wl_keyboard_send_keymap(resource,
|
||||||
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1,
|
||||||
fd,
|
fd,
|
||||||
xkb_info->keymap_size);
|
size);
|
||||||
err_mmap:
|
|
||||||
close(fd);
|
os_ro_anonymous_file_put_fd(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -3149,8 +3147,7 @@ weston_xkb_info_destroy(struct weston_xkb_info *xkb_info)
|
|||||||
|
|
||||||
xkb_keymap_unref(xkb_info->keymap);
|
xkb_keymap_unref(xkb_info->keymap);
|
||||||
|
|
||||||
if (xkb_info->keymap_string)
|
os_ro_anonymous_file_destroy(xkb_info->keymap_rofile);
|
||||||
free(xkb_info->keymap_string);
|
|
||||||
free(xkb_info);
|
free(xkb_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3171,6 +3168,8 @@ weston_compositor_xkb_destroy(struct weston_compositor *ec)
|
|||||||
static struct weston_xkb_info *
|
static struct weston_xkb_info *
|
||||||
weston_xkb_info_create(struct xkb_keymap *keymap)
|
weston_xkb_info_create(struct xkb_keymap *keymap)
|
||||||
{
|
{
|
||||||
|
char *keymap_string;
|
||||||
|
size_t keymap_size;
|
||||||
struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
|
struct weston_xkb_info *xkb_info = zalloc(sizeof *xkb_info);
|
||||||
if (xkb_info == NULL)
|
if (xkb_info == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -3202,13 +3201,22 @@ weston_xkb_info_create(struct xkb_keymap *keymap)
|
|||||||
xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
|
xkb_info->scroll_led = xkb_keymap_led_get_index(xkb_info->keymap,
|
||||||
XKB_LED_NAME_SCROLL);
|
XKB_LED_NAME_SCROLL);
|
||||||
|
|
||||||
xkb_info->keymap_string = xkb_keymap_get_as_string(xkb_info->keymap,
|
keymap_string = xkb_keymap_get_as_string(xkb_info->keymap,
|
||||||
XKB_KEYMAP_FORMAT_TEXT_V1);
|
XKB_KEYMAP_FORMAT_TEXT_V1);
|
||||||
if (xkb_info->keymap_string == NULL) {
|
if (keymap_string == NULL) {
|
||||||
weston_log("failed to get string version of keymap\n");
|
weston_log("failed to get string version of keymap\n");
|
||||||
goto err_keymap;
|
goto err_keymap;
|
||||||
}
|
}
|
||||||
xkb_info->keymap_size = strlen(xkb_info->keymap_string) + 1;
|
keymap_size = strlen(keymap_string) + 1;
|
||||||
|
|
||||||
|
xkb_info->keymap_rofile = os_ro_anonymous_file_create(keymap_size,
|
||||||
|
keymap_string);
|
||||||
|
free(keymap_string);
|
||||||
|
|
||||||
|
if (!xkb_info->keymap_rofile) {
|
||||||
|
weston_log("failed to create anonymous file for keymap\n");
|
||||||
|
goto err_keymap;
|
||||||
|
}
|
||||||
|
|
||||||
return xkb_info;
|
return xkb_info;
|
||||||
|
|
||||||
@@ -3441,7 +3449,8 @@ weston_seat_init(struct weston_seat *seat, struct weston_compositor *ec,
|
|||||||
wl_signal_init(&seat->destroy_signal);
|
wl_signal_init(&seat->destroy_signal);
|
||||||
wl_signal_init(&seat->updated_caps_signal);
|
wl_signal_init(&seat->updated_caps_signal);
|
||||||
|
|
||||||
seat->global = wl_global_create(ec->wl_display, &wl_seat_interface, 7,
|
seat->global = wl_global_create(ec->wl_display, &wl_seat_interface,
|
||||||
|
MIN(wl_seat_interface.version, 7),
|
||||||
seat, bind_seat);
|
seat, bind_seat);
|
||||||
|
|
||||||
seat->compositor = ec;
|
seat->compositor = ec;
|
||||||
|
|||||||
Reference in New Issue
Block a user