diff --git a/include/wlr/types/wlr_output_management_v1.h b/include/wlr/types/wlr_output_management_v1.h index 1104c938..4d449601 100644 --- a/include/wlr/types/wlr_output_management_v1.h +++ b/include/wlr/types/wlr_output_management_v1.h @@ -22,8 +22,19 @@ struct wlr_output_manager_v1 { uint32_t serial; struct { + /** + * The `apply` and `test` events are emitted when a client requests a + * configuration to be applied or tested. The compositor should send + * feedback with `wlr_output_configuration_v1_send_succeeded` xor + * `wlr_output_configuration_v1_send_failed`. + * + * The compositor gains ownership over the configuration (passed as the + * event data). That is, the compositor is responsible for destroying + * the configuration. + */ struct wl_signal apply; // wlr_output_configuration_v1 struct wl_signal test; // wlr_output_configuration_v1 + struct wl_signal destroy; } events; @@ -79,20 +90,52 @@ struct wlr_output_configuration_head_v1 { struct wl_listener output_destroy; }; +/** + * Create a new output manager. The compositor is responsible for calling + * `wlr_output_manager_v1_set_configuration` whenever the current output + * configuration changes. + */ struct wlr_output_manager_v1 *wlr_output_manager_v1_create( struct wl_display *display); +/** + * Updates the output manager's current configuration. This will broadcast any + * changes to all clients. + * + * This function takes ownership over `config`. That is, the compositor must not + * access the configuration anymore. + */ void wlr_output_manager_v1_set_configuration( struct wlr_output_manager_v1 *manager, struct wlr_output_configuration_v1 *config); +/** + * Create a new, empty output configuration. Compositors should add current head + * status with `wlr_output_configuration_head_v1_create`. They can then call + * `wlr_output_manager_v1_set_configuration`. + */ struct wlr_output_configuration_v1 *wlr_output_configuration_v1_create(void); void wlr_output_configuration_v1_destroy( struct wlr_output_configuration_v1 *config); +/** + * If the configuration comes from a client request, this sends positive + * feedback to the client (configuration has been applied). + */ void wlr_output_configuration_v1_send_succeeded( struct wlr_output_configuration_v1 *config); +/** + * If the configuration comes from a client request, this sends negative + * feedback to the client (configuration has not been applied). + */ void wlr_output_configuration_v1_send_failed( struct wlr_output_configuration_v1 *config); +/** + * Create a new configuration head for the given output. This adds the head to + * the provided output configuration. + * + * The configuration head will be pre-filled with data from `output`. The + * compositor should adjust this data according to its current internal state. + */ struct wlr_output_configuration_head_v1 * wlr_output_configuration_head_v1_create( struct wlr_output_configuration_v1 *config, struct wlr_output *output); diff --git a/types/wlr_output_management_v1.c b/types/wlr_output_management_v1.c index 8864e01d..9c78a7f2 100644 --- a/types/wlr_output_management_v1.c +++ b/types/wlr_output_management_v1.c @@ -148,6 +148,8 @@ static void config_head_handle_set_mode(struct wl_client *client, return; } + // Mode can be NULL if the output doesn't support modes (in which case we + // expose only one "virtual" mode, the current mode) struct wlr_output_mode *mode = mode_from_resource(mode_resource); struct wlr_output *output = config_head->state.output; @@ -272,6 +274,8 @@ static struct wlr_output_configuration_v1 *config_from_resource( return wl_resource_get_user_data(resource); } +// Checks that the head is unconfigured (ie. no enable_head/disable_head request +// has yet been sent for this head), if not sends a protocol error. static bool config_check_head_is_unconfigured( struct wlr_output_configuration_v1 *config, struct wlr_output *output) { struct wlr_output_configuration_head_v1 *head; @@ -358,6 +362,8 @@ static void config_handle_disable_head(struct wl_client *client, config_head->state.enabled = false; } +// Finalizes a configuration. This prevents the same config from being used +// multiple times. static void config_finalize(struct wlr_output_configuration_v1 *config) { if (config->finalized) { return; @@ -668,6 +674,7 @@ static struct wl_resource *head_send_mode(struct wlr_output_head_v1 *head, return mode_resource; } +// Sends new head state to a client. 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); @@ -690,8 +697,10 @@ static void head_send_state(struct wlr_output_head_v1 *head, break; } } + assert(found); if (head->state.mode == NULL) { + // Fake a single output mode if output doesn't support modes struct wlr_output_mode virtual_mode = { .width = head->state.custom_mode.width, .height = head->state.custom_mode.height, @@ -700,7 +709,6 @@ static void head_send_state(struct wlr_output_head_v1 *head, send_mode_state(mode_resource, &virtual_mode); } - assert(found); zwlr_output_head_v1_send_current_mode(head_resource, mode_resource); } @@ -767,6 +775,8 @@ static void manager_send_head(struct wlr_output_manager_v1 *manager, head_send_state(head, head_resource, HEAD_STATE_ALL); } +// Compute state that has changed and sends it to all clients. Then writes the +// new state to the head. static bool manager_update_head(struct wlr_output_manager_v1 *manager, struct wlr_output_head_v1 *head, struct wlr_output_head_v1_state *next) {