wayland: Add wl_global filter manager
One can add a wl_global filter to a wl_display instance, which can be used to decide what clients should see what globals. This has so far been used to limit a Xwayland specific protocol extension to only Xwayland. In order to expand the logic about what globals are filtered to what clients, introduce a filter manager and port the Xwayland specific protocol filter to this new manager. Tests are added, using a new dummy protocol, to ensure that filtering is working as expected. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2810>
This commit is contained in:
parent
192401dee5
commit
91c40a47b3
@ -595,6 +595,8 @@ if have_wayland
|
|||||||
'wayland/meta-wayland-dma-buf.h',
|
'wayland/meta-wayland-dma-buf.h',
|
||||||
'wayland/meta-wayland-dnd-surface.c',
|
'wayland/meta-wayland-dnd-surface.c',
|
||||||
'wayland/meta-wayland-dnd-surface.h',
|
'wayland/meta-wayland-dnd-surface.h',
|
||||||
|
'wayland/meta-wayland-filter-manager.c',
|
||||||
|
'wayland/meta-wayland-filter-manager.h',
|
||||||
'wayland/meta-wayland-gtk-shell.c',
|
'wayland/meta-wayland-gtk-shell.c',
|
||||||
'wayland/meta-wayland-gtk-shell.h',
|
'wayland/meta-wayland-gtk-shell.h',
|
||||||
'wayland/meta-wayland.h',
|
'wayland/meta-wayland.h',
|
||||||
|
@ -408,6 +408,9 @@ if have_native_tests
|
|||||||
'suite': 'wayland',
|
'suite': 'wayland',
|
||||||
'sources': [
|
'sources': [
|
||||||
'wayland-unit-tests.c',
|
'wayland-unit-tests.c',
|
||||||
|
dummy_client_header,
|
||||||
|
dummy_server_header,
|
||||||
|
dummy_protocol_code,
|
||||||
wayland_test_utils,
|
wayland_test_utils,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
9
src/tests/protocol/dummy.xml
Normal file
9
src/tests/protocol/dummy.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="dummy">
|
||||||
|
<description summary=""/>
|
||||||
|
<interface name="dummy" version="1">
|
||||||
|
<description summary=""/>
|
||||||
|
<request name="destroy" type="destructor"/>
|
||||||
|
<event name="event"/>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
@ -30,3 +30,36 @@ test_driver_protocol_code = custom_target(
|
|||||||
'@INPUT@', '@OUTPUT@',
|
'@INPUT@', '@OUTPUT@',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dummy_server_header = custom_target(
|
||||||
|
'dummy server header',
|
||||||
|
input: 'dummy.xml',
|
||||||
|
output: 'dummy-server-protocol.h',
|
||||||
|
command: [
|
||||||
|
wayland_scanner,
|
||||||
|
'server-header',
|
||||||
|
'@INPUT@', '@OUTPUT@',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
dummy_client_header = custom_target(
|
||||||
|
'dummy client header',
|
||||||
|
input: 'dummy.xml',
|
||||||
|
output: 'dummy-client-protocol.h',
|
||||||
|
command: [
|
||||||
|
wayland_scanner,
|
||||||
|
'client-header',
|
||||||
|
'@INPUT@', '@OUTPUT@',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
dummy_protocol_code = custom_target(
|
||||||
|
'dummy protocol code',
|
||||||
|
input: 'dummy.xml',
|
||||||
|
output: 'dummy-protocol.c',
|
||||||
|
command: [
|
||||||
|
wayland_scanner,
|
||||||
|
'private-code',
|
||||||
|
'@INPUT@', '@OUTPUT@',
|
||||||
|
]
|
||||||
|
)
|
||||||
|
@ -29,8 +29,13 @@
|
|||||||
#include "tests/meta-test-utils.h"
|
#include "tests/meta-test-utils.h"
|
||||||
#include "tests/meta-wayland-test-driver.h"
|
#include "tests/meta-wayland-test-driver.h"
|
||||||
#include "tests/meta-wayland-test-utils.h"
|
#include "tests/meta-wayland-test-utils.h"
|
||||||
|
#include "wayland/meta-wayland-client-private.h"
|
||||||
|
#include "wayland/meta-wayland-filter-manager.h"
|
||||||
#include "wayland/meta-wayland-surface.h"
|
#include "wayland/meta-wayland-surface.h"
|
||||||
|
|
||||||
|
#include "dummy-client-protocol.h"
|
||||||
|
#include "dummy-server-protocol.h"
|
||||||
|
|
||||||
static MetaContext *test_context;
|
static MetaContext *test_context;
|
||||||
static MetaWaylandTestDriver *test_driver;
|
static MetaWaylandTestDriver *test_driver;
|
||||||
static MetaVirtualMonitor *virtual_monitor;
|
static MetaVirtualMonitor *virtual_monitor;
|
||||||
@ -677,6 +682,176 @@ xdg_foreign_set_parent_of (void)
|
|||||||
meta_wayland_test_client_finish (wayland_test_client);
|
meta_wayland_test_client_finish (wayland_test_client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaWaylandAccess
|
||||||
|
dummy_global_filter (const struct wl_client *client,
|
||||||
|
const struct wl_global *global,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandClient *allowed_client = META_WAYLAND_CLIENT (user_data);
|
||||||
|
|
||||||
|
if (g_object_get_data (G_OBJECT (allowed_client),
|
||||||
|
"test-client-destroyed"))
|
||||||
|
return META_WAYLAND_ACCESS_DENIED;
|
||||||
|
else if (meta_wayland_client_matches (allowed_client, client))
|
||||||
|
return META_WAYLAND_ACCESS_ALLOWED;
|
||||||
|
else
|
||||||
|
return META_WAYLAND_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dummy_bind (struct wl_client *client,
|
||||||
|
void *data,
|
||||||
|
uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
|
||||||
|
{
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_registry_global (void *user_data,
|
||||||
|
struct wl_registry *registry,
|
||||||
|
uint32_t id,
|
||||||
|
const char *interface,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
gboolean *global_seen = user_data;
|
||||||
|
|
||||||
|
if (strcmp (interface, dummy_interface.name) == 0)
|
||||||
|
*global_seen = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
handle_registry_global_remove (void *user_data,
|
||||||
|
struct wl_registry *registry,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
handle_registry_global,
|
||||||
|
handle_registry_global_remove
|
||||||
|
};
|
||||||
|
|
||||||
|
static gpointer
|
||||||
|
test_client_thread_func (gpointer user_data)
|
||||||
|
{
|
||||||
|
int fd = GPOINTER_TO_INT (user_data);
|
||||||
|
struct wl_display *wl_display;
|
||||||
|
struct wl_registry *wl_registry;
|
||||||
|
gboolean global_seen = FALSE;
|
||||||
|
|
||||||
|
wl_display = wl_display_connect_to_fd (fd);
|
||||||
|
g_assert_nonnull (wl_display);
|
||||||
|
|
||||||
|
wl_registry = wl_display_get_registry (wl_display);
|
||||||
|
wl_registry_add_listener (wl_registry, ®istry_listener, &global_seen);
|
||||||
|
wl_display_roundtrip (wl_display);
|
||||||
|
wl_registry_destroy (wl_registry);
|
||||||
|
|
||||||
|
wl_display_disconnect (wl_display);
|
||||||
|
|
||||||
|
return GINT_TO_POINTER (global_seen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_client_destroyed (MetaWaylandClient *client,
|
||||||
|
gboolean *client_destroyed)
|
||||||
|
{
|
||||||
|
*client_destroyed = TRUE;
|
||||||
|
g_object_set_data (G_OBJECT (client), "test-client-destroyed",
|
||||||
|
GINT_TO_POINTER (TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wayland_registry_filter (void)
|
||||||
|
{
|
||||||
|
g_autoptr (GError) error = NULL;
|
||||||
|
MetaWaylandCompositor *wayland_compositor =
|
||||||
|
meta_context_get_wayland_compositor (test_context);
|
||||||
|
MetaWaylandFilterManager *filter_manager =
|
||||||
|
meta_wayland_compositor_get_filter_manager (wayland_compositor);
|
||||||
|
struct wl_display *wayland_display =
|
||||||
|
meta_wayland_compositor_get_wayland_display (wayland_compositor);
|
||||||
|
struct wl_global *dummy_global;
|
||||||
|
int fd;
|
||||||
|
g_autoptr (MetaWaylandClient) client1 = NULL;
|
||||||
|
g_autoptr (MetaWaylandClient) client2 = NULL;
|
||||||
|
g_autoptr (MetaWaylandClient) client3 = NULL;
|
||||||
|
g_autoptr (GThread) thread1 = NULL;
|
||||||
|
g_autoptr (GThread) thread2 = NULL;
|
||||||
|
g_autoptr (GThread) thread3 = NULL;
|
||||||
|
gboolean client1_destroyed = FALSE;
|
||||||
|
gboolean client2_destroyed = FALSE;
|
||||||
|
gboolean client3_destroyed = FALSE;
|
||||||
|
gboolean client1_saw_global;
|
||||||
|
gboolean client2_saw_global;
|
||||||
|
gboolean client3_saw_global;
|
||||||
|
|
||||||
|
client1 = meta_wayland_client_new_indirect (test_context, &error);
|
||||||
|
g_assert_nonnull (client1);
|
||||||
|
g_assert_null (error);
|
||||||
|
client2 = meta_wayland_client_new_indirect (test_context, &error);
|
||||||
|
g_assert_nonnull (client2);
|
||||||
|
g_assert_null (error);
|
||||||
|
client3 = meta_wayland_client_new_indirect (test_context, &error);
|
||||||
|
g_assert_nonnull (client3);
|
||||||
|
g_assert_null (error);
|
||||||
|
|
||||||
|
g_signal_connect (client1, "client-destroyed",
|
||||||
|
G_CALLBACK (on_client_destroyed), &client1_destroyed);
|
||||||
|
g_signal_connect (client2, "client-destroyed",
|
||||||
|
G_CALLBACK (on_client_destroyed), &client2_destroyed);
|
||||||
|
g_signal_connect (client3, "client-destroyed",
|
||||||
|
G_CALLBACK (on_client_destroyed), &client3_destroyed);
|
||||||
|
|
||||||
|
dummy_global = wl_global_create (wayland_display,
|
||||||
|
&dummy_interface,
|
||||||
|
1, NULL, dummy_bind);
|
||||||
|
meta_wayland_filter_manager_add_global (filter_manager,
|
||||||
|
dummy_global,
|
||||||
|
dummy_global_filter,
|
||||||
|
client1);
|
||||||
|
|
||||||
|
fd = meta_wayland_client_setup_fd (client1, &error);
|
||||||
|
g_assert_cmpint (fd, >=, 0);
|
||||||
|
g_assert_null (error);
|
||||||
|
thread1 = g_thread_new ("test client thread 1",
|
||||||
|
test_client_thread_func,
|
||||||
|
GINT_TO_POINTER (fd));
|
||||||
|
|
||||||
|
fd = meta_wayland_client_setup_fd (client2, &error);
|
||||||
|
g_assert_cmpint (fd, >=, 0);
|
||||||
|
g_assert_null (error);
|
||||||
|
thread2 = g_thread_new ("test client thread 2",
|
||||||
|
test_client_thread_func,
|
||||||
|
GINT_TO_POINTER (fd));
|
||||||
|
|
||||||
|
while (!client1_destroyed || !client2_destroyed)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|
||||||
|
client1_saw_global = GPOINTER_TO_INT (g_thread_join (thread1));
|
||||||
|
client2_saw_global = GPOINTER_TO_INT (g_thread_join (thread2));
|
||||||
|
|
||||||
|
g_assert_true (client1_saw_global);
|
||||||
|
g_assert_false (client2_saw_global);
|
||||||
|
|
||||||
|
meta_wayland_filter_manager_remove_global (filter_manager, dummy_global);
|
||||||
|
wl_global_destroy (dummy_global);
|
||||||
|
|
||||||
|
fd = meta_wayland_client_setup_fd (client3, &error);
|
||||||
|
g_assert_cmpint (fd, >=, 0);
|
||||||
|
g_assert_null (error);
|
||||||
|
thread3 = g_thread_new ("test client thread 3",
|
||||||
|
test_client_thread_func,
|
||||||
|
GINT_TO_POINTER (fd));
|
||||||
|
while (!client3_destroyed)
|
||||||
|
g_main_context_iteration (NULL, TRUE);
|
||||||
|
|
||||||
|
client3_saw_global = GPOINTER_TO_INT (g_thread_join (thread3));
|
||||||
|
g_assert_false (client3_saw_global);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_before_tests (void)
|
on_before_tests (void)
|
||||||
{
|
{
|
||||||
@ -722,6 +897,8 @@ init_tests (void)
|
|||||||
toplevel_bounds_monitors);
|
toplevel_bounds_monitors);
|
||||||
g_test_add_func ("/wayland/xdg-foreign/set-parent-of",
|
g_test_add_func ("/wayland/xdg-foreign/set-parent-of",
|
||||||
xdg_foreign_set_parent_of);
|
xdg_foreign_set_parent_of);
|
||||||
|
g_test_add_func ("/wayland/registry/filter",
|
||||||
|
wayland_registry_filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
104
src/wayland/meta-wayland-filter-manager.c
Normal file
104
src/wayland/meta-wayland-filter-manager.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "meta-wayland-filter-manager.h"
|
||||||
|
|
||||||
|
#include "meta-wayland.h"
|
||||||
|
|
||||||
|
struct _MetaWaylandFilterManager
|
||||||
|
{
|
||||||
|
GHashTable *filters;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandFilter
|
||||||
|
{
|
||||||
|
MetaWaylandFilterFunc func;
|
||||||
|
gpointer user_data;
|
||||||
|
} MetaWaylandFilter;
|
||||||
|
|
||||||
|
static bool
|
||||||
|
global_filter_func (const struct wl_client *client,
|
||||||
|
const struct wl_global *global,
|
||||||
|
void *user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandFilterManager *filter_manager = user_data;
|
||||||
|
MetaWaylandFilter *filter;
|
||||||
|
|
||||||
|
filter = g_hash_table_lookup (filter_manager->filters, global);
|
||||||
|
if (!filter)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
switch (filter->func (client, global, filter->user_data))
|
||||||
|
{
|
||||||
|
case META_WAYLAND_ACCESS_ALLOWED:
|
||||||
|
return true;
|
||||||
|
case META_WAYLAND_ACCESS_DENIED:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_assert_not_reached ();
|
||||||
|
}
|
||||||
|
|
||||||
|
MetaWaylandFilterManager *
|
||||||
|
meta_wayland_filter_manager_new (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
struct wl_display *wayland_display =
|
||||||
|
meta_wayland_compositor_get_wayland_display (compositor);
|
||||||
|
MetaWaylandFilterManager *filter_manager;
|
||||||
|
|
||||||
|
filter_manager = g_new0 (MetaWaylandFilterManager, 1);
|
||||||
|
filter_manager->filters = g_hash_table_new_full (NULL, NULL, NULL, g_free);
|
||||||
|
wl_display_set_global_filter (wayland_display,
|
||||||
|
global_filter_func, filter_manager);
|
||||||
|
|
||||||
|
return filter_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_filter_manager_free (MetaWaylandFilterManager *filter_manager)
|
||||||
|
{
|
||||||
|
g_hash_table_unref (filter_manager->filters);
|
||||||
|
g_free (filter_manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_filter_manager_add_global (MetaWaylandFilterManager *filter_manager,
|
||||||
|
struct wl_global *global,
|
||||||
|
MetaWaylandFilterFunc filter_func,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandFilter *filter;
|
||||||
|
|
||||||
|
g_return_if_fail (!g_hash_table_lookup (filter_manager->filters, global));
|
||||||
|
|
||||||
|
filter = g_new0 (MetaWaylandFilter, 1);
|
||||||
|
filter->func = filter_func;
|
||||||
|
filter->user_data = user_data;
|
||||||
|
|
||||||
|
g_hash_table_insert (filter_manager->filters, global, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_wayland_filter_manager_remove_global (MetaWaylandFilterManager *filter_manager,
|
||||||
|
struct wl_global *global)
|
||||||
|
{
|
||||||
|
g_hash_table_remove (filter_manager->filters, global);
|
||||||
|
}
|
56
src/wayland/meta-wayland-filter-manager.h
Normal file
56
src/wayland/meta-wayland-filter-manager.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 Red Hat
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
* 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef META_WAYLAND_FILTER_MANAGER_H
|
||||||
|
#define META_WAYLAND_FILTER_MANAGER_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <wayland-server-core.h>
|
||||||
|
|
||||||
|
#include "core/util-private.h"
|
||||||
|
#include "wayland/meta-wayland-types.h"
|
||||||
|
|
||||||
|
typedef enum _MetaWaylandAccess
|
||||||
|
{
|
||||||
|
META_WAYLAND_ACCESS_ALLOWED,
|
||||||
|
META_WAYLAND_ACCESS_DENIED,
|
||||||
|
} MetaWaylandAccess;
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandFilterManager MetaWaylandFilterManager;
|
||||||
|
|
||||||
|
typedef MetaWaylandAccess (* MetaWaylandFilterFunc) (const struct wl_client *client,
|
||||||
|
const struct wl_global *global,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
MetaWaylandFilterManager * meta_wayland_filter_manager_new (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
void meta_wayland_filter_manager_free (MetaWaylandFilterManager *filter_manager);
|
||||||
|
|
||||||
|
META_EXPORT_TEST
|
||||||
|
void meta_wayland_filter_manager_add_global (MetaWaylandFilterManager *filter_manager,
|
||||||
|
struct wl_global *global,
|
||||||
|
MetaWaylandFilterFunc filter_func,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
|
||||||
|
META_EXPORT_TEST
|
||||||
|
void meta_wayland_filter_manager_remove_global (MetaWaylandFilterManager *filter_manager,
|
||||||
|
struct wl_global *global);
|
||||||
|
|
||||||
|
#endif /* META_WAYLAND_FILTER_MANAGER_H */
|
@ -73,4 +73,6 @@ typedef struct _MetaXWaylandManager MetaXWaylandManager;
|
|||||||
|
|
||||||
typedef struct _MetaWaylandXdgForeign MetaWaylandXdgForeign;
|
typedef struct _MetaWaylandXdgForeign MetaWaylandXdgForeign;
|
||||||
|
|
||||||
|
typedef struct _MetaWaylandFilterManager MetaWaylandFilterManager;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
#include "wayland/meta-wayland-data-device.h"
|
#include "wayland/meta-wayland-data-device.h"
|
||||||
#include "wayland/meta-wayland-dma-buf.h"
|
#include "wayland/meta-wayland-dma-buf.h"
|
||||||
#include "wayland/meta-wayland-egl-stream.h"
|
#include "wayland/meta-wayland-egl-stream.h"
|
||||||
|
#include "wayland/meta-wayland-filter-manager.h"
|
||||||
#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h"
|
#include "wayland/meta-wayland-inhibit-shortcuts-dialog.h"
|
||||||
#include "wayland/meta-wayland-inhibit-shortcuts.h"
|
#include "wayland/meta-wayland-inhibit-shortcuts.h"
|
||||||
#include "wayland/meta-wayland-legacy-xdg-foreign.h"
|
#include "wayland/meta-wayland-legacy-xdg-foreign.h"
|
||||||
@ -75,6 +76,8 @@ static char *_display_name_override;
|
|||||||
typedef struct _MetaWaylandCompositorPrivate
|
typedef struct _MetaWaylandCompositorPrivate
|
||||||
{
|
{
|
||||||
gboolean is_wayland_egl_display_bound;
|
gboolean is_wayland_egl_display_bound;
|
||||||
|
|
||||||
|
MetaWaylandFilterManager *filter_manager;
|
||||||
} MetaWaylandCompositorPrivate;
|
} MetaWaylandCompositorPrivate;
|
||||||
|
|
||||||
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandCompositor, meta_wayland_compositor,
|
G_DEFINE_TYPE_WITH_PRIVATE (MetaWaylandCompositor, meta_wayland_compositor,
|
||||||
@ -451,6 +454,8 @@ static void
|
|||||||
meta_wayland_compositor_finalize (GObject *object)
|
meta_wayland_compositor_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
MetaWaylandCompositor *compositor = META_WAYLAND_COMPOSITOR (object);
|
MetaWaylandCompositor *compositor = META_WAYLAND_COMPOSITOR (object);
|
||||||
|
MetaWaylandCompositorPrivate *priv =
|
||||||
|
meta_wayland_compositor_get_instance_private (compositor);
|
||||||
MetaBackend *backend = meta_context_get_backend (compositor->context);
|
MetaBackend *backend = meta_context_get_backend (compositor->context);
|
||||||
ClutterActor *stage = meta_backend_get_stage (backend);
|
ClutterActor *stage = meta_backend_get_stage (backend);
|
||||||
|
|
||||||
@ -470,6 +475,8 @@ meta_wayland_compositor_finalize (GObject *object)
|
|||||||
|
|
||||||
g_clear_pointer (&compositor->seat, meta_wayland_seat_free);
|
g_clear_pointer (&compositor->seat, meta_wayland_seat_free);
|
||||||
|
|
||||||
|
g_clear_pointer (&priv->filter_manager, meta_wayland_filter_manager_free);
|
||||||
|
|
||||||
g_clear_pointer (&compositor->display_name, g_free);
|
g_clear_pointer (&compositor->display_name, g_free);
|
||||||
g_clear_pointer (&compositor->wayland_display, wl_display_destroy);
|
g_clear_pointer (&compositor->wayland_display, wl_display_destroy);
|
||||||
g_clear_pointer (&compositor->source, g_source_destroy);
|
g_clear_pointer (&compositor->source, g_source_destroy);
|
||||||
@ -480,6 +487,9 @@ meta_wayland_compositor_finalize (GObject *object)
|
|||||||
static void
|
static void
|
||||||
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
||||||
{
|
{
|
||||||
|
MetaWaylandCompositorPrivate *priv =
|
||||||
|
meta_wayland_compositor_get_instance_private (compositor);
|
||||||
|
|
||||||
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
|
compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
|
||||||
|
|
||||||
wl_log_set_handler_server (meta_wayland_log_func);
|
wl_log_set_handler_server (meta_wayland_log_func);
|
||||||
@ -487,6 +497,8 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
|
|||||||
compositor->wayland_display = wl_display_create ();
|
compositor->wayland_display = wl_display_create ();
|
||||||
if (compositor->wayland_display == NULL)
|
if (compositor->wayland_display == NULL)
|
||||||
g_error ("Failed to create the global wl_display");
|
g_error ("Failed to create the global wl_display");
|
||||||
|
|
||||||
|
priv->filter_manager = meta_wayland_filter_manager_new (compositor);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -861,3 +873,12 @@ meta_wayland_compositor_get_wayland_display (MetaWaylandCompositor *compositor)
|
|||||||
{
|
{
|
||||||
return compositor->wayland_display;
|
return compositor->wayland_display;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MetaWaylandFilterManager *
|
||||||
|
meta_wayland_compositor_get_filter_manager (MetaWaylandCompositor *compositor)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositorPrivate *priv =
|
||||||
|
meta_wayland_compositor_get_instance_private (compositor);
|
||||||
|
|
||||||
|
return priv->filter_manager;
|
||||||
|
}
|
||||||
|
@ -102,8 +102,12 @@ MetaXWaylandManager * meta_wayland_compositor_get_xwayland_manager (MetaWaylan
|
|||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
MetaContext * meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor);
|
MetaContext * meta_wayland_compositor_get_context (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
META_EXPORT_TEST
|
||||||
struct wl_display * meta_wayland_compositor_get_wayland_display (MetaWaylandCompositor *compositor);
|
struct wl_display * meta_wayland_compositor_get_wayland_display (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
gboolean meta_wayland_compositor_is_grabbed (MetaWaylandCompositor *compositor);
|
gboolean meta_wayland_compositor_is_grabbed (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
|
META_EXPORT_TEST
|
||||||
|
MetaWaylandFilterManager * meta_wayland_compositor_get_filter_manager (MetaWaylandCompositor *compositor);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include "meta/meta-backend.h"
|
#include "meta/meta-backend.h"
|
||||||
#include "backends/meta-settings-private.h"
|
#include "backends/meta-settings-private.h"
|
||||||
|
#include "wayland/meta-wayland-filter-manager.h"
|
||||||
#include "wayland/meta-wayland-private.h"
|
#include "wayland/meta-wayland-private.h"
|
||||||
#include "wayland/meta-wayland-versions.h"
|
#include "wayland/meta-wayland-versions.h"
|
||||||
#include "wayland/meta-wayland-seat.h"
|
#include "wayland/meta-wayland-seat.h"
|
||||||
@ -339,12 +340,37 @@ bind_keyboard_grab (struct wl_client *client,
|
|||||||
NULL, NULL);
|
NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaWaylandAccess
|
||||||
|
xwayland_grab_keyboard_filter (const struct wl_client *client,
|
||||||
|
const struct wl_global *global,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
MetaWaylandCompositor *compositor = user_data;
|
||||||
|
MetaXWaylandManager *xwayland_manager = &compositor->xwayland_manager;
|
||||||
|
|
||||||
|
if (client == xwayland_manager->client)
|
||||||
|
return META_WAYLAND_ACCESS_ALLOWED;
|
||||||
|
else
|
||||||
|
return META_WAYLAND_ACCESS_DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_xwayland_grab_keyboard_init (MetaWaylandCompositor *compositor)
|
meta_xwayland_grab_keyboard_init (MetaWaylandCompositor *compositor)
|
||||||
{
|
{
|
||||||
return (wl_global_create (compositor->wayland_display,
|
struct wl_global *global;
|
||||||
&zwp_xwayland_keyboard_grab_manager_v1_interface,
|
MetaWaylandFilterManager *filter_manager;
|
||||||
META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION,
|
|
||||||
NULL,
|
global = wl_global_create (compositor->wayland_display,
|
||||||
bind_keyboard_grab) != NULL);
|
&zwp_xwayland_keyboard_grab_manager_v1_interface,
|
||||||
|
META_ZWP_XWAYLAND_KEYBOARD_GRAB_V1_VERSION,
|
||||||
|
NULL,
|
||||||
|
bind_keyboard_grab);
|
||||||
|
|
||||||
|
filter_manager = meta_wayland_compositor_get_filter_manager (compositor);
|
||||||
|
meta_wayland_filter_manager_add_global (filter_manager,
|
||||||
|
global,
|
||||||
|
xwayland_grab_keyboard_filter,
|
||||||
|
compositor);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -73,11 +73,6 @@ static void meta_xwayland_stop_xserver (MetaXWaylandManager *manager);
|
|||||||
static void
|
static void
|
||||||
meta_xwayland_set_primary_output (MetaX11Display *x11_display);
|
meta_xwayland_set_primary_output (MetaX11Display *x11_display);
|
||||||
|
|
||||||
static bool
|
|
||||||
meta_xwayland_global_filter (const struct wl_client *client,
|
|
||||||
const struct wl_global *global,
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
static MetaMonitorManager *
|
static MetaMonitorManager *
|
||||||
monitor_manager_from_x11_display (MetaX11Display *x11_display)
|
monitor_manager_from_x11_display (MetaX11Display *x11_display)
|
||||||
{
|
{
|
||||||
@ -1127,9 +1122,7 @@ meta_xwayland_init (MetaXWaylandManager *manager,
|
|||||||
|
|
||||||
/* Xwayland specific protocol, needs to be filtered out for all other clients */
|
/* Xwayland specific protocol, needs to be filtered out for all other clients */
|
||||||
meta_xwayland_grab_keyboard_init (compositor);
|
meta_xwayland_grab_keyboard_init (compositor);
|
||||||
wl_display_set_global_filter (compositor->wayland_display,
|
|
||||||
meta_xwayland_global_filter,
|
|
||||||
compositor);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1299,23 +1292,6 @@ meta_xwayland_manager_handle_xevent (MetaXWaylandManager *manager,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
meta_xwayland_global_filter (const struct wl_client *client,
|
|
||||||
const struct wl_global *global,
|
|
||||||
void *data)
|
|
||||||
{
|
|
||||||
MetaWaylandCompositor *compositor = (MetaWaylandCompositor *) data;
|
|
||||||
MetaXWaylandManager *xwayland_manager = &compositor->xwayland_manager;
|
|
||||||
|
|
||||||
/* Keyboard grabbing protocol is for Xwayland only */
|
|
||||||
if (client != xwayland_manager->client)
|
|
||||||
return (wl_global_get_interface (global) !=
|
|
||||||
&zwp_xwayland_keyboard_grab_manager_v1_interface);
|
|
||||||
|
|
||||||
/* All others are visible to all clients */
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
meta_xwayland_signal (MetaXWaylandManager *manager,
|
meta_xwayland_signal (MetaXWaylandManager *manager,
|
||||||
int signum,
|
int signum,
|
||||||
|
Loading…
Reference in New Issue
Block a user