mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2025-11-04 13:29:51 -05:00
wayland-server: Add wl_global_create/destroy()
This patch introduces wl_global_create() and wl_global_destroy() as replacements for wl_display_add_global() and wl_display_remove_global(). The add/remove_global API did not allow a compositor to indicate the implemented version of a global, it just took the version from the interface meta data. The problem is that the meta data (which lives in libwayland-server.so) can get out of sync with a compositor implementation. The compositor will then advertise a higher version of a global than what it actually implements. The new API lets a compositor pass in a version when it registers a global, which solves the problem. The add/remove API is deprecated with this patch and will be removed.
This commit is contained in:
parent
40fc79d5b0
commit
4cffa0fd61
2 changed files with 60 additions and 17 deletions
|
|
@ -95,8 +95,10 @@ struct wl_display {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_global {
|
struct wl_global {
|
||||||
|
struct wl_display *display;
|
||||||
const struct wl_interface *interface;
|
const struct wl_interface *interface;
|
||||||
uint32_t name;
|
uint32_t name;
|
||||||
|
uint32_t version;
|
||||||
void *data;
|
void *data;
|
||||||
wl_global_bind_func_t bind;
|
wl_global_bind_func_t bind;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
|
@ -589,7 +591,8 @@ registry_bind(struct wl_client *client,
|
||||||
if (global->name == name)
|
if (global->name == name)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (&global->link == &display->global_list)
|
if (&global->link == &display->global_list ||
|
||||||
|
global->version < version)
|
||||||
wl_resource_post_error(resource,
|
wl_resource_post_error(resource,
|
||||||
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
WL_DISPLAY_ERROR_INVALID_OBJECT,
|
||||||
"invalid global %d", name);
|
"invalid global %d", name);
|
||||||
|
|
@ -652,7 +655,7 @@ display_get_registry(struct wl_client *client,
|
||||||
WL_REGISTRY_GLOBAL,
|
WL_REGISTRY_GLOBAL,
|
||||||
global->name,
|
global->name,
|
||||||
global->interface->name,
|
global->interface->name,
|
||||||
global->interface->version);
|
global->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct wl_display_interface display_interface = {
|
static const struct wl_display_interface display_interface = {
|
||||||
|
|
@ -714,7 +717,7 @@ wl_display_create(void)
|
||||||
display->id = 1;
|
display->id = 1;
|
||||||
display->serial = 0;
|
display->serial = 0;
|
||||||
|
|
||||||
if (!wl_display_add_global(display, &wl_display_interface,
|
if (!wl_global_create(display, &wl_display_interface, 1,
|
||||||
display, bind_display)) {
|
display, bind_display)) {
|
||||||
wl_event_loop_destroy(display->loop);
|
wl_event_loop_destroy(display->loop);
|
||||||
free(display);
|
free(display);
|
||||||
|
|
@ -749,19 +752,27 @@ wl_display_destroy(struct wl_display *display)
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT struct wl_global *
|
WL_EXPORT struct wl_global *
|
||||||
wl_display_add_global(struct wl_display *display,
|
wl_global_create(struct wl_display *display,
|
||||||
const struct wl_interface *interface,
|
const struct wl_interface *interface, int version,
|
||||||
void *data, wl_global_bind_func_t bind)
|
void *data, wl_global_bind_func_t bind)
|
||||||
{
|
{
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
|
|
||||||
|
if (interface->version < version) {
|
||||||
|
wl_log("wl_global_create: implemented version higher "
|
||||||
|
"than interface version%m\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
global = malloc(sizeof *global);
|
global = malloc(sizeof *global);
|
||||||
if (global == NULL)
|
if (global == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
global->display = display;
|
||||||
global->name = display->id++;
|
global->name = display->id++;
|
||||||
global->interface = interface;
|
global->interface = interface;
|
||||||
|
global->version = version;
|
||||||
global->data = data;
|
global->data = data;
|
||||||
global->bind = bind;
|
global->bind = bind;
|
||||||
wl_list_insert(display->global_list.prev, &global->link);
|
wl_list_insert(display->global_list.prev, &global->link);
|
||||||
|
|
@ -771,14 +782,15 @@ wl_display_add_global(struct wl_display *display,
|
||||||
WL_REGISTRY_GLOBAL,
|
WL_REGISTRY_GLOBAL,
|
||||||
global->name,
|
global->name,
|
||||||
global->interface->name,
|
global->interface->name,
|
||||||
global->interface->version);
|
global->version);
|
||||||
|
|
||||||
return global;
|
return global;
|
||||||
}
|
}
|
||||||
|
|
||||||
WL_EXPORT void
|
WL_EXPORT void
|
||||||
wl_display_remove_global(struct wl_display *display, struct wl_global *global)
|
wl_global_destroy(struct wl_global *global)
|
||||||
{
|
{
|
||||||
|
struct wl_display *display = global->display;
|
||||||
struct wl_resource *resource;
|
struct wl_resource *resource;
|
||||||
|
|
||||||
wl_list_for_each(resource, &display->registry_resource_list, link)
|
wl_list_for_each(resource, &display->registry_resource_list, link)
|
||||||
|
|
@ -1139,3 +1151,26 @@ wl_client_new_object(struct wl_client *client,
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct wl_global *
|
||||||
|
wl_display_add_global(struct wl_display *display,
|
||||||
|
const struct wl_interface *interface,
|
||||||
|
void *data, wl_global_bind_func_t bind) WL_DEPRECATED;
|
||||||
|
|
||||||
|
WL_EXPORT struct wl_global *
|
||||||
|
wl_display_add_global(struct wl_display *display,
|
||||||
|
const struct wl_interface *interface,
|
||||||
|
void *data, wl_global_bind_func_t bind)
|
||||||
|
{
|
||||||
|
return wl_global_create(display, interface, interface->version, data, bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_display_remove_global(struct wl_display *display,
|
||||||
|
struct wl_global *global) WL_DEPRECATED;
|
||||||
|
|
||||||
|
WL_EXPORT void
|
||||||
|
wl_display_remove_global(struct wl_display *display, struct wl_global *global)
|
||||||
|
{
|
||||||
|
wl_global_destroy(global);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -99,14 +99,6 @@ void wl_display_flush_clients(struct wl_display *display);
|
||||||
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
|
typedef void (*wl_global_bind_func_t)(struct wl_client *client, void *data,
|
||||||
uint32_t version, uint32_t id);
|
uint32_t version, uint32_t id);
|
||||||
|
|
||||||
struct wl_global *wl_display_add_global(struct wl_display *display,
|
|
||||||
const struct wl_interface *interface,
|
|
||||||
void *data,
|
|
||||||
wl_global_bind_func_t bind);
|
|
||||||
|
|
||||||
void wl_display_remove_global(struct wl_display *display,
|
|
||||||
struct wl_global *global);
|
|
||||||
|
|
||||||
uint32_t wl_display_get_serial(struct wl_display *display);
|
uint32_t wl_display_get_serial(struct wl_display *display);
|
||||||
uint32_t wl_display_next_serial(struct wl_display *display);
|
uint32_t wl_display_next_serial(struct wl_display *display);
|
||||||
|
|
||||||
|
|
@ -115,6 +107,12 @@ void wl_display_add_destroy_listener(struct wl_display *display,
|
||||||
struct wl_listener *wl_display_get_destroy_listener(struct wl_display *display,
|
struct wl_listener *wl_display_get_destroy_listener(struct wl_display *display,
|
||||||
wl_notify_func_t notify);
|
wl_notify_func_t notify);
|
||||||
|
|
||||||
|
struct wl_global *wl_global_create(struct wl_display *display,
|
||||||
|
const struct wl_interface *interface,
|
||||||
|
int version,
|
||||||
|
void *data, wl_global_bind_func_t bind);
|
||||||
|
void wl_global_destroy(struct wl_global *global);
|
||||||
|
|
||||||
struct wl_client *wl_client_create(struct wl_display *display, int fd);
|
struct wl_client *wl_client_create(struct wl_display *display, int fd);
|
||||||
void wl_client_destroy(struct wl_client *client);
|
void wl_client_destroy(struct wl_client *client);
|
||||||
void wl_client_flush(struct wl_client *client);
|
void wl_client_flush(struct wl_client *client);
|
||||||
|
|
@ -213,6 +211,16 @@ wl_client_new_object(struct wl_client *client,
|
||||||
const struct wl_interface *interface,
|
const struct wl_interface *interface,
|
||||||
const void *implementation, void *data) WL_DEPRECATED;
|
const void *implementation, void *data) WL_DEPRECATED;
|
||||||
|
|
||||||
|
struct wl_global *
|
||||||
|
wl_display_add_global(struct wl_display *display,
|
||||||
|
const struct wl_interface *interface,
|
||||||
|
void *data,
|
||||||
|
wl_global_bind_func_t bind) WL_DEPRECATED;
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_display_remove_global(struct wl_display *display,
|
||||||
|
struct wl_global *global) WL_DEPRECATED;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue