mirror of
https://github.com/emersion/kanshi
synced 2024-09-18 09:51:36 +02:00
Listen to output-management events
This commit is contained in:
parent
4f0ee6a165
commit
7952a0b691
50
include/kanshi.h
Normal file
50
include/kanshi.h
Normal file
@ -0,0 +1,50 @@
|
||||
#ifndef KANSHI_KANSHI_H
|
||||
#define KANSHI_KANSHI_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
struct zwlr_output_manager_v1;
|
||||
|
||||
struct kanshi_state;
|
||||
struct kanshi_head;
|
||||
|
||||
struct kanshi_mode {
|
||||
struct kanshi_head *head;
|
||||
struct zwlr_output_mode_v1 *wlr_mode;
|
||||
struct wl_list link;
|
||||
|
||||
int32_t width, height;
|
||||
int32_t refresh; // mHz
|
||||
bool preferred;
|
||||
};
|
||||
|
||||
struct kanshi_head {
|
||||
struct kanshi_state *state;
|
||||
struct zwlr_output_head_v1 *wlr_head;
|
||||
struct wl_list link;
|
||||
|
||||
char *name, *description;
|
||||
int32_t phys_width, phys_height; // mm
|
||||
struct wl_list modes;
|
||||
|
||||
bool enabled;
|
||||
struct kanshi_mode *mode;
|
||||
struct {
|
||||
int32_t width, height;
|
||||
int32_t refresh;
|
||||
} custom_mode;
|
||||
int32_t x, y;
|
||||
enum wl_output_transform transform;
|
||||
double scale;
|
||||
};
|
||||
|
||||
struct kanshi_state {
|
||||
bool running;
|
||||
struct zwlr_output_manager_v1 *output_manager;
|
||||
|
||||
struct wl_list heads;
|
||||
uint32_t serial;
|
||||
};
|
||||
|
||||
#endif
|
219
main.c
219
main.c
@ -1,8 +1,199 @@
|
||||
#define _POSIX_C_SOURCE 1
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wayland-client.h>
|
||||
|
||||
#include "kanshi.h"
|
||||
#include "parser.h"
|
||||
#include "wlr-output-management-unstable-v1-client-protocol.h"
|
||||
|
||||
|
||||
static void mode_handle_size(void *data, struct zwlr_output_mode_v1 *wlr_mode,
|
||||
int32_t width, int32_t height) {
|
||||
struct kanshi_mode *mode = data;
|
||||
mode->width = width;
|
||||
mode->height = height;
|
||||
}
|
||||
|
||||
static void mode_handle_refresh(void *data,
|
||||
struct zwlr_output_mode_v1 *wlr_mode, int32_t refresh) {
|
||||
struct kanshi_mode *mode = data;
|
||||
mode->refresh = refresh;
|
||||
}
|
||||
|
||||
static void mode_handle_preferred(void *data,
|
||||
struct zwlr_output_mode_v1 *wlr_mode) {
|
||||
struct kanshi_mode *mode = data;
|
||||
mode->preferred = true;
|
||||
}
|
||||
|
||||
static void mode_handle_finished(void *data,
|
||||
struct zwlr_output_mode_v1 *wlr_mode) {
|
||||
struct kanshi_mode *mode = data;
|
||||
wl_list_remove(&mode->link);
|
||||
zwlr_output_mode_v1_destroy(mode->wlr_mode);
|
||||
free(mode);
|
||||
}
|
||||
|
||||
static const struct zwlr_output_mode_v1_listener mode_listener = {
|
||||
.size = mode_handle_size,
|
||||
.refresh = mode_handle_refresh,
|
||||
.preferred = mode_handle_preferred,
|
||||
.finished = mode_handle_finished,
|
||||
};
|
||||
|
||||
static void head_handle_name(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, const char *name) {
|
||||
struct kanshi_head *head = data;
|
||||
head->name = strdup(name);
|
||||
}
|
||||
|
||||
static void head_handle_description(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, const char *description) {
|
||||
struct kanshi_head *head = data;
|
||||
head->description = strdup(description);
|
||||
}
|
||||
|
||||
static void head_handle_physical_size(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, int32_t width, int32_t height) {
|
||||
struct kanshi_head *head = data;
|
||||
head->phys_width = width;
|
||||
head->phys_height = height;
|
||||
}
|
||||
|
||||
static void head_handle_mode(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head,
|
||||
struct zwlr_output_mode_v1 *wlr_mode) {
|
||||
struct kanshi_head *head = data;
|
||||
|
||||
struct kanshi_mode *mode = calloc(1, sizeof(*mode));
|
||||
mode->head = head;
|
||||
mode->wlr_mode = wlr_mode;
|
||||
wl_list_insert(&head->modes, &mode->link);
|
||||
|
||||
zwlr_output_mode_v1_add_listener(wlr_mode, &mode_listener, mode);
|
||||
}
|
||||
|
||||
static void head_handle_enabled(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, int32_t enabled) {
|
||||
struct kanshi_head *head = data;
|
||||
head->enabled = !!enabled;
|
||||
if (!enabled) {
|
||||
head->mode = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void head_handle_current_mode(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head,
|
||||
struct zwlr_output_mode_v1 *wlr_mode) {
|
||||
struct kanshi_head *head = data;
|
||||
struct kanshi_mode *mode;
|
||||
wl_list_for_each(mode, &head->modes, link) {
|
||||
if (mode->wlr_mode == wlr_mode) {
|
||||
head->mode = mode;
|
||||
return;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "received unknown current_mode\n");
|
||||
head->mode = NULL;
|
||||
}
|
||||
|
||||
static void head_handle_position(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, int32_t x, int32_t y) {
|
||||
struct kanshi_head *head = data;
|
||||
head->x = x;
|
||||
head->y = y;
|
||||
}
|
||||
|
||||
static void head_handle_transform(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, int32_t transform) {
|
||||
struct kanshi_head *head = data;
|
||||
head->transform = transform;
|
||||
}
|
||||
|
||||
static void head_handle_scale(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head, wl_fixed_t scale) {
|
||||
struct kanshi_head *head = data;
|
||||
head->scale = wl_fixed_to_double(scale);
|
||||
}
|
||||
|
||||
static void head_handle_finished(void *data,
|
||||
struct zwlr_output_head_v1 *wlr_head) {
|
||||
struct kanshi_head *head = data;
|
||||
wl_list_remove(&head->link);
|
||||
zwlr_output_head_v1_destroy(head->wlr_head);
|
||||
free(head->name);
|
||||
free(head->description);
|
||||
free(head);
|
||||
}
|
||||
|
||||
static const struct zwlr_output_head_v1_listener head_listener = {
|
||||
.name = head_handle_name,
|
||||
.description = head_handle_description,
|
||||
.physical_size = head_handle_physical_size,
|
||||
.mode = head_handle_mode,
|
||||
.enabled = head_handle_enabled,
|
||||
.current_mode = head_handle_current_mode,
|
||||
.position = head_handle_position,
|
||||
.transform = head_handle_transform,
|
||||
.scale = head_handle_scale,
|
||||
.finished = head_handle_finished,
|
||||
};
|
||||
|
||||
static void output_manager_handle_head(void *data,
|
||||
struct zwlr_output_manager_v1 *manager,
|
||||
struct zwlr_output_head_v1 *wlr_head) {
|
||||
struct kanshi_state *state = data;
|
||||
|
||||
struct kanshi_head *head = calloc(1, sizeof(*head));
|
||||
head->state = state;
|
||||
head->wlr_head = wlr_head;
|
||||
head->scale = 1.0;
|
||||
wl_list_init(&head->modes);
|
||||
wl_list_insert(&state->heads, &head->link);
|
||||
|
||||
zwlr_output_head_v1_add_listener(wlr_head, &head_listener, head);
|
||||
}
|
||||
|
||||
static void output_manager_handle_done(void *data,
|
||||
struct zwlr_output_manager_v1 *manager, uint32_t serial) {
|
||||
struct kanshi_state *state = data;
|
||||
state->serial = serial;
|
||||
}
|
||||
|
||||
static void output_manager_handle_finished(void *data,
|
||||
struct zwlr_output_manager_v1 *manager) {
|
||||
// This space is intentionally left blank
|
||||
}
|
||||
|
||||
static const struct zwlr_output_manager_v1_listener output_manager_listener = {
|
||||
.head = output_manager_handle_head,
|
||||
.done = output_manager_handle_done,
|
||||
.finished = output_manager_handle_finished,
|
||||
};
|
||||
|
||||
static void registry_handle_global(void *data, struct wl_registry *registry,
|
||||
uint32_t name, const char *interface, uint32_t version) {
|
||||
struct kanshi_state *state = data;
|
||||
|
||||
if (strcmp(interface, zwlr_output_manager_v1_interface.name) == 0) {
|
||||
state->output_manager = wl_registry_bind(registry, name,
|
||||
&zwlr_output_manager_v1_interface, 1);
|
||||
zwlr_output_manager_v1_add_listener(state->output_manager,
|
||||
&output_manager_listener, state);
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_handle_global_remove(void *data,
|
||||
struct wl_registry *registry, uint32_t name) {
|
||||
// This space is intentionally left blank
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener registry_listener = {
|
||||
.global = registry_handle_global,
|
||||
.global_remove = registry_handle_global_remove,
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char config_filename[] = "kanshi/config";
|
||||
@ -25,5 +216,31 @@ int main(int argc, char *argv[]) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
struct wl_display *display = wl_display_connect(NULL);
|
||||
if (display == NULL) {
|
||||
fprintf(stderr, "failed to connect to display\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
struct kanshi_state state = {
|
||||
.running = true,
|
||||
};
|
||||
wl_list_init(&state.heads);
|
||||
|
||||
struct wl_registry *registry = wl_display_get_registry(display);
|
||||
wl_registry_add_listener(registry, ®istry_listener, &state);
|
||||
wl_display_dispatch(display);
|
||||
wl_display_roundtrip(display);
|
||||
|
||||
if (state.output_manager == NULL) {
|
||||
fprintf(stderr, "compositor doesn't support "
|
||||
"wlr-output-management-unstable-v1\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
while (state.running && wl_display_dispatch(display) != -1) {
|
||||
// This space intentionally left blank
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ add_project_arguments(cc.get_supported_arguments([
|
||||
|
||||
wayland_client = dependency('wayland-client')
|
||||
|
||||
kanshi_inc = include_directories('include')
|
||||
subdir('protocol')
|
||||
|
||||
executable(
|
||||
meson.project_name(),
|
||||
@ -44,7 +44,7 @@ executable(
|
||||
'main.c',
|
||||
'parser.c',
|
||||
),
|
||||
include_directories: kanshi_inc,
|
||||
dependencies: [wayland_client],
|
||||
include_directories: include_directories('include'),
|
||||
dependencies: [wayland_client, client_protos],
|
||||
install: true,
|
||||
)
|
||||
|
37
protocol/meson.build
Normal file
37
protocol/meson.build
Normal file
@ -0,0 +1,37 @@
|
||||
wayland_scanner = find_program('wayland-scanner')
|
||||
|
||||
wayland_scanner_code = generator(
|
||||
wayland_scanner,
|
||||
output: '@BASENAME@-protocol.c',
|
||||
arguments: ['private-code', '@INPUT@', '@OUTPUT@'],
|
||||
)
|
||||
|
||||
wayland_scanner_client = generator(
|
||||
wayland_scanner,
|
||||
output: '@BASENAME@-client-protocol.h',
|
||||
arguments: ['client-header', '@INPUT@', '@OUTPUT@'],
|
||||
)
|
||||
|
||||
client_protocols = [
|
||||
['wlr-output-management-unstable-v1.xml'],
|
||||
]
|
||||
|
||||
client_protos_src = []
|
||||
client_protos_headers = []
|
||||
|
||||
foreach p : client_protocols
|
||||
xml = join_paths(p)
|
||||
client_protos_src += wayland_scanner_code.process(xml)
|
||||
client_protos_headers += wayland_scanner_client.process(xml)
|
||||
endforeach
|
||||
|
||||
lib_client_protos = static_library(
|
||||
'client_protos',
|
||||
client_protos_src + client_protos_headers,
|
||||
dependencies: [wayland_client]
|
||||
)
|
||||
|
||||
client_protos = declare_dependency(
|
||||
link_with: lib_client_protos,
|
||||
sources: client_protos_headers,
|
||||
)
|
483
protocol/wlr-output-management-unstable-v1.xml
Normal file
483
protocol/wlr-output-management-unstable-v1.xml
Normal file
@ -0,0 +1,483 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="wlr_output_management_unstable_v1">
|
||||
<copyright>
|
||||
Copyright © 2019 Purism SPC
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that copyright notice and this permission
|
||||
notice appear in supporting documentation, and that the name of
|
||||
the copyright holders not be used in advertising or publicity
|
||||
pertaining to distribution of the software without specific,
|
||||
written prior permission. The copyright holders make no
|
||||
representations about the suitability of this software for any
|
||||
purpose. It is provided "as is" without express or implied
|
||||
warranty.
|
||||
|
||||
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
</copyright>
|
||||
|
||||
<description summary="protocol to configure output devices">
|
||||
This protocol exposes interfaces to obtain and modify output device
|
||||
configuration.
|
||||
|
||||
Warning! The protocol described in this file is experimental and
|
||||
backward incompatible changes may be made. Backward compatible changes
|
||||
may be added together with the corresponding interface version bump.
|
||||
Backward incompatible changes are done by bumping the version number in
|
||||
the protocol and interface names and resetting the interface version.
|
||||
Once the protocol is to be declared stable, the 'z' prefix and the
|
||||
version number in the protocol and interface names are removed and the
|
||||
interface version number is reset.
|
||||
</description>
|
||||
|
||||
<interface name="zwlr_output_manager_v1" version="1">
|
||||
<description summary="output device configuration manager">
|
||||
This interface is a manager that allows reading and writing the current
|
||||
output device configuration.
|
||||
|
||||
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 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.
|
||||
|
||||
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 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
|
||||
output property advertisement protocol for regular clients. Instead,
|
||||
protocols such as xdg-output should be used.
|
||||
</description>
|
||||
|
||||
<event name="head">
|
||||
<description summary="introduce 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>
|
||||
|
||||
<event name="done">
|
||||
<description summary="sent all information about current configuration">
|
||||
This event is sent after all information has been sent after binding to
|
||||
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. 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.
|
||||
|
||||
A serial is sent to be used in a future create_configuration request.
|
||||
</description>
|
||||
<arg name="serial" type="uint" summary="current configuration serial"/>
|
||||
</event>
|
||||
|
||||
<request name="create_configuration">
|
||||
<description summary="create a new output configuration object">
|
||||
Create a new output configuration object. This allows to update head
|
||||
properties.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_output_configuration_v1"/>
|
||||
<arg name="serial" type="uint"/>
|
||||
</request>
|
||||
|
||||
<request name="stop">
|
||||
<description summary="stop sending events">
|
||||
Indicates the client no longer wishes to receive events for output
|
||||
configuration changes. However the compositor may emit further events,
|
||||
until the finished event is emitted.
|
||||
|
||||
The client must not send any more requests after this one.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="finished">
|
||||
<description summary="the compositor has finished with the manager">
|
||||
This event indicates that the compositor is done sending manager events.
|
||||
The compositor will destroy the object immediately after sending this
|
||||
event, so it will become invalid and the client should release any
|
||||
resources associated with it.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_head_v1" version="1">
|
||||
<description summary="output device">
|
||||
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: modes, name, description and
|
||||
physical_size. These cannot be changed by clients.
|
||||
|
||||
Other properties can be updated via a wlr_output_configuration object.
|
||||
|
||||
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="name">
|
||||
<description summary="head name">
|
||||
This event describes the head name.
|
||||
|
||||
The naming convention is compositor defined, but limited to alphanumeric
|
||||
characters and dashes (-). Each name is unique among all wlr_output_head
|
||||
objects, but if a wlr_output_head object is destroyed the same name may
|
||||
be reused later. The names will also remain consistent across sessions
|
||||
with the same hardware and software configuration.
|
||||
|
||||
Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc. However, do
|
||||
not assume that the name is a reflection of an underlying DRM
|
||||
connector, X11 connection, etc.
|
||||
|
||||
If the compositor implements the xdg-output protocol and this head is
|
||||
enabled, the xdg_output.name event must report the same name.
|
||||
|
||||
The name event is sent after a wlr_output_head object is created. This
|
||||
event is only sent once per object, and the name does not change over
|
||||
the lifetime of the wlr_output_head object.
|
||||
</description>
|
||||
<arg name="name" type="string"/>
|
||||
</event>
|
||||
|
||||
<event name="description">
|
||||
<description summary="head description">
|
||||
This event describes a human-readable description of the head.
|
||||
|
||||
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'. 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.
|
||||
|
||||
The description event is sent after a wlr_output_head object is created.
|
||||
This event is only sent once per object, and the description does not
|
||||
change over the lifetime of the wlr_output_head object.
|
||||
</description>
|
||||
<arg name="description" type="string"/>
|
||||
</event>
|
||||
|
||||
<event name="physical_size">
|
||||
<description summary="head physical size">
|
||||
This event describes the physical size of the head. This event is only
|
||||
sent if the head has a physical size (e.g. is not a projector or a
|
||||
virtual device).
|
||||
</description>
|
||||
<arg name="width" type="int" summary="width in millimeters of the output"/>
|
||||
<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
|
||||
mapped to a region of the global compositor space.
|
||||
|
||||
When a head is disabled, some properties (current_mode, position,
|
||||
transform and scale) are irrelevant.
|
||||
</description>
|
||||
<arg name="enabled" type="int" summary="zero if disabled, non-zero if enabled"/>
|
||||
</event>
|
||||
|
||||
<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.
|
||||
</description>
|
||||
<arg name="mode" type="object" interface="zwlr_output_mode_v1"/>
|
||||
</event>
|
||||
|
||||
<event name="position">
|
||||
<description summary="current position">
|
||||
This events describes the position of the head in the global compositor
|
||||
space. It is only sent if the output is enabled.
|
||||
</description>
|
||||
<arg name="x" type="int"
|
||||
summary="x position within the global compositor space"/>
|
||||
<arg name="y" type="int"
|
||||
summary="y position within the global compositor space"/>
|
||||
</event>
|
||||
|
||||
<event name="transform">
|
||||
<description summary="current transformation">
|
||||
This event describes the transformation currently applied to the head.
|
||||
It is only sent if the output is enabled.
|
||||
</description>
|
||||
<arg name="transform" type="int" enum="wl_output.transform"/>
|
||||
</event>
|
||||
|
||||
<event name="scale">
|
||||
<description summary="current scale">
|
||||
This events describes the scale of the head in the global compositor
|
||||
space. It is only sent if the output is enabled.
|
||||
</description>
|
||||
<arg name="scale" type="fixed"/>
|
||||
</event>
|
||||
|
||||
<event name="finished">
|
||||
<description summary="the head has been destroyed">
|
||||
The compositor will destroy the object immediately after sending this
|
||||
event, so it will become invalid and the client should release any
|
||||
resources associated with it.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_mode_v1" version="1">
|
||||
<description summary="output mode">
|
||||
This object describes an output mode.
|
||||
|
||||
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">
|
||||
<description summary="mode size">
|
||||
This event describes the mode size. The size is given in physical
|
||||
hardware units of the output device. This is not necessarily the same as
|
||||
the output size in the global compositor space. For instance, the output
|
||||
may be scaled or transformed.
|
||||
</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"/>
|
||||
</event>
|
||||
|
||||
<event name="refresh">
|
||||
<description summary="mode refresh rate">
|
||||
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>
|
||||
|
||||
<event name="preferred">
|
||||
<description summary="mode is preferred">
|
||||
This event advertises this mode as preferred.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="finished">
|
||||
<description summary="the mode has been destroyed">
|
||||
The compositor will destroy the object immediately after sending this
|
||||
event, so it will become invalid and the client should release any
|
||||
resources associated with it.
|
||||
</description>
|
||||
</event>
|
||||
</interface>
|
||||
|
||||
<interface name="zwlr_output_configuration_v1" version="1">
|
||||
<description summary="output configuration">
|
||||
This object is used by the client to describe a full output configuration.
|
||||
|
||||
First, the client needs to setup the output configuration. Each head can
|
||||
be either enabled (and configured) or disabled. It is a protocol error to
|
||||
send two enable_head or disable_head requests with the same head. It is a
|
||||
protocol error to omit a head in a configuration.
|
||||
|
||||
Then, the client can apply or test the configuration. The compositor will
|
||||
then reply with a succeeded, failed or cancelled event. Finally the client
|
||||
should destroy the configuration object.
|
||||
</description>
|
||||
|
||||
<enum name="error">
|
||||
<entry name="already_configured_head" value="1"
|
||||
summary="head has been configured twice"/>
|
||||
<entry name="unconfigured_head" value="2"
|
||||
summary="head has not been configured"/>
|
||||
<entry name="already_used" value="3"
|
||||
summary="request sent after configuration has been applied or tested"/>
|
||||
</enum>
|
||||
|
||||
<request name="enable_head">
|
||||
<description summary="enable and configure a head">
|
||||
Enable a head. This request creates a head configuration object that can
|
||||
be used to change the head's properties.
|
||||
</description>
|
||||
<arg name="id" type="new_id" interface="zwlr_output_configuration_head_v1"
|
||||
summary="a new object to configure the head"/>
|
||||
<arg name="head" type="object" interface="zwlr_output_head_v1"
|
||||
summary="the head to be enabled"/>
|
||||
</request>
|
||||
|
||||
<request name="disable_head">
|
||||
<description summary="disable a head">
|
||||
Disable a head.
|
||||
</description>
|
||||
<arg name="head" type="object" interface="zwlr_output_head_v1"
|
||||
summary="the head to be disabled"/>
|
||||
</request>
|
||||
|
||||
<request name="apply">
|
||||
<description summary="apply the configuration">
|
||||
Apply the new output configuration.
|
||||
|
||||
In case the configuration is successfully applied, there is no guarantee
|
||||
that the new output state matches completely the requested
|
||||
configuration. For instance, a compositor might round the scale if it
|
||||
doesn't support fractional scaling.
|
||||
|
||||
After this request has been sent, the compositor must respond with an
|
||||
succeeded, failed or cancelled event. Sending a request that isn't the
|
||||
destructor is a protocol error.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<request name="test">
|
||||
<description summary="test the configuration">
|
||||
Test the new output configuration. The configuration won't be applied,
|
||||
but will only be validated.
|
||||
|
||||
Even if the compositor succeeds to test a configuration, applying it may
|
||||
fail.
|
||||
|
||||
After this request has been sent, the compositor must respond with an
|
||||
succeeded, failed or cancelled event. Sending a request that isn't the
|
||||
destructor is a protocol error.
|
||||
</description>
|
||||
</request>
|
||||
|
||||
<event name="succeeded">
|
||||
<description summary="configuration changes succeeded">
|
||||
Sent after the compositor has successfully applied the changes or
|
||||
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>
|
||||
|
||||
<event name="failed">
|
||||
<description summary="configuration changes failed">
|
||||
Sent if the compositor rejects the changes or failed to apply them. The
|
||||
compositor should revert any changes made by the apply request that
|
||||
triggered this event.
|
||||
|
||||
Upon receiving this event, the client should destroy this object.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<event name="cancelled">
|
||||
<description summary="configuration has been cancelled">
|
||||
Sent if the compositor cancels the configuration because the state of an
|
||||
output changed and the client has outdated information (e.g. after an
|
||||
output has been hotplugged).
|
||||
|
||||
The client can create a new configuration with a newer serial and try
|
||||
again.
|
||||
|
||||
Upon receiving this event, the client should destroy this object.
|
||||
</description>
|
||||
</event>
|
||||
|
||||
<request name="destroy" type="destructor">
|
||||
<description summary="destroy the output configuration">
|
||||
Using this request a client can tell the compositor that it is not going
|
||||
to use the configuration object anymore. Any changes to the outputs
|
||||
that have not been applied will be discarded.
|
||||
|
||||
This request also destroys wlr_output_configuration_head objects created
|
||||
via this object.
|
||||
</description>
|
||||
</request>
|
||||
</interface>
|
||||
|
||||
<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="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">
|
||||
<description summary="set the mode">
|
||||
This request sets the head's mode.
|
||||
</description>
|
||||
<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.
|
||||
</description>
|
||||
<arg name="x" type="int" summary="x position in the global compositor space"/>
|
||||
<arg name="y" type="int" summary="y position in the global compositor space"/>
|
||||
</request>
|
||||
|
||||
<request name="set_transform">
|
||||
<description summary="set the transform">
|
||||
This request sets the head's transform.
|
||||
</description>
|
||||
<arg name="transform" type="int" enum="wl_output.transform"/>
|
||||
</request>
|
||||
|
||||
<request name="set_scale">
|
||||
<description summary="set the scale">
|
||||
This request sets the head's scale.
|
||||
</description>
|
||||
<arg name="scale" type="fixed"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
Loading…
Reference in New Issue
Block a user