output-management-v1: update protocol, add set_custom_mode
This commit is contained in:
parent
fc0ba3ea22
commit
ab3446091b
|
@ -26,7 +26,7 @@
|
||||||
</copyright>
|
</copyright>
|
||||||
|
|
||||||
<description summary="protocol to configure output devices">
|
<description summary="protocol to configure output devices">
|
||||||
This protocol exposes interfaces to get and change output device
|
This protocol exposes interfaces to obtain and modify output device
|
||||||
configuration.
|
configuration.
|
||||||
|
|
||||||
Warning! The protocol described in this file is experimental and
|
Warning! The protocol described in this file is experimental and
|
||||||
|
@ -46,15 +46,23 @@
|
||||||
|
|
||||||
Output devices that display pixels (e.g. a physical monitor or a virtual
|
Output devices that display pixels (e.g. a physical monitor or a virtual
|
||||||
output in a window) are represented as heads. Heads cannot be created nor
|
output in a window) are represented as heads. Heads cannot be created nor
|
||||||
destroyed, but they can be enabled or disabled and their properties can be
|
destroyed by the client, but they can be enabled or disabled and their
|
||||||
changed. Each head may have one or more available modes.
|
properties can be changed. Each head may have one or more available modes.
|
||||||
|
|
||||||
Heads are advertised when the output manager is bound, and whenever they
|
Whenever a head appears (e.g. a monitor is plugged in), it will be
|
||||||
appear.
|
advertised via the head event. Immediately after the output manager is
|
||||||
|
bound, all current heads are advertised.
|
||||||
|
|
||||||
Whenever the number of heads or modes changes, the done event will be
|
Whenever a head's properties change, the relevant wlr_output_head events
|
||||||
sent. It carries a serial which can be used in a create_configuration
|
will be sent. Not all head properties will be sent: only properties that
|
||||||
request to change heads properties.
|
have changed need to.
|
||||||
|
|
||||||
|
Whenever a head disappears (e.g. a monitor is unplugged), a
|
||||||
|
wlr_output_head.finished event will be sent.
|
||||||
|
|
||||||
|
After one or more heads appear, change or disappear, the done event will
|
||||||
|
be sent. It carries a serial which can be used in a create_configuration
|
||||||
|
request to update heads properties.
|
||||||
|
|
||||||
The information obtained from this protocol should only be used for output
|
The information obtained from this protocol should only be used for output
|
||||||
configuration purposes. This protocol is not designed to be a generic
|
configuration purposes. This protocol is not designed to be a generic
|
||||||
|
@ -64,7 +72,9 @@
|
||||||
|
|
||||||
<event name="head">
|
<event name="head">
|
||||||
<description summary="introduce a new head">
|
<description summary="introduce a new head">
|
||||||
This event introduces a new head.
|
This event introduces a new head. This happens whenever a new head
|
||||||
|
appears (e.g. a monitor is plugged in) or after the output manager is
|
||||||
|
bound.
|
||||||
</description>
|
</description>
|
||||||
<arg name="head" type="new_id" interface="zwlr_output_head_v1"/>
|
<arg name="head" type="new_id" interface="zwlr_output_head_v1"/>
|
||||||
</event>
|
</event>
|
||||||
|
@ -75,7 +85,8 @@
|
||||||
the output manager object and after any subsequent changes. This applies
|
the output manager object and after any subsequent changes. This applies
|
||||||
to child head and mode objects as well. In other words, this event is
|
to child head and mode objects as well. In other words, this event is
|
||||||
sent whenever a head or mode is created or destroyed and whenever one of
|
sent whenever a head or mode is created or destroyed and whenever one of
|
||||||
their properties has been changed.
|
their properties has been changed. Not all state is re-sent each time
|
||||||
|
the current configuration changes: only the actual changes are sent.
|
||||||
|
|
||||||
This allows changes to the output configuration to be seen as atomic,
|
This allows changes to the output configuration to be seen as atomic,
|
||||||
even if they happen via multiple events.
|
even if they happen via multiple events.
|
||||||
|
@ -116,28 +127,21 @@
|
||||||
|
|
||||||
<interface name="zwlr_output_head_v1" version="1">
|
<interface name="zwlr_output_head_v1" version="1">
|
||||||
<description summary="output device">
|
<description summary="output device">
|
||||||
A head is an output device. The difference with wl_output is that heads
|
A head is an output device. The difference between a wl_output object and
|
||||||
are advertized even if they are turned off. A head object only advertises
|
a head is that heads are advertised even if they are turned off. A head
|
||||||
properties and cannot be used directly to change them. In order to update
|
object only advertises properties and cannot be used directly to change
|
||||||
some properties, one needs to create a wlr_output_configuration object.
|
them.
|
||||||
|
|
||||||
A head has some read-only properties: mode, name, description and
|
A head has some read-only properties: modes, name, description and
|
||||||
physical_size. These cannot be changed by clients.
|
physical_size. These cannot be changed by clients.
|
||||||
|
|
||||||
enabled and current_mode are physical properties. Updating them might take
|
Other properties can be updated via a wlr_output_configuration object.
|
||||||
some time, depending on hardware limitations.
|
|
||||||
|
|
||||||
position, transform and scale are logical properties. They describe how
|
Properties sent via this interface are applied atomically via the
|
||||||
the output is mapped in the global compositor space.
|
wlr_output_manager.done event. No guarantees are made regarding the order
|
||||||
|
in which properties are sent.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<event name="mode">
|
|
||||||
<description summary="advertise a supported mode">
|
|
||||||
If the head supports modes, this event is sent once per supported mode.
|
|
||||||
</description>
|
|
||||||
<arg name="mode" type="new_id" interface="zwlr_output_mode_v1"/>
|
|
||||||
</event>
|
|
||||||
|
|
||||||
<event name="name">
|
<event name="name">
|
||||||
<description summary="head name">
|
<description summary="head name">
|
||||||
This event describes the head name.
|
This event describes the head name.
|
||||||
|
@ -168,7 +172,9 @@
|
||||||
|
|
||||||
The description is a UTF-8 string with no convention defined for its
|
The description is a UTF-8 string with no convention defined for its
|
||||||
contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
|
contents. Examples might include 'Foocorp 11" Display' or 'Virtual X11
|
||||||
output via :1'.
|
output via :1'. However, do not assume that the name is a reflection of
|
||||||
|
the make, model, serial of the underlying DRM connector or the display
|
||||||
|
name of the underlying X11 connection, etc.
|
||||||
|
|
||||||
If the compositor implements xdg-output and this head is enabled,
|
If the compositor implements xdg-output and this head is enabled,
|
||||||
the xdg_output.description must report the same description.
|
the xdg_output.description must report the same description.
|
||||||
|
@ -190,6 +196,14 @@
|
||||||
<arg name="height" type="int" summary="height in millimeters of the output"/>
|
<arg name="height" type="int" summary="height in millimeters of the output"/>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
<event name="mode">
|
||||||
|
<description summary="introduce a mode">
|
||||||
|
This event introduces a mode for this head. It is sent once per
|
||||||
|
supported mode.
|
||||||
|
</description>
|
||||||
|
<arg name="mode" type="new_id" interface="zwlr_output_mode_v1"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
<event name="enabled">
|
<event name="enabled">
|
||||||
<description summary="head is enabled or disabled">
|
<description summary="head is enabled or disabled">
|
||||||
This event describes whether the head is enabled. A disabled head is not
|
This event describes whether the head is enabled. A disabled head is not
|
||||||
|
@ -204,7 +218,7 @@
|
||||||
<event name="current_mode">
|
<event name="current_mode">
|
||||||
<description summary="current mode">
|
<description summary="current mode">
|
||||||
This event describes the mode currently in use for this head. It is only
|
This event describes the mode currently in use for this head. It is only
|
||||||
sent if the output is enabled and supports modes.
|
sent if the output is enabled.
|
||||||
</description>
|
</description>
|
||||||
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
||||||
</event>
|
</event>
|
||||||
|
@ -251,6 +265,10 @@
|
||||||
|
|
||||||
Some heads don't support output modes, in which case modes won't be
|
Some heads don't support output modes, in which case modes won't be
|
||||||
advertised.
|
advertised.
|
||||||
|
|
||||||
|
Properties sent via this interface are applied atomically via the
|
||||||
|
wlr_output_manager.done event. No guarantees are made regarding the order
|
||||||
|
in which properties are sent.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<event name="size">
|
<event name="size">
|
||||||
|
@ -266,7 +284,8 @@
|
||||||
|
|
||||||
<event name="refresh">
|
<event name="refresh">
|
||||||
<description summary="mode refresh rate">
|
<description summary="mode refresh rate">
|
||||||
This event describes the mode's fixed vertical refresh rate, if any.
|
This event describes the mode's fixed vertical refresh rate. It is only
|
||||||
|
sent if the mode has a fixed refresh rate.
|
||||||
</description>
|
</description>
|
||||||
<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
|
<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
|
||||||
</event>
|
</event>
|
||||||
|
@ -322,7 +341,7 @@
|
||||||
|
|
||||||
<request name="disable_head">
|
<request name="disable_head">
|
||||||
<description summary="disable a head">
|
<description summary="disable a head">
|
||||||
Disable a head. The head's properties are irrelevant in this case.
|
Disable a head.
|
||||||
</description>
|
</description>
|
||||||
<arg name="head" type="object" interface="zwlr_output_head_v1"
|
<arg name="head" type="object" interface="zwlr_output_head_v1"
|
||||||
summary="the head to be disabled"/>
|
summary="the head to be disabled"/>
|
||||||
|
@ -363,6 +382,9 @@
|
||||||
tested them.
|
tested them.
|
||||||
|
|
||||||
Upon receiving this event, the client should destroy this object.
|
Upon receiving this event, the client should destroy this object.
|
||||||
|
|
||||||
|
If the current configuration has changed, events to describe the changes
|
||||||
|
will be sent followed by a wlr_output_manager.done event.
|
||||||
</description>
|
</description>
|
||||||
</event>
|
</event>
|
||||||
|
|
||||||
|
@ -404,12 +426,16 @@
|
||||||
<interface name="zwlr_output_configuration_head_v1" version="1">
|
<interface name="zwlr_output_configuration_head_v1" version="1">
|
||||||
<description summary="head configuration">
|
<description summary="head configuration">
|
||||||
This object is used by the client to update a single head's configuration.
|
This object is used by the client to update a single head's configuration.
|
||||||
|
|
||||||
|
It is a protocol error to set the same property twice.
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<enum name="error">
|
<enum name="error">
|
||||||
<entry name="invalid_mode" value="1" summary="mode doesn't belong to head"/>
|
<entry name="already_set" value="1" summary="property has already been set"/>
|
||||||
<entry name="invalid_transform" value="2" summary="transform value outside enum"/>
|
<entry name="invalid_mode" value="2" summary="mode doesn't belong to head"/>
|
||||||
<entry name="invalid_scale" value="3" summary="scale negative or zero"/>
|
<entry name="invalid_custom_mode" value="3" summary="mode is invalid"/>
|
||||||
|
<entry name="invalid_transform" value="4" summary="transform value outside enum"/>
|
||||||
|
<entry name="invalid_scale" value="5" summary="scale negative or zero"/>
|
||||||
</enum>
|
</enum>
|
||||||
|
|
||||||
<request name="set_mode">
|
<request name="set_mode">
|
||||||
|
@ -419,6 +445,19 @@
|
||||||
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
||||||
</request>
|
</request>
|
||||||
|
|
||||||
|
<request name="set_custom_mode">
|
||||||
|
<description summary="set a custom mode">
|
||||||
|
This request assigns a custom mode to the head. The size is given in
|
||||||
|
physical hardware units of the output device. If set to zero, the
|
||||||
|
refresh rate is unspecified.
|
||||||
|
|
||||||
|
It is a protocol error to set both a mode and a custom mode.
|
||||||
|
</description>
|
||||||
|
<arg name="width" type="int" summary="width of the mode in hardware units"/>
|
||||||
|
<arg name="height" type="int" summary="height of the mode in hardware units"/>
|
||||||
|
<arg name="refresh" type="int" summary="vertical refresh rate in mHz or zero"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
<request name="set_position">
|
<request name="set_position">
|
||||||
<description summary="set the position">
|
<description summary="set the position">
|
||||||
This request sets the head's position in the global compositor space.
|
This request sets the head's position in the global compositor space.
|
||||||
|
|
|
@ -451,6 +451,11 @@ void handle_output_manager_apply(struct wl_listener *listener, void *data) {
|
||||||
}
|
}
|
||||||
if (config_head->state.mode != NULL) {
|
if (config_head->state.mode != NULL) {
|
||||||
ok &= wlr_output_set_mode(wlr_output, config_head->state.mode);
|
ok &= wlr_output_set_mode(wlr_output, config_head->state.mode);
|
||||||
|
} else {
|
||||||
|
ok &= wlr_output_set_custom_mode(wlr_output,
|
||||||
|
config_head->state.custom_mode.width,
|
||||||
|
config_head->state.custom_mode.height,
|
||||||
|
config_head->state.custom_mode.refresh);
|
||||||
}
|
}
|
||||||
wlr_output_layout_add(desktop->layout, wlr_output,
|
wlr_output_layout_add(desktop->layout, wlr_output,
|
||||||
config_head->state.x, config_head->state.y);
|
config_head->state.x, config_head->state.y);
|
||||||
|
|
|
@ -149,10 +149,11 @@ static void config_head_handle_set_mode(struct wl_client *client,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_output_mode *mode = mode_from_resource(mode_resource);
|
struct wlr_output_mode *mode = mode_from_resource(mode_resource);
|
||||||
|
struct wlr_output *output = config_head->state.output;
|
||||||
|
|
||||||
bool found = false;
|
bool found = (mode == NULL && wl_list_empty(&output->modes));
|
||||||
struct wlr_output_mode *m;
|
struct wlr_output_mode *m;
|
||||||
wl_list_for_each(m, &config_head->state.output->modes, link) {
|
wl_list_for_each(m, &output->modes, link) {
|
||||||
if (mode == m) {
|
if (mode == m) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
@ -167,6 +168,33 @@ static void config_head_handle_set_mode(struct wl_client *client,
|
||||||
}
|
}
|
||||||
|
|
||||||
config_head->state.mode = mode;
|
config_head->state.mode = mode;
|
||||||
|
if (mode != NULL) {
|
||||||
|
config_head->state.custom_mode.width = 0;
|
||||||
|
config_head->state.custom_mode.height = 0;
|
||||||
|
config_head->state.custom_mode.refresh = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void config_head_handle_set_custom_mode(struct wl_client *client,
|
||||||
|
struct wl_resource *config_head_resource, int32_t width, int32_t height,
|
||||||
|
int32_t refresh) {
|
||||||
|
struct wlr_output_configuration_head_v1 *config_head =
|
||||||
|
config_head_from_resource(config_head_resource);
|
||||||
|
if (config_head == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width <= 0 || height <= 0 || refresh < 0) {
|
||||||
|
wl_resource_post_error(config_head_resource,
|
||||||
|
ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_CUSTOM_MODE,
|
||||||
|
"invalid custom mode");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config_head->state.mode = NULL;
|
||||||
|
config_head->state.custom_mode.width = width;
|
||||||
|
config_head->state.custom_mode.height = height;
|
||||||
|
config_head->state.custom_mode.refresh = refresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void config_head_handle_set_position(struct wl_client *client,
|
static void config_head_handle_set_position(struct wl_client *client,
|
||||||
|
@ -221,6 +249,7 @@ static void config_head_handle_set_scale(struct wl_client *client,
|
||||||
|
|
||||||
static const struct zwlr_output_configuration_head_v1_interface config_head_impl = {
|
static const struct zwlr_output_configuration_head_v1_interface config_head_impl = {
|
||||||
.set_mode = config_head_handle_set_mode,
|
.set_mode = config_head_handle_set_mode,
|
||||||
|
.set_custom_mode = config_head_handle_set_custom_mode,
|
||||||
.set_position = config_head_handle_set_position,
|
.set_position = config_head_handle_set_position,
|
||||||
.set_transform = config_head_handle_set_transform,
|
.set_transform = config_head_handle_set_transform,
|
||||||
.set_scale = config_head_handle_set_scale,
|
.set_scale = config_head_handle_set_scale,
|
||||||
|
|
Loading…
Reference in New Issue