mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-10-29 05:40:16 -04:00
wayland-server: Add API to control globals visibility
Add a new API to let compositor decide whether or not a wl_global should be advertised to the clients via wl_registry_bind() or display_get_registry() By using its own filter, the compositor can decide which wl_global would be listed to clients. Compositors can use this mechanism to hide their own private interfaces that regular clients should not use. - Hiding interfaces that expose compositor implementation details makes it harder for clients to identify the compositor. Therefore clients are a little less likely to develop compositor-specific workarounds instead of reporting problems upstream. - Hiding can be used to diminish the problems from missing namespacing: if two compositors happen to use the same named global with different interfaces for their special-purpose clients, the client expecting the different interface would probably never see it advertised. Signed-off-by: Olivier Fourdan <ofourdan@redhat.com> Reviewed-by: Jonas Ådahl <jadahl@gmail.com> Reviewed-by: Yong Bakos <ybakos@humanoriented.com> Acked-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk> Reviewed-by: Pekka Paalanen <pekka.paalanen@collabora.co.uk>
This commit is contained in:
parent
2f72d0a8a8
commit
d915447365
2 changed files with 87 additions and 5 deletions
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include "wayland-util.h"
|
#include "wayland-util.h"
|
||||||
#include "wayland-version.h"
|
#include "wayland-version.h"
|
||||||
|
|
||||||
|
|
@ -168,6 +169,30 @@ wl_global_create(struct wl_display *display,
|
||||||
void
|
void
|
||||||
wl_global_destroy(struct wl_global *global);
|
wl_global_destroy(struct wl_global *global);
|
||||||
|
|
||||||
|
/** A filter function for wl_global objects
|
||||||
|
*
|
||||||
|
* \param client The client object
|
||||||
|
* \param global The global object to show or hide
|
||||||
|
* \param data The user data pointer
|
||||||
|
*
|
||||||
|
* A filter function enables the server to decide which globals to
|
||||||
|
* advertise to each client.
|
||||||
|
*
|
||||||
|
* When a wl_global filter is set, the given callback funtion will be
|
||||||
|
* called during wl_global advertisment and binding.
|
||||||
|
*
|
||||||
|
* This function should return true if the global object should be made
|
||||||
|
* visible to the client or false otherwise.
|
||||||
|
*/
|
||||||
|
typedef bool (*wl_display_global_filter_func_t)(const struct wl_client *client,
|
||||||
|
const struct wl_global *global,
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_display_set_global_filter(struct wl_display *display,
|
||||||
|
wl_display_global_filter_func_t filter,
|
||||||
|
void *data);
|
||||||
|
|
||||||
struct wl_client *
|
struct wl_client *
|
||||||
wl_client_create(struct wl_display *display, int fd);
|
wl_client_create(struct wl_display *display, int fd);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,9 @@ struct wl_display {
|
||||||
struct wl_signal create_client_signal;
|
struct wl_signal create_client_signal;
|
||||||
|
|
||||||
struct wl_array additional_shm_formats;
|
struct wl_array additional_shm_formats;
|
||||||
|
|
||||||
|
wl_display_global_filter_func_t global_filter;
|
||||||
|
void *global_filter_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_global {
|
struct wl_global {
|
||||||
|
|
@ -769,6 +772,21 @@ wl_client_destroy(struct wl_client *client)
|
||||||
free(client);
|
free(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if a global filter is registered and use it if any.
|
||||||
|
*
|
||||||
|
* If no wl_global filter has been registered, this funtion will
|
||||||
|
* return true, allowing the wl_global to be visible to the wl_client
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
wl_global_is_visible(const struct wl_client *client,
|
||||||
|
const struct wl_global *global)
|
||||||
|
{
|
||||||
|
struct wl_display *display = client->display;
|
||||||
|
|
||||||
|
return (display->global_filter == NULL ||
|
||||||
|
display->global_filter(client, global, display->global_filter_data));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
registry_bind(struct wl_client *client,
|
registry_bind(struct wl_client *client,
|
||||||
struct wl_resource *resource, uint32_t name,
|
struct wl_resource *resource, uint32_t name,
|
||||||
|
|
@ -795,6 +813,10 @@ registry_bind(struct wl_client *client,
|
||||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||||
"invalid version for global %s (%d): have %d, wanted %d",
|
"invalid version for global %s (%d): have %d, wanted %d",
|
||||||
interface, name, global->version, version);
|
interface, name, global->version, version);
|
||||||
|
else if (!wl_global_is_visible(client, global))
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||||
|
"invalid global %s (%d)", interface, name);
|
||||||
else
|
else
|
||||||
global->bind(client, global->data, version, id);
|
global->bind(client, global->data, version, id);
|
||||||
}
|
}
|
||||||
|
|
@ -850,11 +872,12 @@ display_get_registry(struct wl_client *client,
|
||||||
®istry_resource->link);
|
®istry_resource->link);
|
||||||
|
|
||||||
wl_list_for_each(global, &display->global_list, link)
|
wl_list_for_each(global, &display->global_list, link)
|
||||||
wl_resource_post_event(registry_resource,
|
if (wl_global_is_visible(client, global))
|
||||||
WL_REGISTRY_GLOBAL,
|
wl_resource_post_event(registry_resource,
|
||||||
global->name,
|
WL_REGISTRY_GLOBAL,
|
||||||
global->interface->name,
|
global->name,
|
||||||
global->version);
|
global->interface->name,
|
||||||
|
global->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_display_interface display_interface = {
|
static const struct wl_display_interface display_interface = {
|
||||||
|
|
@ -925,6 +948,9 @@ wl_display_create(void)
|
||||||
display->id = 1;
|
display->id = 1;
|
||||||
display->serial = 0;
|
display->serial = 0;
|
||||||
|
|
||||||
|
display->global_filter = NULL;
|
||||||
|
display->global_filter_data = NULL;
|
||||||
|
|
||||||
wl_array_init(&display->additional_shm_formats);
|
wl_array_init(&display->additional_shm_formats);
|
||||||
|
|
||||||
return display;
|
return display;
|
||||||
|
|
@ -999,6 +1025,37 @@ wl_display_destroy(struct wl_display *display)
|
||||||
free(display);
|
free(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Set a filter function for global objects
|
||||||
|
*
|
||||||
|
* \param display The Wayland display object.
|
||||||
|
* \param filter The global filter funtion.
|
||||||
|
* \param data User data to be associated with the global filter.
|
||||||
|
* \return None.
|
||||||
|
*
|
||||||
|
* Set a filter for the wl_display to advertise or hide global objects
|
||||||
|
* to clients.
|
||||||
|
* The set filter will be used during wl_global advertisment to
|
||||||
|
* determine whether a global object should be advertised to a
|
||||||
|
* given client, and during wl_global binding to determine whether
|
||||||
|
* a given client should be allowed to bind to a global.
|
||||||
|
*
|
||||||
|
* Clients that try to bind to a global that was filtered out will
|
||||||
|
* have an error raised.
|
||||||
|
*
|
||||||
|
* Setting the filter NULL will result in all globals being
|
||||||
|
* advertised to all clients. The default is no filter.
|
||||||
|
*
|
||||||
|
* \memberof wl_display
|
||||||
|
*/
|
||||||
|
WL_EXPORT void
|
||||||
|
wl_display_set_global_filter(struct wl_display *display,
|
||||||
|
wl_display_global_filter_func_t filter,
|
||||||
|
void *data)
|
||||||
|
{
|
||||||
|
display->global_filter = filter;
|
||||||
|
display->global_filter_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
WL_EXPORT struct wl_global *
|
WL_EXPORT struct wl_global *
|
||||||
wl_global_create(struct wl_display *display,
|
wl_global_create(struct wl_display *display,
|
||||||
const struct wl_interface *interface, int version,
|
const struct wl_interface *interface, int version,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue