From 822a9f65a4f965a7561de287013c2a5c159453ab Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Sat, 21 Oct 2017 17:37:25 +1300 Subject: Add pointer to backend inside wlr_output --- include/wlr/interfaces/wlr_output.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/wlr/interfaces/wlr_output.h') diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index b7927569..17dd5538 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -1,8 +1,9 @@ #ifndef WLR_INTERFACES_WLR_OUTPUT_H #define WLR_INTERFACES_WLR_OUTPUT_H -#include #include +#include +#include struct wlr_output_impl { void (*enable)(struct wlr_output *output, bool enable); @@ -21,7 +22,8 @@ struct wlr_output_impl { uint16_t (*get_gamma_size)(struct wlr_output *output); }; -void wlr_output_init(struct wlr_output *output, const struct wlr_output_impl *impl); +void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, + const struct wlr_output_impl *impl); void wlr_output_free(struct wlr_output *output); void wlr_output_update_matrix(struct wlr_output *output); struct wl_global *wlr_output_create_global( -- cgit v1.2.3 From e1d213fccdae068ecc0f11f4321dfd6528163253 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 22 Oct 2017 22:21:23 +0200 Subject: Create globals only for enabled outputs in DRM backend --- backend/drm/drm.c | 7 ++++--- examples/screenshot.c | 4 ---- include/wlr/interfaces/wlr_output.h | 5 +++-- types/wlr_output.c | 31 ++++++++++++++++++++++++------- 4 files changed, 31 insertions(+), 16 deletions(-) (limited to 'include/wlr/interfaces/wlr_output.h') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 51a5f636..8f80e65c 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -748,7 +748,6 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { free(edid); wl_list_insert(&drm->outputs, &wlr_conn->link); - wlr_output_create_global(&wlr_conn->output, drm->display); wlr_log(L_INFO, "Found display '%s'", wlr_conn->output.name); } else { seen[index] = true; @@ -756,7 +755,6 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { if (wlr_conn->state == WLR_DRM_CONN_DISCONNECTED && drm_conn->connection == DRM_MODE_CONNECTED) { - wlr_log(L_INFO, "'%s' connected", wlr_conn->output.name); wlr_log(L_INFO, "Detected modes:"); @@ -778,14 +776,17 @@ void wlr_drm_scan_connectors(struct wlr_drm_backend *drm) { wl_list_insert(&wlr_conn->output.modes, &mode->wlr_mode.link); } + wlr_output_create_global(&wlr_conn->output, drm->display); + wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; wlr_log(L_INFO, "Sending modesetting signal for '%s'", wlr_conn->output.name); wl_signal_emit(&drm->backend.events.output_add, &wlr_conn->output); } else if (wlr_conn->state == WLR_DRM_CONN_CONNECTED && drm_conn->connection != DRM_MODE_CONNECTED) { - wlr_log(L_INFO, "'%s' disconnected", wlr_conn->output.name); + + wlr_output_destroy_global(&wlr_conn->output); wlr_drm_connector_cleanup(wlr_conn); } diff --git a/examples/screenshot.c b/examples/screenshot.c index 95af49ca..2a3b74aa 100644 --- a/examples/screenshot.c +++ b/examples/screenshot.c @@ -267,10 +267,6 @@ int main(int argc, char *argv[]) { struct screenshooter_output *output; wl_list_for_each(output, &output_list, link) { - if (output->width == 0 || output->height == 0) { - continue; - } - output->buffer = create_shm_buffer(output->width, output->height, &output->data); if (output->buffer == NULL) { return -1; diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 17dd5538..338d3375 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -26,7 +26,8 @@ void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, const struct wlr_output_impl *impl); void wlr_output_free(struct wlr_output *output); void wlr_output_update_matrix(struct wlr_output *output); -struct wl_global *wlr_output_create_global( - struct wlr_output *wlr_output, struct wl_display *display); +struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output, + struct wl_display *display); +void wlr_output_destroy_global(struct wlr_output *wlr_output); #endif diff --git a/types/wlr_output.c b/types/wlr_output.c index 611d4ad1..eb5bdd26 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -76,16 +76,20 @@ static void wl_output_bind(struct wl_client *wl_client, void *_wlr_output, struct wlr_output *wlr_output = _wlr_output; assert(wl_client && wlr_output); - struct wl_resource *wl_resource = wl_resource_create( - wl_client, &wl_output_interface, version, id); - wl_resource_set_implementation(wl_resource, &wl_output_impl, - wlr_output, wl_output_destroy); - wl_list_insert(&wlr_output->wl_resources, wl_resource_get_link(wl_resource)); + struct wl_resource *wl_resource = wl_resource_create(wl_client, + &wl_output_interface, version, id); + wl_resource_set_implementation(wl_resource, &wl_output_impl, wlr_output, + wl_output_destroy); + wl_list_insert(&wlr_output->wl_resources, + wl_resource_get_link(wl_resource)); wl_output_send_to_resource(wl_resource); } -struct wl_global *wlr_output_create_global( - struct wlr_output *wlr_output, struct wl_display *display) { +struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output, + struct wl_display *display) { + if (wlr_output->wl_global != NULL) { + return wlr_output->wl_global; + } struct wl_global *wl_global = wl_global_create(display, &wl_output_interface, 3, wlr_output, wl_output_bind); wlr_output->wl_global = wl_global; @@ -93,6 +97,19 @@ struct wl_global *wlr_output_create_global( return wl_global; } +void wlr_output_destroy_global(struct wlr_output *wlr_output) { + if (wlr_output->wl_global == NULL) { + return; + } + struct wl_resource *resource, *tmp; + wl_resource_for_each_safe(resource, tmp, &wlr_output->wl_resources) { + struct wl_list *link = wl_resource_get_link(resource); + wl_list_remove(link); + } + wl_global_destroy(wlr_output->wl_global); + wlr_output->wl_global = NULL; +} + void wlr_output_update_matrix(struct wlr_output *output) { wlr_matrix_texture(output->transform_matrix, output->width, output->height, output->transform); } -- cgit v1.2.3 From 1cc8f21d8e19df2d1cc43864ae5715fbb5fbbe21 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 22 Oct 2017 12:30:45 +0200 Subject: Cleanup wlr_gamma_control --- backend/drm/drm.c | 4 +- include/wlr/interfaces/wlr_output.h | 4 +- include/wlr/types/wlr_gamma_control.h | 16 ++++- include/wlr/types/wlr_output.h | 4 +- types/wlr_gamma_control.c | 121 +++++++++++++++++++++++++--------- types/wlr_output.c | 4 +- 6 files changed, 111 insertions(+), 42 deletions(-) (limited to 'include/wlr/interfaces/wlr_output.h') diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 8f80e65c..d0bdfcd5 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -211,13 +211,13 @@ static void wlr_drm_connector_swap_buffers(struct wlr_output *output) { } static void wlr_drm_connector_set_gamma(struct wlr_output *output, - uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) { + uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; drmModeCrtcSetGamma(drm->fd, conn->crtc->id, size, r, g, b); } -static uint16_t wlr_drm_connector_get_gamma_size(struct wlr_output *output) { +static uint32_t wlr_drm_connector_get_gamma_size(struct wlr_output *output) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; drmModeCrtc *crtc = conn->old_crtc; return crtc ? crtc->gamma_size : 0; diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 338d3375..636cc06c 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -18,8 +18,8 @@ struct wlr_output_impl { void (*make_current)(struct wlr_output *output); void (*swap_buffers)(struct wlr_output *output); void (*set_gamma)(struct wlr_output *output, - uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); - uint16_t (*get_gamma_size)(struct wlr_output *output); + uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b); + uint32_t (*get_gamma_size)(struct wlr_output *output); }; void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, diff --git a/include/wlr/types/wlr_gamma_control.h b/include/wlr/types/wlr_gamma_control.h index 96c9f545..59f18494 100644 --- a/include/wlr/types/wlr_gamma_control.h +++ b/include/wlr/types/wlr_gamma_control.h @@ -5,18 +5,28 @@ struct wlr_gamma_control_manager { struct wl_global *wl_global; + struct wl_list controls; // list of wlr_gamma_control void *data; }; struct wlr_gamma_control { struct wl_resource *resource; - struct wl_resource *output; + struct wlr_output *output; + struct wl_list link; + + struct wl_listener output_destroy_listener; + + struct { + struct wl_signal destroy; + } events; void* data; }; -struct wlr_gamma_control_manager *wlr_gamma_control_manager_create(struct wl_display *display); -void wlr_gamma_control_manager_destroy(struct wlr_gamma_control_manager *gamma_control_manager); +struct wlr_gamma_control_manager *wlr_gamma_control_manager_create( + struct wl_display *display); +void wlr_gamma_control_manager_destroy( + struct wlr_gamma_control_manager *gamma_control_manager); #endif diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index d8649bbb..74eb15ed 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -84,7 +84,7 @@ void wlr_output_effective_resolution(struct wlr_output *output, void wlr_output_make_current(struct wlr_output *output); void wlr_output_swap_buffers(struct wlr_output *output); void wlr_output_set_gamma(struct wlr_output *output, - uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b); -uint16_t wlr_output_get_gamma_size(struct wlr_output *output); + uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b); +uint32_t wlr_output_get_gamma_size(struct wlr_output *output); #endif diff --git a/types/wlr_gamma_control.c b/types/wlr_gamma_control.c index 973fd613..9d74e749 100644 --- a/types/wlr_gamma_control.c +++ b/types/wlr_gamma_control.c @@ -6,96 +6,155 @@ #include #include "gamma-control-protocol.h" -static void resource_destroy(struct wl_client *client, struct wl_resource *resource) { +static void resource_destroy(struct wl_client *client, + struct wl_resource *resource) { wl_resource_destroy(resource); } -static void gamma_control_destroy(struct wl_resource *resource) { - struct wlr_gamma_control *gamma_control = wl_resource_get_user_data(resource); +static void gamma_control_destroy(struct wlr_gamma_control *gamma_control) { + wl_signal_emit(&gamma_control->events.destroy, gamma_control); + wl_list_remove(&gamma_control->output_destroy_listener.link); + wl_resource_set_user_data(gamma_control->resource, NULL); free(gamma_control); } +static void gamma_control_destroy_resource(struct wl_resource *resource) { + struct wlr_gamma_control *gamma_control = + wl_resource_get_user_data(resource); + gamma_control_destroy(gamma_control); +} + +static void gamma_control_handle_output_destroy(struct wl_listener *listener, + void *data) { + struct wlr_gamma_control *gamma_control = + wl_container_of(listener, gamma_control, output_destroy_listener); + gamma_control_destroy(gamma_control); +} + static void gamma_control_set_gamma(struct wl_client *client, - struct wl_resource *_gamma_control, struct wl_array *red, + struct wl_resource *gamma_control_resource, struct wl_array *red, struct wl_array *green, struct wl_array *blue) { + struct wlr_gamma_control *gamma_control = + wl_resource_get_user_data(gamma_control_resource); + if (red->size != green->size || red->size != blue->size) { - wl_resource_post_error(_gamma_control, GAMMA_CONTROL_ERROR_INVALID_GAMMA, + wl_resource_post_error(gamma_control_resource, + GAMMA_CONTROL_ERROR_INVALID_GAMMA, "The gamma ramps don't have the same size"); return; } + + uint32_t size = red->size / sizeof(uint16_t); uint16_t *r = (uint16_t *)red->data; uint16_t *g = (uint16_t *)green->data; uint16_t *b = (uint16_t *)blue->data; - struct wlr_gamma_control *gamma_control = wl_resource_get_user_data(_gamma_control); - struct wlr_output *output = wl_resource_get_user_data(gamma_control->output); - wlr_output_set_gamma(output, red->size / sizeof(uint16_t), r, g, b); + + wlr_output_set_gamma(gamma_control->output, size, r, g, b); } static void gamma_control_reset_gamma(struct wl_client *client, - struct wl_resource *_gamma_control) { + struct wl_resource *gamma_control_resource) { // TODO } -static const struct gamma_control_interface gamma_control_implementation = { +static const struct gamma_control_interface gamma_control_impl = { .destroy = resource_destroy, .set_gamma = gamma_control_set_gamma, .reset_gamma = gamma_control_reset_gamma, }; static void gamma_control_manager_get_gamma_control(struct wl_client *client, - struct wl_resource *_gamma_control_manager, uint32_t id, - struct wl_resource *_output) { - //struct wlr_gamma_control_manager *gamma_control_manager = - // wl_resource_get_user_data(_gamma_control_manager); - struct wlr_output *output = wl_resource_get_user_data(_output); - struct wlr_gamma_control *gamma_control; - if (!(gamma_control = calloc(1, sizeof(struct wlr_gamma_control)))) { + struct wl_resource *gamma_control_manager_resource, uint32_t id, + struct wl_resource *output_resource) { + struct wlr_gamma_control_manager *gamma_control_manager = + wl_resource_get_user_data(gamma_control_manager_resource); + struct wlr_output *output = wl_resource_get_user_data(output_resource); + + struct wlr_gamma_control *gamma_control = + calloc(1, sizeof(struct wlr_gamma_control)); + if (gamma_control == NULL) { + wl_client_post_no_memory(client); return; } - gamma_control->output = _output; + gamma_control->output = output; + + int version = wl_resource_get_version(gamma_control_manager_resource); gamma_control->resource = wl_resource_create(client, - &gamma_control_interface, wl_resource_get_version(_gamma_control_manager), id); - wlr_log(L_DEBUG, "new gamma_control %p (res %p)", gamma_control, gamma_control->resource); + &gamma_control_interface, version, id); + if (gamma_control->resource == NULL) { + wl_client_post_no_memory(client); + free(gamma_control); + return; + } + wlr_log(L_DEBUG, "new gamma_control %p (res %p)", gamma_control, + gamma_control->resource); wl_resource_set_implementation(gamma_control->resource, - &gamma_control_implementation, gamma_control, gamma_control_destroy); - gamma_control_send_gamma_size(gamma_control->resource, wlr_output_get_gamma_size(output)); + &gamma_control_impl, gamma_control, gamma_control_destroy_resource); + + wl_signal_init(&gamma_control->events.destroy); + + wl_signal_add(&output->events.destroy, + &gamma_control->output_destroy_listener); + gamma_control->output_destroy_listener.notify = + gamma_control_handle_output_destroy; + + wl_list_insert(&gamma_control_manager->controls, &gamma_control->link); + + gamma_control_send_gamma_size(gamma_control->resource, + wlr_output_get_gamma_size(output)); } static struct gamma_control_manager_interface gamma_control_manager_impl = { .get_gamma_control = gamma_control_manager_get_gamma_control, }; -static void gamma_control_manager_bind(struct wl_client *wl_client, +static void gamma_control_manager_bind(struct wl_client *client, void *_gamma_control_manager, uint32_t version, uint32_t id) { - struct wlr_gamma_control_manager *gamma_control_manager = _gamma_control_manager; - assert(wl_client && gamma_control_manager); + struct wlr_gamma_control_manager *gamma_control_manager = + _gamma_control_manager; + assert(client && gamma_control_manager); - struct wl_resource *wl_resource = wl_resource_create( - wl_client, &gamma_control_manager_interface, version, id); - wl_resource_set_implementation(wl_resource, &gamma_control_manager_impl, + struct wl_resource *resource = wl_resource_create(client, + &gamma_control_manager_interface, version, id); + if (resource == NULL) { + wl_client_post_no_memory(client); + return; + } + wl_resource_set_implementation(resource, &gamma_control_manager_impl, gamma_control_manager, NULL); } -struct wlr_gamma_control_manager *wlr_gamma_control_manager_create(struct wl_display *display) { +struct wlr_gamma_control_manager *wlr_gamma_control_manager_create( + struct wl_display *display) { struct wlr_gamma_control_manager *gamma_control_manager = calloc(1, sizeof(struct wlr_gamma_control_manager)); if (!gamma_control_manager) { return NULL; } struct wl_global *wl_global = wl_global_create(display, - &gamma_control_manager_interface, 1, gamma_control_manager, gamma_control_manager_bind); + &gamma_control_manager_interface, 1, gamma_control_manager, + gamma_control_manager_bind); if (!wl_global) { free(gamma_control_manager); return NULL; } gamma_control_manager->wl_global = wl_global; + + wl_list_init(&gamma_control_manager->controls); + return gamma_control_manager; } -void wlr_gamma_control_manager_destroy(struct wlr_gamma_control_manager *gamma_control_manager) { +void wlr_gamma_control_manager_destroy( + struct wlr_gamma_control_manager *gamma_control_manager) { if (!gamma_control_manager) { return; } + struct wlr_gamma_control *gamma_control, *tmp; + wl_list_for_each_safe(gamma_control, tmp, &gamma_control_manager->controls, + link) { + gamma_control_destroy(gamma_control); + } // TODO: this segfault (wl_display->registry_resource_list is not init) // wl_global_destroy(gamma_control_manager->wl_global); free(gamma_control_manager); diff --git a/types/wlr_output.c b/types/wlr_output.c index eb5bdd26..a02798b2 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -404,13 +404,13 @@ void wlr_output_swap_buffers(struct wlr_output *output) { } void wlr_output_set_gamma(struct wlr_output *output, - uint16_t size, uint16_t *r, uint16_t *g, uint16_t *b) { + uint32_t size, uint16_t *r, uint16_t *g, uint16_t *b) { if (output->impl->set_gamma) { output->impl->set_gamma(output, size, r, g, b); } } -uint16_t wlr_output_get_gamma_size(struct wlr_output *output) { +uint32_t wlr_output_get_gamma_size(struct wlr_output *output) { if (!output->impl->get_gamma_size) { return 0; } -- cgit v1.2.3 From eea532911a5be8d45770d074546bdeb8a0f16c5b Mon Sep 17 00:00:00 2001 From: emersion Date: Mon, 23 Oct 2017 21:03:00 +0200 Subject: Send output current mode when changed --- backend/wayland/output.c | 10 +++----- backend/x11/backend.c | 4 +-- include/wlr/interfaces/wlr_output.h | 3 ++- types/wlr_output.c | 51 ++++++++++++++++++++++++++++++++----- 4 files changed, 51 insertions(+), 17 deletions(-) (limited to 'include/wlr/interfaces/wlr_output.h') diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 3194e2cf..0dde343c 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -210,9 +210,7 @@ static void xdg_toplevel_handle_configure(void *data, struct zxdg_toplevel_v6 *x } // loop over states for maximized etc? wl_egl_window_resize(output->egl_window, width, height, 0, 0); - output->wlr_output.width = width; - output->wlr_output.height = height; - wlr_output_update_matrix(&output->wlr_output); + wlr_output_update_size(&output->wlr_output, width, height); wl_signal_emit(&output->wlr_output.events.resolution, output); } @@ -244,13 +242,11 @@ struct wlr_output *wlr_wl_output_create(struct wlr_backend *_backend) { wlr_output_init(&output->wlr_output, &backend->backend, &output_impl); struct wlr_output *wlr_output = &output->wlr_output; - wlr_output->width = 640; - wlr_output->height = 480; + wlr_output_update_size(wlr_output, 640, 480); strncpy(wlr_output->make, "wayland", sizeof(wlr_output->make)); strncpy(wlr_output->model, "wayland", sizeof(wlr_output->model)); snprintf(wlr_output->name, sizeof(wlr_output->name), "WL-%d", - wl_list_length(&backend->outputs) + 1); - wlr_output_update_matrix(wlr_output); + wl_list_length(&backend->outputs) + 1); output->backend = backend; diff --git a/backend/x11/backend.c b/backend/x11/backend.c index d30ec376..0e98b8d9 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -121,9 +121,7 @@ static bool handle_x11_event(struct wlr_x11_backend *x11, xcb_generic_event_t *e case XCB_CONFIGURE_NOTIFY: { xcb_configure_notify_event_t *ev = (xcb_configure_notify_event_t *)event; - output->wlr_output.width = ev->width; - output->wlr_output.height = ev->height; - wlr_output_update_matrix(&output->wlr_output); + wlr_output_update_size(&output->wlr_output, ev->width, ev->height); wl_signal_emit(&output->wlr_output.events.resolution, output); // Move the pointer to its new location diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index 636cc06c..d365e8f5 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -25,7 +25,8 @@ struct wlr_output_impl { void wlr_output_init(struct wlr_output *output, struct wlr_backend *backend, const struct wlr_output_impl *impl); void wlr_output_free(struct wlr_output *output); -void wlr_output_update_matrix(struct wlr_output *output); +void wlr_output_update_size(struct wlr_output *output, int32_t width, + int32_t height); struct wl_global *wlr_output_create_global(struct wlr_output *wlr_output, struct wl_display *display); void wlr_output_destroy_global(struct wlr_output *wlr_output); diff --git a/types/wlr_output.c b/types/wlr_output.c index a02798b2..e8d4af3e 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -33,8 +33,8 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { if (output->current_mode == mode) { flags |= WL_OUTPUT_MODE_CURRENT; } - wl_output_send_mode(resource, flags, - mode->width, mode->height, mode->refresh); + wl_output_send_mode(resource, flags, mode->width, mode->height, + mode->refresh); } if (wl_list_length(&output->modes) == 0) { @@ -51,6 +51,25 @@ static void wl_output_send_to_resource(struct wl_resource *resource) { } } +static void wlr_output_send_current_mode_to_resource( + struct wl_resource *resource) { + struct wlr_output *output = wl_resource_get_user_data(resource); + assert(output); + const uint32_t version = wl_resource_get_version(resource); + if (version < WL_OUTPUT_MODE_SINCE_VERSION) { + return; + } + if (output->current_mode != NULL) { + struct wlr_output_mode *mode = output->current_mode; + wl_output_send_mode(resource, mode->flags | WL_OUTPUT_MODE_CURRENT, + mode->width, mode->height, mode->refresh); + } else { + // Output has no mode, send the current width/height + wl_output_send_mode(resource, WL_OUTPUT_MODE_CURRENT, output->width, + output->height, 0); + } +} + static void wl_output_destroy(struct wl_resource *resource) { struct wlr_output *output = wl_resource_get_user_data(resource); struct wl_resource *_resource = NULL; @@ -110,32 +129,52 @@ void wlr_output_destroy_global(struct wlr_output *wlr_output) { wlr_output->wl_global = NULL; } -void wlr_output_update_matrix(struct wlr_output *output) { - wlr_matrix_texture(output->transform_matrix, output->width, output->height, output->transform); +static void wlr_output_update_matrix(struct wlr_output *output) { + wlr_matrix_texture(output->transform_matrix, output->width, output->height, + output->transform); } void wlr_output_enable(struct wlr_output *output, bool enable) { output->impl->enable(output, enable); } -bool wlr_output_set_mode(struct wlr_output *output, struct wlr_output_mode *mode) { +bool wlr_output_set_mode(struct wlr_output *output, + struct wlr_output_mode *mode) { if (!output->impl || !output->impl->set_mode) { return false; } bool result = output->impl->set_mode(output, mode); if (result) { wlr_output_update_matrix(output); + struct wl_resource *resource; + wl_resource_for_each(resource, &output->wl_resources) { + wlr_output_send_current_mode_to_resource(resource); + } } return result; } +void wlr_output_update_size(struct wlr_output *output, int32_t width, + int32_t height) { + output->width = width; + output->height = height; + wlr_output_update_matrix(output); + if (output->wl_global != NULL) { + struct wl_resource *resource; + wl_resource_for_each(resource, &output->wl_resources) { + wlr_output_send_current_mode_to_resource(resource); + } + } +} + void wlr_output_transform(struct wlr_output *output, enum wl_output_transform transform) { output->impl->transform(output, transform); wlr_output_update_matrix(output); } -void wlr_output_set_position(struct wlr_output *output, int32_t lx, int32_t ly) { +void wlr_output_set_position(struct wlr_output *output, int32_t lx, + int32_t ly) { if (lx == output->lx && ly == output->ly) { return; } -- cgit v1.2.3