diff --git a/include/wlr/types/wlr_output_management_v1.h b/include/wlr/types/wlr_output_management_v1.h index 2835a5924..723696e9b 100644 --- a/include/wlr/types/wlr_output_management_v1.h +++ b/include/wlr/types/wlr_output_management_v1.h @@ -55,7 +55,7 @@ struct wlr_output_head_v1_state { int32_t width, height; int32_t refresh; } custom_mode; - int32_t x, y; + int32_t x, y, width, height; enum wl_output_transform transform; float scale; bool adaptive_sync_enabled; diff --git a/protocol/wlr-output-management-unstable-v1.xml b/protocol/wlr-output-management-unstable-v1.xml index 541284a8c..34e9dda5f 100644 --- a/protocol/wlr-output-management-unstable-v1.xml +++ b/protocol/wlr-output-management-unstable-v1.xml @@ -39,7 +39,7 @@ interface version number is reset. - + This interface is a manager that allows reading and writing the current output device configuration. @@ -125,7 +125,7 @@ - + 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 @@ -140,6 +140,11 @@ 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. + + The viewport indicates the logical size taken by the output in the global + compositor space. If the viewport aspect ratio doesn't match the current + mode aspect ratio, the compositor should letter-box the output with black + borders. @@ -229,7 +234,7 @@ - This events describes the position of the head in the global compositor + This event describes the position of the head in the global compositor space. It is only sent if the output is enabled. This events describes the scale of the head in the global compositor space. It is only sent if the output is enabled. + + Starting from version 5, this event is deprecated: the viewport event + should be used instead. @@ -364,9 +372,20 @@ + + + + + + This event describes the size of the head in the global compositor + space. It is only sent if the output is enabled. + + + + - + This object describes an output mode. @@ -421,7 +440,7 @@ - + This object is used by the client to describe a full output configuration. @@ -539,7 +558,7 @@ - + This object is used by the client to update a single head's configuration. @@ -554,6 +573,7 @@ + @@ -594,6 +614,9 @@ This request sets the head's scale. + + Starting from version 5, this request is deprecated: clients should use + set_viewport instead. @@ -607,5 +630,17 @@ + + + + + + This request sets the head's viewport. + + This overrides the set_scale request, if any was sent. + + + + diff --git a/types/wlr_output_management_v1.c b/types/wlr_output_management_v1.c index 910bcbe5e..c92105008 100644 --- a/types/wlr_output_management_v1.c +++ b/types/wlr_output_management_v1.c @@ -6,7 +6,7 @@ #include #include "wlr-output-management-unstable-v1-protocol.h" -#define OUTPUT_MANAGER_VERSION 4 +#define OUTPUT_MANAGER_VERSION 5 enum { HEAD_STATE_ENABLED = 1 << 0, @@ -15,11 +15,12 @@ enum { HEAD_STATE_TRANSFORM = 1 << 3, HEAD_STATE_SCALE = 1 << 4, HEAD_STATE_ADAPTIVE_SYNC = 1 << 5, + HEAD_STATE_VIEWPORT = 1 << 6, }; static const uint32_t HEAD_STATE_ALL = HEAD_STATE_ENABLED | HEAD_STATE_MODE | HEAD_STATE_POSITION | HEAD_STATE_TRANSFORM | HEAD_STATE_SCALE | - HEAD_STATE_ADAPTIVE_SYNC; + HEAD_STATE_ADAPTIVE_SYNC | HEAD_STATE_VIEWPORT; static const struct zwlr_output_head_v1_interface head_impl; @@ -162,6 +163,8 @@ struct wlr_output_configuration_head_v1 * config_head->state.scale = output->scale; config_head->state.adaptive_sync_enabled = output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED; + config_head->state.width = output->width * output->scale; + config_head->state.height = output->height * output->scale; return config_head; } @@ -307,6 +310,26 @@ static void config_head_handle_set_adaptive_sync(struct wl_client *client, } } +static void config_head_handle_set_viewport(struct wl_client *client, + struct wl_resource *config_head_resource, + int32_t width, int32_t height) { + 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) { + wl_resource_post_error(config_head_resource, + ZWLR_OUTPUT_CONFIGURATION_HEAD_V1_ERROR_INVALID_VIEWPORT, + "invalid viewport"); + return; + } + + config_head->state.width = width; + config_head->state.height = height; +} + 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, @@ -314,6 +337,7 @@ static const struct zwlr_output_configuration_head_v1_interface config_head_impl .set_transform = config_head_handle_set_transform, .set_scale = config_head_handle_set_scale, .set_adaptive_sync = config_head_handle_set_adaptive_sync, + .set_viewport = config_head_handle_set_viewport, }; static void config_head_handle_resource_destroy(struct wl_resource *resource) { @@ -752,6 +776,7 @@ static struct wl_resource *head_send_mode(struct wlr_output_head_v1 *head, static void head_send_state(struct wlr_output_head_v1 *head, struct wl_resource *head_resource, uint32_t state) { struct wl_client *client = wl_resource_get_client(head_resource); + uint32_t version = wl_resource_get_version(head_resource); if (state & HEAD_STATE_ENABLED) { zwlr_output_head_v1_send_enabled(head_resource, head->state.enabled); @@ -805,8 +830,7 @@ static void head_send_state(struct wlr_output_head_v1 *head, } if ((state & HEAD_STATE_ADAPTIVE_SYNC) && - wl_resource_get_version(head_resource) >= - ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_SINCE_VERSION) { + version >= ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_SINCE_VERSION) { if (head->state.adaptive_sync_enabled) { zwlr_output_head_v1_send_adaptive_sync(head_resource, ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_ENABLED); @@ -815,6 +839,12 @@ static void head_send_state(struct wlr_output_head_v1 *head, ZWLR_OUTPUT_HEAD_V1_ADAPTIVE_SYNC_STATE_DISABLED); } } + + if ((state & HEAD_STATE_VIEWPORT) && + version >= ZWLR_OUTPUT_HEAD_V1_VIEWPORT_SINCE_VERSION) { + zwlr_output_head_v1_send_viewport(head_resource, + head->state.width, head->state.height); + } } static void head_handle_resource_destroy(struct wl_resource *resource) { @@ -911,6 +941,9 @@ static bool manager_update_head(struct wlr_output_manager_v1 *manager, if (current->adaptive_sync_enabled != next->adaptive_sync_enabled) { state |= HEAD_STATE_ADAPTIVE_SYNC; } + if (current->width != next->width || current->height != next->height) { + state |= HEAD_STATE_VIEWPORT; + } // If a mode was added to wlr_output.modes we need to add the new mode // to the wlr_output_head