mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-05-03 06:46:33 -04:00
Merge branch 'jorth/wl-upgrade' into 'main'
Draft: Implement transparent wire format upgrade See merge request wayland/wayland!492
This commit is contained in:
commit
e9a00ec4ad
5 changed files with 228 additions and 31 deletions
|
|
@ -1220,6 +1220,118 @@ connect_to_socket(const char *name)
|
|||
return fd;
|
||||
}
|
||||
|
||||
struct upgrade_data {
|
||||
struct wl_fixes **fixes;
|
||||
struct wl_upgrade **upgrade;
|
||||
bool *upgraded;
|
||||
};
|
||||
|
||||
static void upgrade_global(void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name,
|
||||
const char *interface,
|
||||
uint32_t version)
|
||||
{
|
||||
struct upgrade_data *upgrade = data;
|
||||
if (strcmp(interface, "wl_fixes") == 0) {
|
||||
*upgrade->fixes = wl_registry_bind(wl_registry, name, &wl_fixes_interface, 1);
|
||||
} else if (strcmp(interface, "wl_upgrade") == 0) {
|
||||
*upgrade->upgrade = wl_registry_bind(wl_registry, name, &wl_upgrade_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void upgrade_global_removed(void *data,
|
||||
struct wl_registry *wl_registry,
|
||||
uint32_t name)
|
||||
{
|
||||
// nothing
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener upgrade_registry_listener = {
|
||||
.global = upgrade_global,
|
||||
.global_remove = upgrade_global_removed,
|
||||
};
|
||||
|
||||
static void upgrade_upgraded(void *data,
|
||||
struct wl_upgrade *wl_upgrade)
|
||||
{
|
||||
struct upgrade_data *upgrade = data;
|
||||
*upgrade->upgraded = true;
|
||||
}
|
||||
|
||||
static const struct wl_upgrade_listener upgrade_upgrade_listener = {
|
||||
.upgraded = upgrade_upgraded,
|
||||
};
|
||||
|
||||
static void
|
||||
try_upgrade(struct wl_display *display)
|
||||
{
|
||||
struct wl_event_queue *queue = NULL;
|
||||
struct wl_display *display_wrapper = NULL;
|
||||
struct wl_registry *registry = NULL;
|
||||
struct wl_fixes *fixes = NULL;
|
||||
struct wl_upgrade *upgrade = NULL;
|
||||
bool upgraded = false;
|
||||
struct upgrade_data data = {
|
||||
.fixes = &fixes,
|
||||
.upgrade = &upgrade,
|
||||
.upgraded = &upgraded,
|
||||
};
|
||||
|
||||
queue = wl_display_create_queue_with_name(display, "Upgrade Queue");
|
||||
if (!queue) {
|
||||
goto out;
|
||||
}
|
||||
display_wrapper = wl_proxy_create_wrapper(display);
|
||||
if (!display_wrapper) {
|
||||
goto out;
|
||||
}
|
||||
wl_proxy_set_queue((struct wl_proxy *)display_wrapper, queue);
|
||||
registry = wl_display_get_registry(display_wrapper);
|
||||
if (!registry) {
|
||||
goto out;
|
||||
}
|
||||
wl_registry_add_listener(registry, &upgrade_registry_listener, &data);
|
||||
wl_display_roundtrip_queue(display, queue);
|
||||
if (!upgrade) {
|
||||
goto out;
|
||||
}
|
||||
assert(fixes);
|
||||
wl_fixes_destroy_registry(fixes, registry);
|
||||
wl_registry_destroy(registry);
|
||||
registry = NULL;
|
||||
wl_fixes_destroy(fixes);
|
||||
fixes = NULL;
|
||||
wl_upgrade_add_listener(upgrade, &upgrade_upgrade_listener, &data);
|
||||
wl_upgrade_upgrade(upgrade);
|
||||
while (!upgraded) {
|
||||
if (wl_display_dispatch_queue(display, queue) == -1) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
wl_connection_enable_v2(display->connection);
|
||||
|
||||
out:
|
||||
if (upgrade) {
|
||||
wl_upgrade_destroy(upgrade);
|
||||
}
|
||||
if (registry) {
|
||||
if (fixes) {
|
||||
wl_fixes_destroy_registry(fixes, registry);
|
||||
}
|
||||
wl_registry_destroy(registry);
|
||||
}
|
||||
if (fixes) {
|
||||
wl_fixes_destroy(fixes);
|
||||
}
|
||||
if (display_wrapper) {
|
||||
wl_proxy_wrapper_destroy(display_wrapper);
|
||||
}
|
||||
if (queue) {
|
||||
wl_event_queue_release(queue);
|
||||
}
|
||||
}
|
||||
|
||||
/** Connect to Wayland display on an already open fd
|
||||
*
|
||||
* \param fd The fd to use for the connection
|
||||
|
|
@ -1308,6 +1420,8 @@ wl_display_connect_to_fd(int fd)
|
|||
if (display->connection == NULL)
|
||||
goto err_connection;
|
||||
|
||||
try_upgrade(display);
|
||||
|
||||
return display;
|
||||
|
||||
err_connection:
|
||||
|
|
@ -1570,7 +1684,7 @@ increase_closure_args_refcount(struct wl_closure *closure)
|
|||
static int
|
||||
queue_event(struct wl_display *display, int len)
|
||||
{
|
||||
uint32_t p[2], id;
|
||||
uint32_t p[WL_MAX_HEADER_U32], id;
|
||||
int opcode, size;
|
||||
struct wl_proxy *proxy;
|
||||
struct wl_closure *closure;
|
||||
|
|
@ -1580,10 +1694,8 @@ queue_event(struct wl_display *display, int len)
|
|||
unsigned int time;
|
||||
int num_zombie_fds;
|
||||
|
||||
wl_connection_copy(display->connection, p, sizeof p);
|
||||
id = p[0];
|
||||
opcode = p[1] & 0xffff;
|
||||
size = p[1] >> 16;
|
||||
wl_connection_copy(display->connection, p, wl_connection_header_size(display->connection));
|
||||
wl_connection_parse_header(display->connection, p, &id, &size, &opcode, &num_zombie_fds);
|
||||
|
||||
/*
|
||||
* If the message is larger than the maximum size of the
|
||||
|
|
@ -1742,6 +1854,7 @@ read_events(struct wl_display *display)
|
|||
{
|
||||
int total, rem, size;
|
||||
uint32_t serial;
|
||||
int header_size = wl_connection_header_size(display->connection);
|
||||
|
||||
display->reader_count--;
|
||||
if (display->reader_count == 0) {
|
||||
|
|
@ -1766,7 +1879,7 @@ read_events(struct wl_display *display)
|
|||
return -1;
|
||||
}
|
||||
|
||||
for (rem = total; rem >= 8; rem -= size) {
|
||||
for (rem = total; rem >= header_size; rem -= size) {
|
||||
size = queue_event(display, rem);
|
||||
if (size == -1) {
|
||||
display_fatal_error(display, errno);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue