mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-12-22 18:09:49 +01:00
output-management-v1: update protocol, add set_custom_mode
This commit is contained in:
parent
fc0ba3ea22
commit
ab3446091b
3 changed files with 108 additions and 35 deletions
|
@ -26,7 +26,7 @@
|
|||
</copyright>
|
||||
|
||||
<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.
|
||||
|
||||
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 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
|
||||
changed. Each head may have one or more available modes.
|
||||
destroyed by the client, but they can be enabled or disabled and their
|
||||
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
|
||||
appear.
|
||||
Whenever a head appears (e.g. a monitor is plugged in), it will be
|
||||
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
|
||||
sent. It carries a serial which can be used in a create_configuration
|
||||
request to change heads properties.
|
||||
Whenever a head's properties change, the relevant wlr_output_head events
|
||||
will be sent. Not all head properties will be sent: only properties that
|
||||
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
|
||||
configuration purposes. This protocol is not designed to be a generic
|
||||
|
@ -64,7 +72,9 @@
|
|||
|
||||
<event name="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>
|
||||
<arg name="head" type="new_id" interface="zwlr_output_head_v1"/>
|
||||
</event>
|
||||
|
@ -75,7 +85,8 @@
|
|||
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
|
||||
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,
|
||||
even if they happen via multiple events.
|
||||
|
@ -116,28 +127,21 @@
|
|||
|
||||
<interface name="zwlr_output_head_v1" version="1">
|
||||
<description summary="output device">
|
||||
A head is an output device. The difference with wl_output is that heads
|
||||
are advertized even if they are turned off. A head object only advertises
|
||||
properties and cannot be used directly to change them. In order to update
|
||||
some properties, one needs to create a wlr_output_configuration object.
|
||||
A head is an output device. The difference between a wl_output object and
|
||||
a head is that heads are advertised even if they are turned off. A head
|
||||
object only advertises properties and cannot be used directly to change
|
||||
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.
|
||||
|
||||
enabled and current_mode are physical properties. Updating them might take
|
||||
some time, depending on hardware limitations.
|
||||
Other properties can be updated via a wlr_output_configuration object.
|
||||
|
||||
position, transform and scale are logical properties. They describe how
|
||||
the output is mapped in the global compositor space.
|
||||
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>
|
||||
|
||||
<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">
|
||||
<description summary="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
|
||||
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,
|
||||
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"/>
|
||||
</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">
|
||||
<description summary="head is enabled or disabled">
|
||||
This event describes whether the head is enabled. A disabled head is not
|
||||
|
@ -204,7 +218,7 @@
|
|||
<event name="current_mode">
|
||||
<description summary="current mode">
|
||||
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>
|
||||
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
||||
</event>
|
||||
|
@ -251,6 +265,10 @@
|
|||
|
||||
Some heads don't support output modes, in which case modes won't be
|
||||
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>
|
||||
|
||||
<event name="size">
|
||||
|
@ -266,7 +284,8 @@
|
|||
|
||||
<event name="refresh">
|
||||
<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>
|
||||
<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
|
||||
</event>
|
||||
|
@ -322,7 +341,7 @@
|
|||
|
||||
<request name="disable_head">
|
||||
<description summary="disable a head">
|
||||
Disable a head. The head's properties are irrelevant in this case.
|
||||
Disable a head.
|
||||
</description>
|
||||
<arg name="head" type="object" interface="zwlr_output_head_v1"
|
||||
summary="the head to be disabled"/>
|
||||
|
@ -363,6 +382,9 @@
|
|||
tested them.
|
||||
|
||||
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>
|
||||
</event>
|
||||
|
||||
|
@ -404,12 +426,16 @@
|
|||
<interface name="zwlr_output_configuration_head_v1" version="1">
|
||||
<description summary="head 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>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="invalid_mode" value="1" summary="mode doesn't belong to head"/>
|
||||
<entry name="invalid_transform" value="2" summary="transform value outside enum"/>
|
||||
<entry name="invalid_scale" value="3" summary="scale negative or zero"/>
|
||||
<entry name="already_set" value="1" summary="property has already been set"/>
|
||||
<entry name="invalid_mode" value="2" summary="mode doesn't belong to head"/>
|
||||
<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>
|
||||
|
||||
<request name="set_mode">
|
||||
|
@ -419,6 +445,19 @@
|
|||
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
||||
</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">
|
||||
<description summary="set the position">
|
||||
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) {
|
||||
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,
|
||||
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 *output = config_head->state.output;
|
||||
|
||||
bool found = false;
|
||||
bool found = (mode == NULL && wl_list_empty(&output->modes));
|
||||
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) {
|
||||
found = true;
|
||||
break;
|
||||
|
@ -167,6 +168,33 @@ static void config_head_handle_set_mode(struct wl_client *client,
|
|||
}
|
||||
|
||||
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,
|
||||
|
@ -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 = {
|
||||
.set_mode = config_head_handle_set_mode,
|
||||
.set_custom_mode = config_head_handle_set_custom_mode,
|
||||
.set_position = config_head_handle_set_position,
|
||||
.set_transform = config_head_handle_set_transform,
|
||||
.set_scale = config_head_handle_set_scale,
|
||||
|
|
Loading…
Reference in a new issue