output-management-v1: add support for position, transform and scale

This commit is contained in:
emersion 2019-03-08 17:28:47 +01:00 committed by Drew DeVault
parent ee77a65fe3
commit d71ebde545
2 changed files with 57 additions and 14 deletions

View file

@ -37,6 +37,9 @@ struct wlr_output_head_v1_state {
bool enabled; bool enabled;
struct wlr_output_mode *mode; struct wlr_output_mode *mode;
int32_t x, y;
enum wl_output_transform transform;
double scale;
}; };
struct wlr_output_head_v1 { struct wlr_output_head_v1 {

View file

@ -10,12 +10,14 @@
enum { enum {
HEAD_STATE_ENABLED = 1 << 0, HEAD_STATE_ENABLED = 1 << 0,
HEAD_STATE_MODE = 2 << 0, HEAD_STATE_MODE = 1 << 1,
// TODO: other properties HEAD_STATE_POSITION = 1 << 2,
HEAD_STATE_TRANSFORM = 1 << 3,
HEAD_STATE_SCALE = 1 << 4,
}; };
static const uint32_t HEAD_STATE_ALL = static const uint32_t HEAD_STATE_ALL = HEAD_STATE_ENABLED | HEAD_STATE_MODE |
HEAD_STATE_ENABLED | HEAD_STATE_MODE; HEAD_STATE_POSITION | HEAD_STATE_TRANSFORM | HEAD_STATE_SCALE;
// Can return NULL if the head is inert // Can return NULL if the head is inert
@ -117,7 +119,10 @@ struct wlr_output_configuration_head_v1 *
config_head_create(config, output); config_head_create(config, output);
config_head->state.enabled = output->enabled; config_head->state.enabled = output->enabled;
config_head->state.mode = output->current_mode; config_head->state.mode = output->current_mode;
// TODO: other properties config_head->state.x = output->lx;
config_head->state.y = output->ly;
config_head->state.transform = output->transform;
config_head->state.scale = output->scale;
return config_head; return config_head;
} }
@ -521,7 +526,20 @@ static void head_send_state(struct wlr_output_head_v1 *head,
zwlr_output_head_v1_send_current_mode(head_resource, mode_resource); zwlr_output_head_v1_send_current_mode(head_resource, mode_resource);
} }
// TODO: send other properties if (state & HEAD_STATE_POSITION) {
zwlr_output_head_v1_send_position(head_resource,
head->state.x, head->state.y);
}
if (state & HEAD_STATE_TRANSFORM) {
zwlr_output_head_v1_send_transform(head_resource,
head->state.transform);
}
if (state & HEAD_STATE_SCALE) {
zwlr_output_head_v1_send_scale(head_resource,
wl_fixed_from_double(head->state.scale));
}
} }
static void head_handle_resource_destroy(struct wl_resource *resource) { static void head_handle_resource_destroy(struct wl_resource *resource) {
@ -586,7 +604,7 @@ static void manager_send_head(struct wlr_output_manager_v1 *manager,
head_send_state(head, head_resource, HEAD_STATE_ALL); head_send_state(head, head_resource, HEAD_STATE_ALL);
} }
static void manager_update_head(struct wlr_output_manager_v1 *manager, static bool manager_update_head(struct wlr_output_manager_v1 *manager,
struct wlr_output_head_v1 *head, struct wlr_output_head_v1 *head,
struct wlr_output_head_v1_state *next) { struct wlr_output_head_v1_state *next) {
struct wlr_output_head_v1_state *current = &head->state; struct wlr_output_head_v1_state *current = &head->state;
@ -594,33 +612,49 @@ static void manager_update_head(struct wlr_output_manager_v1 *manager,
uint32_t state = 0; uint32_t state = 0;
if (current->enabled != next->enabled) { if (current->enabled != next->enabled) {
state |= HEAD_STATE_ENABLED; state |= HEAD_STATE_ENABLED;
current->enabled = next->enabled;
} }
if (current->mode != next->mode) { if (current->mode != next->mode) {
state |= HEAD_STATE_MODE; state |= HEAD_STATE_MODE;
current->mode = next->mode;
} }
// TODO: update other properties if (current->x != next->x || current->y != next->y) {
state |= HEAD_STATE_POSITION;
}
if (current->transform != next->transform) {
state |= HEAD_STATE_TRANSFORM;
}
if (current->scale != next->scale) {
state |= HEAD_STATE_SCALE;
}
struct wl_resource *resource; if (state != 0) {
wl_resource_for_each(resource, &head->resources) { *current = *next;
head_send_state(head, resource, state);
struct wl_resource *resource;
wl_resource_for_each(resource, &head->resources) {
head_send_state(head, resource, state);
}
} }
return state != 0;
} }
void wlr_output_manager_v1_set_configuration( void wlr_output_manager_v1_set_configuration(
struct wlr_output_manager_v1 *manager, struct wlr_output_manager_v1 *manager,
struct wlr_output_configuration_v1 *config) { struct wlr_output_configuration_v1 *config) {
bool changed = false;
// Either update or destroy existing heads // Either update or destroy existing heads
struct wlr_output_head_v1 *existing_head, *head_tmp; struct wlr_output_head_v1 *existing_head, *head_tmp;
wl_list_for_each_safe(existing_head, head_tmp, &manager->heads, link) { wl_list_for_each_safe(existing_head, head_tmp, &manager->heads, link) {
struct wlr_output_configuration_head_v1 *updated_head = struct wlr_output_configuration_head_v1 *updated_head =
configuration_get_head(config, existing_head->state.output); configuration_get_head(config, existing_head->state.output);
if (updated_head != NULL) { if (updated_head != NULL) {
manager_update_head(manager, existing_head, &updated_head->state); changed |= manager_update_head(manager,
existing_head, &updated_head->state);
config_head_destroy(updated_head); config_head_destroy(updated_head);
} else { } else {
head_destroy(existing_head); head_destroy(existing_head);
changed = true;
} }
} }
@ -642,10 +676,16 @@ void wlr_output_manager_v1_set_configuration(
wl_resource_for_each(manager_resource, &manager->resources) { wl_resource_for_each(manager_resource, &manager->resources) {
manager_send_head(manager, head, manager_resource); manager_send_head(manager, head, manager_resource);
} }
changed = true;
} }
wlr_output_configuration_v1_destroy(config); wlr_output_configuration_v1_destroy(config);
if (!changed) {
return;
}
manager->serial = wl_display_next_serial(manager->display); manager->serial = wl_display_next_serial(manager->display);
struct wl_resource *manager_resource; struct wl_resource *manager_resource;
wl_resource_for_each(manager_resource, &manager->resources) { wl_resource_for_each(manager_resource, &manager->resources) {