From 457ab2ae2bf48d318c704e4073755f4c0f6f6d22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Dardenne?= Date: Sat, 18 Apr 2020 12:50:27 +0200 Subject: [PATCH] Refactor to share image drawing code --- i3lock.c | 18 ++-------- unlock_indicator.c | 89 +++++++++++++++++++++++----------------------- unlock_indicator.h | 4 +-- 3 files changed, 48 insertions(+), 63 deletions(-) diff --git a/i3lock.c b/i3lock.c index 8ce8ffc..228f72c 100644 --- a/i3lock.c +++ b/i3lock.c @@ -2195,21 +2195,7 @@ int main(int argc, char *argv[]) { blur_image_surface(blur_img, blur_sigma); if (img) { // Display image centered on all outputs. - if (centered) { - draw_on_all_outputs(ctx); - } else if (tile) { - /* create a pattern and fill a rectangle as big as the screen */ - cairo_pattern_t *pattern; - pattern = cairo_pattern_create_for_surface(img); - cairo_set_source(ctx, pattern); - cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); - cairo_rectangle(ctx, 0, 0, last_resolution[0], last_resolution[1]); - cairo_fill(ctx); - cairo_pattern_destroy(pattern); - } else { - cairo_set_source_surface(ctx, img, 0, 0); - cairo_paint(ctx); - } + draw_image(last_resolution, ctx); cairo_surface_destroy(img); img = NULL; } @@ -2223,7 +2209,7 @@ int main(int argc, char *argv[]) { win = open_fullscreen_window(conn, screen, color); xcb_pixmap_t pixmap = create_bg_pixmap(conn, win, last_resolution, color); - draw_image(last_resolution, pixmap); + render_lock(last_resolution, pixmap); xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[]){pixmap}); xcb_free_pixmap(conn, pixmap); diff --git a/unlock_indicator.c b/unlock_indicator.c index 5a46423..dfa0f9f 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c @@ -673,10 +673,9 @@ static void draw_elements(cairo_t *const ctx, DrawData const *const draw_data) { } /* - * Draws global image with fill color onto a provided drawable with the given - * resolution. + * Renders the lock screen on the provided drawable with the given resolution. */ -void draw_image(uint32_t *resolution, xcb_drawable_t drawable) { +void render_lock(uint32_t *resolution, xcb_drawable_t drawable) { const double scaling_factor = get_dpi_value() / 96.0; int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER); DEBUG("scaling_factor is %.f, physical diameter is %d px\n", @@ -720,22 +719,7 @@ void draw_image(uint32_t *resolution, xcb_drawable_t drawable) { cairo_set_source_surface(xcb_ctx, blur_img, 0, 0); cairo_paint(xcb_ctx); } else { // img can no longer be non-NULL if blur_img is not null - if (centered) - draw_on_all_outputs(xcb_ctx); - } - else if (tile) { - /* create a pattern and fill a rectangle as big as the screen */ - cairo_pattern_t *pattern; - pattern = cairo_pattern_create_for_surface(img); - cairo_set_source(xcb_ctx, pattern); - cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); - cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); - cairo_fill(xcb_ctx); - cairo_pattern_destroy(pattern); - } else { - cairo_set_source_surface(xcb_ctx, img, 0, 0); - cairo_paint(xcb_ctx); - } + draw_image(resolution, xcb_ctx); } } else { cairo_set_source_rgb(xcb_ctx, rgb16.red, rgb16.green, rgb16.blue); @@ -1068,49 +1052,64 @@ void draw_image(uint32_t *resolution, xcb_drawable_t drawable) { cairo_destroy(xcb_ctx); } -void draw_on_all_outputs(cairo_t* xcb_ctx) { - double image_width = cairo_image_surface_get_width(img); - double image_height = cairo_image_surface_get_height(img); +void draw_image(uint32_t* resolution, cairo_t* xcb_ctx) { + if (centered) { + double image_width = cairo_image_surface_get_width(img); + double image_height = cairo_image_surface_get_height(img); - xcb_randr_get_screen_resources_current_reply_t *reply = xcb_randr_get_screen_resources_current_reply( - conn, xcb_randr_get_screen_resources_current(conn, screen->root), NULL); + xcb_randr_get_screen_resources_current_reply_t *reply = xcb_randr_get_screen_resources_current_reply( + conn, xcb_randr_get_screen_resources_current(conn, screen->root), NULL); - xcb_timestamp_t timestamp = reply->config_timestamp; - int len = xcb_randr_get_screen_resources_current_outputs_length(reply); - xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply); + xcb_timestamp_t timestamp = reply->config_timestamp; + int len = xcb_randr_get_screen_resources_current_outputs_length(reply); + xcb_randr_output_t *randr_outputs = xcb_randr_get_screen_resources_current_outputs(reply); - for (int i = 0; i < len; i++) { - xcb_randr_get_output_info_reply_t *output = xcb_randr_get_output_info_reply( - conn, xcb_randr_get_output_info(conn, randr_outputs[i], timestamp), NULL); - if (output == NULL) - continue; + for (int i = 0; i < len; i++) { + xcb_randr_get_output_info_reply_t *output = xcb_randr_get_output_info_reply( + conn, xcb_randr_get_output_info(conn, randr_outputs[i], timestamp), NULL); + if (output == NULL) + continue; - if (output->crtc == XCB_NONE || output->connection == XCB_RANDR_CONNECTION_DISCONNECTED) - continue; + if (output->crtc == XCB_NONE || output->connection == XCB_RANDR_CONNECTION_DISCONNECTED) + continue; - xcb_randr_get_crtc_info_cookie_t infoCookie = xcb_randr_get_crtc_info(conn, output->crtc, - timestamp); - xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(conn, infoCookie, NULL); + xcb_randr_get_crtc_info_cookie_t infoCookie = xcb_randr_get_crtc_info(conn, output->crtc, + timestamp); + xcb_randr_get_crtc_info_reply_t *crtc = xcb_randr_get_crtc_info_reply(conn, infoCookie, NULL); - double origin_x = crtc->x + (crtc->width / 2.0 - image_width / 2.0); - double origin_y = crtc->y + (crtc->height / 2.0 - image_height / 2.0); + double origin_x = crtc->x + (crtc->width / 2.0 - image_width / 2.0); + double origin_y = crtc->y + (crtc->height / 2.0 - image_height / 2.0); - cairo_set_source_surface(xcb_ctx, img, origin_x, origin_y); + cairo_set_source_surface(xcb_ctx, img, origin_x, origin_y); + cairo_paint(xcb_ctx); + + free(crtc); + free(output); + } + } else if (tile) { + /* create a pattern and fill a rectangle as big as the screen */ + cairo_pattern_t *pattern; + pattern = cairo_pattern_create_for_surface(img); + cairo_set_source(xcb_ctx, pattern); + cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT); + cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); + cairo_fill(xcb_ctx); + cairo_pattern_destroy(pattern); + } else { + cairo_set_source_surface(xcb_ctx, img, 0, 0); cairo_paint(xcb_ctx); - - free(crtc); - free(output); } + } /* - * Calls draw_image on a new pixmap and swaps that with the current pixmap + * Calls render_lock on a new pixmap and swaps that with the current pixmap * */ void redraw_screen(void) { DEBUG("redraw_screen(unlock_state = %d, auth_state = %d) @ [%lu]\n", unlock_state, auth_state, (unsigned long)time(NULL)); xcb_pixmap_t pixmap = create_bg_pixmap(conn, win, last_resolution, color); - draw_image(last_resolution, pixmap); + render_lock(last_resolution, pixmap); xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){pixmap}); xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]); xcb_free_pixmap(conn, pixmap); diff --git a/unlock_indicator.h b/unlock_indicator.h index 360e190..eef3d96 100644 --- a/unlock_indicator.h +++ b/unlock_indicator.h @@ -38,8 +38,8 @@ typedef struct { double bar_offset; } DrawData; -void draw_image(uint32_t* resolution, xcb_drawable_t drawable); -void draw_on_all_outputs(cairo_t* xcb_ctx); +void render_lock(uint32_t* resolution, xcb_drawable_t drawable); +void draw_image(uint32_t* resolution, cairo_t* xcb_ctx); void init_colors_once(void); void redraw_screen(void); void clear_indicator(void);