From 46b388995d7d50a39d13fce9417e2ad0d2cf749f Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 3 Apr 2018 19:15:14 -0400 Subject: [PATCH] Add hidpi support to swaylock --- include/swaylock/swaylock.h | 1 + swaylock/main.c | 35 +++++++++++++++++++++++++++++-- swaylock/render.c | 41 +++++++++++++++++++++---------------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/include/swaylock/swaylock.h b/include/swaylock/swaylock.h index 06c94ead..173e8b12 100644 --- a/include/swaylock/swaylock.h +++ b/include/swaylock/swaylock.h @@ -52,6 +52,7 @@ struct swaylock_surface { struct pool_buffer buffers[2]; struct pool_buffer *current_buffer; uint32_t width, height; + int32_t scale; struct wl_list link; }; diff --git a/swaylock/main.c b/swaylock/main.c index 6cd4e41d..1eda3afc 100644 --- a/swaylock/main.c +++ b/swaylock/main.c @@ -56,12 +56,42 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { .closed = layer_surface_closed, }; +static void output_geometry(void *data, struct wl_output *output, int32_t x, + int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, + const char *make, const char *model, int32_t transform) { + // Who cares +} + +static void output_mode(void *data, struct wl_output *output, uint32_t flags, + int32_t width, int32_t height, int32_t refresh) { + // Who cares +} + +static void output_done(void *data, struct wl_output *output) { + // Who cares +} + +static void output_scale(void *data, struct wl_output *output, int32_t factor) { + struct swaylock_surface *surface = data; + surface->scale = factor; + if (surface->state->run_display) { + render_frames(surface->state); + } +} + +struct wl_output_listener output_listener = { + .geometry = output_geometry, + .mode = output_mode, + .done = output_done, + .scale = output_scale, +}; + static void handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { struct swaylock_state *state = data; if (strcmp(interface, wl_compositor_interface.name) == 0) { state->compositor = wl_registry_bind(registry, name, - &wl_compositor_interface, 1); + &wl_compositor_interface, 3); } else if (strcmp(interface, wl_shm_interface.name) == 0) { state->shm = wl_registry_bind(registry, name, &wl_shm_interface, 1); @@ -80,7 +110,8 @@ static void handle_global(void *data, struct wl_registry *registry, calloc(1, sizeof(struct swaylock_surface)); surface->state = state; surface->output = wl_registry_bind(registry, name, - &wl_output_interface, 1); + &wl_output_interface, 3); + wl_output_add_listener(surface->output, &output_listener, surface); wl_list_insert(&state->surfaces, &surface->link); } } diff --git a/swaylock/render.c b/swaylock/render.c index 90db71e3..2469e60b 100644 --- a/swaylock/render.c +++ b/swaylock/render.c @@ -9,28 +9,32 @@ void render_frame(struct swaylock_surface *surface) { struct swaylock_state *state = surface->state; surface->current_buffer = get_next_buffer(state->shm, - surface->buffers, surface->width, surface->height); + surface->buffers, + surface->width * surface->scale, + surface->height * surface->scale); cairo_t *cairo = surface->current_buffer->cairo; cairo_identity_matrix(cairo); + + int buffer_width = surface->width * surface->scale; + int buffer_height = surface->height * surface->scale; if (state->args.mode == BACKGROUND_MODE_SOLID_COLOR) { cairo_set_source_u32(cairo, state->args.color); cairo_paint(cairo); } else { - // TODO: hidpi render_background_image(cairo, surface->image, - state->args.mode, surface->width, surface->height, 1); + state->args.mode, buffer_width, buffer_height); } cairo_identity_matrix(cairo); - const int ARC_RADIUS = 50; - const int ARC_THICKNESS = 10; - const float TYPE_INDICATOR_RANGE = M_PI / 3.0f; - const float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f; + int ARC_RADIUS = 50 * surface->scale; + int ARC_THICKNESS = 10 * surface->scale; + float TYPE_INDICATOR_RANGE = M_PI / 3.0f; + float TYPE_INDICATOR_BORDER_THICKNESS = M_PI / 128.0f * surface->scale; + if (state->args.show_indicator && state->auth_state != AUTH_STATE_IDLE) { // Draw circle cairo_set_line_width(cairo, ARC_THICKNESS); - cairo_arc(cairo, surface->width / 2, surface->height / 2, - ARC_RADIUS, 0, 2 * M_PI); + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, ARC_RADIUS, 0, 2 * M_PI); switch (state->auth_state) { case AUTH_STATE_INPUT: case AUTH_STATE_BACKSPACE: { @@ -74,9 +78,9 @@ void render_frame(struct swaylock_surface *surface) { cairo_text_extents_t extents; double x, y; cairo_text_extents(cairo, text, &extents); - x = (surface->width / 2) - + x = (buffer_width / 2) - (extents.width / 2 + extents.x_bearing); - y = (surface->height / 2) - + y = (buffer_height / 2) - (extents.height / 2 + extents.y_bearing); cairo_move_to(cairo, x, y); @@ -91,7 +95,7 @@ void render_frame(struct swaylock_surface *surface) { static double highlight_start = 0; highlight_start += (rand() % (int)(M_PI * 100)) / 100.0 + M_PI * 0.5; - cairo_arc(cairo, surface->width / 2, surface->height / 2, + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_RANGE); if (state->auth_state == AUTH_STATE_INPUT) { @@ -103,12 +107,12 @@ void render_frame(struct swaylock_surface *surface) { // Draw borders cairo_set_source_rgb(cairo, 0, 0, 0); - cairo_arc(cairo, surface->width / 2, surface->height / 2, + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, ARC_RADIUS, highlight_start, highlight_start + TYPE_INDICATOR_BORDER_THICKNESS); cairo_stroke(cairo); - cairo_arc(cairo, surface->width / 2, surface->height / 2, + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, ARC_RADIUS, highlight_start + TYPE_INDICATOR_RANGE, highlight_start + TYPE_INDICATOR_RANGE + TYPE_INDICATOR_BORDER_THICKNESS); @@ -117,17 +121,18 @@ void render_frame(struct swaylock_surface *surface) { // Draw inner + outer border of the circle cairo_set_source_rgb(cairo, 0, 0, 0); - cairo_set_line_width(cairo, 2.0); - cairo_arc(cairo, surface->width / 2, surface->height / 2, + cairo_set_line_width(cairo, 2.0 * surface->scale); + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, ARC_RADIUS - ARC_THICKNESS / 2, 0, 2 * M_PI); cairo_stroke(cairo); - cairo_arc(cairo, surface->width / 2, surface->height / 2, + cairo_arc(cairo, buffer_width / 2, buffer_height / 2, ARC_RADIUS + ARC_THICKNESS / 2, 0, 2 * M_PI); cairo_stroke(cairo); } + wl_surface_set_buffer_scale(surface->surface, surface->scale); wl_surface_attach(surface->surface, surface->current_buffer->buffer, 0, 0); - wl_surface_damage(surface->surface, 0, 0, surface->width, surface->height); + wl_surface_damage(surface->surface, 0, 0, buffer_width, buffer_height); wl_surface_commit(surface->surface); wl_display_roundtrip(state->display); }