mirror of
https://gitlab.freedesktop.org/wayland/wayland.git
synced 2026-03-25 09:07:23 -04:00
Merge branch 'jorth/display-upgrade' into 'main'
protocol: add wl_display_upgrade global See merge request wayland/wayland!534
This commit is contained in:
commit
ccf3be1fc9
5 changed files with 218 additions and 4 deletions
|
|
@ -28,10 +28,14 @@
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
<interface name="wl_display" version="1">
|
<interface name="wl_display" version="2">
|
||||||
<description summary="core global object">
|
<description summary="core global object">
|
||||||
The core global object. This is a special singleton object. It
|
The core global object. This is a special singleton object. It
|
||||||
is used for internal Wayland protocol features.
|
is used for internal Wayland protocol features.
|
||||||
|
|
||||||
|
This interface guarantees that the semantics of requests of this interface
|
||||||
|
are unaffected by the minor version of this interface. The semantics of
|
||||||
|
events may change and new events may be added.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<request name="sync">
|
<request name="sync">
|
||||||
|
|
@ -110,7 +114,7 @@
|
||||||
</event>
|
</event>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_registry" version="1">
|
<interface name="wl_registry" version="2">
|
||||||
<description summary="global registry object">
|
<description summary="global registry object">
|
||||||
The singleton global registry object. The server has a number of
|
The singleton global registry object. The server has a number of
|
||||||
global objects that are available to all clients. These objects
|
global objects that are available to all clients. These objects
|
||||||
|
|
@ -132,6 +136,10 @@
|
||||||
request. This creates a client-side handle that lets the object
|
request. This creates a client-side handle that lets the object
|
||||||
emit events to the client and lets the client invoke requests on
|
emit events to the client and lets the client invoke requests on
|
||||||
the object.
|
the object.
|
||||||
|
|
||||||
|
This interface guarantees that the semantics of the messages of this
|
||||||
|
interface are unaffected by the minor version of this interface; and that
|
||||||
|
no new events will be added to any minor version of this interface.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<request name="bind">
|
<request name="bind">
|
||||||
|
|
@ -171,6 +179,14 @@
|
||||||
</description>
|
</description>
|
||||||
<arg name="name" type="uint" summary="numeric name of the global object"/>
|
<arg name="name" type="uint" summary="numeric name of the global object"/>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<!-- Version 2 additions -->
|
||||||
|
|
||||||
|
<request name="release" type="destructor" since="2">
|
||||||
|
<description summary="destroys this registry">
|
||||||
|
Objects created from this registry are not affected by this request.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
<interface name="wl_callback" version="1" frozen="true">
|
<interface name="wl_callback" version="1" frozen="true">
|
||||||
|
|
@ -3362,4 +3378,56 @@
|
||||||
</request>
|
</request>
|
||||||
</interface>
|
</interface>
|
||||||
|
|
||||||
|
<interface name="wl_display_upgrade" version="2">
|
||||||
|
<description summary="wayland upgrade object">
|
||||||
|
This global allows the IPC library to upgrade the version of the
|
||||||
|
wl_display object.
|
||||||
|
|
||||||
|
This global must not be bound more than once over the lifetime of the
|
||||||
|
connection, otherwise the already_bound error is emitted.
|
||||||
|
|
||||||
|
This global should only be bound by the IPC library because the IPC
|
||||||
|
library must be aware of the version of the wl_display object.
|
||||||
|
|
||||||
|
A compositor that advertises this global must also advertise the wl_fixes
|
||||||
|
global.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<description summary="wl_display_upgrade error values">
|
||||||
|
These errors can be emitted in response to wl_display_upgrade requests.
|
||||||
|
</description>
|
||||||
|
<entry name="already_bound" value="0"
|
||||||
|
summary="the wl_display_upgrade global was bound more than once"/>
|
||||||
|
<entry name="has_objects" value="1"
|
||||||
|
summary="objects other than wl_display and this object exist"/>
|
||||||
|
<entry name="out_of_bounds" value="2"
|
||||||
|
summary="the version requested by the upgrade request is out of bounds"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<event name="max_version">
|
||||||
|
<description summary="the version supported by the compositor">
|
||||||
|
This event informs the client of the maximum wl_display version
|
||||||
|
supported by the compositor. It is sent immediately after this global
|
||||||
|
has been bound. The version is guaranteed to be at least 1.
|
||||||
|
</description>
|
||||||
|
<arg name="version" type="uint" summary="the version"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<request name="upgrade" type="destructor">
|
||||||
|
<description summary="upgrade the wl_display version">
|
||||||
|
Negotiates an upgrade of the version of the wl_display object.
|
||||||
|
|
||||||
|
At the time of the request, no objects other than the wl_display and
|
||||||
|
this object must exist, otherwise the has_objects error is emitted. In
|
||||||
|
particular, the client must use wl_fixes to destroy the registry from
|
||||||
|
which this object was created.
|
||||||
|
|
||||||
|
The version must be at least 1 and must not be larger than the version
|
||||||
|
sent in the version event, otherwise the out_of_bounds error is emitted.
|
||||||
|
</description>
|
||||||
|
<arg name="version" type="uint" summary="the version"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
|
||||||
</protocol>
|
</protocol>
|
||||||
|
|
|
||||||
|
|
@ -245,6 +245,9 @@ wl_display_connect_to_fd(int fd);
|
||||||
void
|
void
|
||||||
wl_display_disconnect(struct wl_display *display);
|
wl_display_disconnect(struct wl_display *display);
|
||||||
|
|
||||||
|
void
|
||||||
|
wl_display_upgrade(struct wl_display *display);
|
||||||
|
|
||||||
int
|
int
|
||||||
wl_display_get_fd(struct wl_display *display);
|
wl_display_get_fd(struct wl_display *display);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1405,6 +1405,84 @@ wl_display_disconnect(struct wl_display *display)
|
||||||
free(display);
|
free(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct upgrade_listener {
|
||||||
|
struct wl_fixes *wl_fixes;
|
||||||
|
struct wl_display_upgrade *wl_display_upgrade;
|
||||||
|
uint32_t version;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void upgrade_max_version(void *data,
|
||||||
|
struct wl_display_upgrade *wl_display_upgrade,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
struct upgrade_listener *listener = data;
|
||||||
|
listener->version = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_display_upgrade_listener upgrade_upgrade_listener = {
|
||||||
|
.max_version = upgrade_max_version,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void upgrade_global(void *data, struct wl_registry *wl_registry,
|
||||||
|
uint32_t name, const char *interface,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
struct upgrade_listener *listener = data;
|
||||||
|
if (!listener->wl_fixes && strcmp(interface, wl_fixes_interface.name) == 0)
|
||||||
|
listener->wl_fixes = wl_registry_bind(wl_registry, name, &wl_fixes_interface, 1);
|
||||||
|
else if (!listener->wl_display_upgrade && strcmp(interface, wl_display_upgrade_interface.name) == 0) {
|
||||||
|
listener->wl_display_upgrade = wl_registry_bind(wl_registry, name, &wl_display_upgrade_interface, 1);
|
||||||
|
wl_display_upgrade_add_listener(listener->wl_display_upgrade, &upgrade_upgrade_listener, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void upgrade_global_remove(void *data, struct wl_registry *wl_registry,
|
||||||
|
uint32_t name)
|
||||||
|
{
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_registry_listener upgrade_registry_listener = {
|
||||||
|
.global = upgrade_global,
|
||||||
|
.global_remove = upgrade_global_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
|
/** Upgrade the wl_display version.
|
||||||
|
*
|
||||||
|
* \param display The display context object
|
||||||
|
*
|
||||||
|
* Tries to upgrade the version of the wl_display. After this function returns,
|
||||||
|
* wl_display_get_version can be used to retrieve the new version of the
|
||||||
|
* wl_display.
|
||||||
|
*
|
||||||
|
* This function should be called immediately after creating the display. It
|
||||||
|
* must not be called any later than that or multiple times, otherwise a
|
||||||
|
* protocol error might occur.
|
||||||
|
*
|
||||||
|
* \memberof wl_display
|
||||||
|
*/
|
||||||
|
WL_EXPORT void
|
||||||
|
wl_display_upgrade(struct wl_display *display)
|
||||||
|
{
|
||||||
|
struct wl_registry *registry = wl_display_get_registry(display);
|
||||||
|
struct upgrade_listener listener = { };
|
||||||
|
wl_registry_add_listener(registry, &upgrade_registry_listener, &listener);
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
if (listener.wl_display_upgrade)
|
||||||
|
wl_display_roundtrip(display);
|
||||||
|
if (listener.wl_fixes) {
|
||||||
|
wl_fixes_destroy_registry(listener.wl_fixes, registry);
|
||||||
|
wl_fixes_destroy(listener.wl_fixes);
|
||||||
|
}
|
||||||
|
if (listener.wl_display_upgrade) {
|
||||||
|
uint32_t version = min(listener.version, (uint32_t)wl_display_interface.version);
|
||||||
|
wl_display_upgrade_upgrade(listener.wl_display_upgrade, version);
|
||||||
|
display->proxy.version = version;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Get a display context's file descriptor
|
/** Get a display context's file descriptor
|
||||||
*
|
*
|
||||||
* \param display The display context object
|
* \param display The display context object
|
||||||
|
|
|
||||||
|
|
@ -697,6 +697,9 @@ wl_shm_buffer_create(struct wl_client *client,
|
||||||
uint32_t id, int32_t width, int32_t height,
|
uint32_t id, int32_t width, int32_t height,
|
||||||
int32_t stride, uint32_t format);
|
int32_t stride, uint32_t format);
|
||||||
|
|
||||||
|
int
|
||||||
|
wl_display_init_upgrade(struct wl_display *display, uint32_t max_version);
|
||||||
|
|
||||||
void
|
void
|
||||||
wl_log_set_handler_server(wl_log_func_t handler);
|
wl_log_set_handler_server(wl_log_func_t handler);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ struct wl_client {
|
||||||
struct wl_priv_signal resource_created_signal;
|
struct wl_priv_signal resource_created_signal;
|
||||||
void *data;
|
void *data;
|
||||||
wl_user_data_destroy_func_t data_dtor;
|
wl_user_data_destroy_func_t data_dtor;
|
||||||
|
bool has_upgrade;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_display {
|
struct wl_display {
|
||||||
|
|
@ -113,6 +114,7 @@ struct wl_display {
|
||||||
struct wl_event_source *term_source;
|
struct wl_event_source *term_source;
|
||||||
|
|
||||||
size_t max_buffer_size;
|
size_t max_buffer_size;
|
||||||
|
uint32_t max_upgrade_version;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wl_global {
|
struct wl_global {
|
||||||
|
|
@ -1077,8 +1079,15 @@ registry_bind(struct wl_client *client,
|
||||||
global->bind(client, global->data, version, id);
|
global->bind(client, global->data, version, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
registry_release(struct wl_client *client, struct wl_resource *resource)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wl_registry_interface registry_interface = {
|
static const struct wl_registry_interface registry_interface = {
|
||||||
registry_bind
|
.bind = registry_bind,
|
||||||
|
.release = registry_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
@ -1114,7 +1123,7 @@ display_get_registry(struct wl_client *client,
|
||||||
struct wl_global *global;
|
struct wl_global *global;
|
||||||
|
|
||||||
registry_resource =
|
registry_resource =
|
||||||
wl_resource_create(client, &wl_registry_interface, 1, id);
|
wl_resource_create(client, &wl_registry_interface, resource->version, id);
|
||||||
if (registry_resource == NULL) {
|
if (registry_resource == NULL) {
|
||||||
wl_client_post_no_memory(client);
|
wl_client_post_no_memory(client);
|
||||||
return;
|
return;
|
||||||
|
|
@ -2428,6 +2437,59 @@ wl_client_set_max_buffer_size(struct wl_client *client, size_t max_buffer_size)
|
||||||
wl_connection_set_max_buffer_size(client->connection, max_buffer_size);
|
wl_connection_set_max_buffer_size(client->connection, max_buffer_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
upgrade_display(struct wl_client *client, struct wl_resource *resource,
|
||||||
|
uint32_t version)
|
||||||
|
{
|
||||||
|
wl_resource_destroy(resource);
|
||||||
|
// TODO: Check that there are no other objects.
|
||||||
|
if (version < 1 || version > client->display->max_upgrade_version) {
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
WL_DISPLAY_UPGRADE_ERROR_OUT_OF_BOUNDS,
|
||||||
|
"version is out of bounds");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client->display_resource->version = (int)version;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct wl_display_upgrade_interface upgrade_interface = {
|
||||||
|
.upgrade = upgrade_display,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
bind_upgrade(struct wl_client *client, void *data, uint32_t version,
|
||||||
|
uint32_t id)
|
||||||
|
{
|
||||||
|
struct wl_resource *resource;
|
||||||
|
resource = wl_resource_create(client, &wl_display_upgrade_interface,
|
||||||
|
(int)version, id);
|
||||||
|
if (!resource) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (client->has_upgrade) {
|
||||||
|
wl_resource_post_error(resource,
|
||||||
|
WL_DISPLAY_UPGRADE_ERROR_ALREADY_BOUND,
|
||||||
|
"wl_display_upgrade has already been bound");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
client->has_upgrade = true;
|
||||||
|
wl_display_upgrade_send_max_version(resource,
|
||||||
|
client->display->max_upgrade_version);
|
||||||
|
wl_resource_set_implementation(resource, &upgrade_interface, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
WL_EXPORT int
|
||||||
|
wl_display_init_upgrade(struct wl_display *display, uint32_t max_version)
|
||||||
|
{
|
||||||
|
if (max_version > (uint32_t)wl_display_upgrade_interface.version)
|
||||||
|
max_version = wl_display_upgrade_interface.version;
|
||||||
|
display->max_upgrade_version = max_version;
|
||||||
|
if (!wl_global_create(display, &wl_display_upgrade_interface, 1, NULL, bind_upgrade))
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/** \cond INTERNAL */
|
/** \cond INTERNAL */
|
||||||
|
|
||||||
/** Initialize a wl_priv_signal object
|
/** Initialize a wl_priv_signal object
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue