diff options
| author | Simeon Simeonov | 2020-10-06 14:33:05 +0200 |
|---|---|---|
| committer | Simeon Simeonov | 2020-10-06 14:33:05 +0200 |
| commit | 12a06184e733554bafc76e643b49067fcd758fc0 (patch) | |
| tree | 03c2c2c4d00c8b07c250e7bfee97d0e64cd064f0 /unlock_indicator.c | |
| parent | a0a3b6e9b55036e8b7095b71151083a069943c33 (diff) | |
Merge the upstream changes from i3lock
Diffstat (limited to 'unlock_indicator.c')
| -rw-r--r-- | unlock_indicator.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/unlock_indicator.c b/unlock_indicator.c index 3d98a5f..73320cb 100644 --- a/unlock_indicator.c +++ b/unlock_indicator.c | |||
| @@ -50,9 +50,9 @@ | |||
| 50 | #define BUTTON_CENTER (BUTTON_RADIUS + 5) | 50 | #define BUTTON_CENTER (BUTTON_RADIUS + 5) |
| 51 | #define BUTTON_DIAMETER (2 * BUTTON_SPACE) | 51 | #define BUTTON_DIAMETER (2 * BUTTON_SPACE) |
| 52 | 52 | ||
| 53 | /****************************************************************************** | 53 | /******************************************************************************* |
| 54 | * Variables defined in i3lock.c. | 54 | * Variables defined in i3lock.c. |
| 55 | *****************************************************************************/ | 55 | ******************************************************************************/ |
| 56 | 56 | ||
| 57 | extern bool debug_mode; | 57 | extern bool debug_mode; |
| 58 | 58 | ||
| @@ -100,16 +100,16 @@ extern bool show_failed_attempts; | |||
| 100 | /* Number of failed unlock attempts. */ | 100 | /* Number of failed unlock attempts. */ |
| 101 | extern int failed_attempts; | 101 | extern int failed_attempts; |
| 102 | 102 | ||
| 103 | /****************************************************************************** | 103 | /******************************************************************************* |
| 104 | * Variables defined in xcb.c. | 104 | * Variables defined in xcb.c. |
| 105 | *****************************************************************************/ | 105 | ******************************************************************************/ |
| 106 | 106 | ||
| 107 | /* The root screen, to determine the DPI. */ | 107 | /* The root screen, to determine the DPI. */ |
| 108 | extern xcb_screen_t *screen; | 108 | extern xcb_screen_t *screen; |
| 109 | 109 | ||
| 110 | /****************************************************************************** | 110 | /******************************************************************************* |
| 111 | * Local variables. | 111 | * Local variables. |
| 112 | *****************************************************************************/ | 112 | ******************************************************************************/ |
| 113 | 113 | ||
| 114 | /* Cache the screen’s visual, necessary for creating a Cairo context. */ | 114 | /* Cache the screen’s visual, necessary for creating a Cairo context. */ |
| 115 | static xcb_visualtype_t *vistype; | 115 | static xcb_visualtype_t *vistype; |
| @@ -124,8 +124,7 @@ auth_state_t auth_state; | |||
| 124 | * resolution and returns it. | 124 | * resolution and returns it. |
| 125 | * | 125 | * |
| 126 | */ | 126 | */ |
| 127 | xcb_pixmap_t draw_image(uint32_t *resolution) { | 127 | void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) { |
| 128 | xcb_pixmap_t bg_pixmap = XCB_NONE; | ||
| 129 | const double scaling_factor = get_dpi_value() / 96.0; | 128 | const double scaling_factor = get_dpi_value() / 96.0; |
| 130 | int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER); | 129 | int button_diameter_physical = ceil(scaling_factor * BUTTON_DIAMETER); |
| 131 | DEBUG("scaling_factor is %.f, physical diameter is %d px\n", | 130 | DEBUG("scaling_factor is %.f, physical diameter is %d px\n", |
| @@ -133,7 +132,7 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 133 | 132 | ||
| 134 | if (!vistype) | 133 | if (!vistype) |
| 135 | vistype = get_root_visual_type(screen); | 134 | vistype = get_root_visual_type(screen); |
| 136 | bg_pixmap = create_bg_pixmap(conn, screen, resolution, color); | 135 | |
| 137 | /* Initialize cairo: Create one in-memory surface to render the unlock | 136 | /* Initialize cairo: Create one in-memory surface to render the unlock |
| 138 | * indicator on, create one XCB surface to actually draw (one or more, | 137 | * indicator on, create one XCB surface to actually draw (one or more, |
| 139 | * depending on the amount of screens) unlock indicators on. */ | 138 | * depending on the amount of screens) unlock indicators on. */ |
| @@ -143,6 +142,19 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 143 | cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); | 142 | cairo_surface_t *xcb_output = cairo_xcb_surface_create(conn, bg_pixmap, vistype, resolution[0], resolution[1]); |
| 144 | cairo_t *xcb_ctx = cairo_create(xcb_output); | 143 | cairo_t *xcb_ctx = cairo_create(xcb_output); |
| 145 | 144 | ||
| 145 | /* After the first iteration, the pixmap will still contain the previous | ||
| 146 | * contents. Explicitly clear the entire pixmap with the background color | ||
| 147 | * first to get back into a defined state: */ | ||
| 148 | char strgroups[3][3] = {{color[0], color[1], '\0'}, | ||
| 149 | {color[2], color[3], '\0'}, | ||
| 150 | {color[4], color[5], '\0'}}; | ||
| 151 | uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), | ||
| 152 | (strtol(strgroups[1], NULL, 16)), | ||
| 153 | (strtol(strgroups[2], NULL, 16))}; | ||
| 154 | cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0); | ||
| 155 | cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); | ||
| 156 | cairo_fill(xcb_ctx); | ||
| 157 | |||
| 146 | if (img) { | 158 | if (img) { |
| 147 | if (!tile) { | 159 | if (!tile) { |
| 148 | cairo_set_source_surface(xcb_ctx, img, 0, 0); | 160 | cairo_set_source_surface(xcb_ctx, img, 0, 0); |
| @@ -157,16 +169,6 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 157 | cairo_fill(xcb_ctx); | 169 | cairo_fill(xcb_ctx); |
| 158 | cairo_pattern_destroy(pattern); | 170 | cairo_pattern_destroy(pattern); |
| 159 | } | 171 | } |
| 160 | } else { | ||
| 161 | char strgroups[3][3] = {{color[0], color[1], '\0'}, | ||
| 162 | {color[2], color[3], '\0'}, | ||
| 163 | {color[4], color[5], '\0'}}; | ||
| 164 | uint32_t rgb16[3] = {(strtol(strgroups[0], NULL, 16)), | ||
| 165 | (strtol(strgroups[1], NULL, 16)), | ||
| 166 | (strtol(strgroups[2], NULL, 16))}; | ||
| 167 | cairo_set_source_rgb(xcb_ctx, rgb16[0] / 255.0, rgb16[1] / 255.0, rgb16[2] / 255.0); | ||
| 168 | cairo_rectangle(xcb_ctx, 0, 0, resolution[0], resolution[1]); | ||
| 169 | cairo_fill(xcb_ctx); | ||
| 170 | } | 172 | } |
| 171 | 173 | ||
| 172 | if (unlock_indicator && | 174 | if (unlock_indicator && |
| @@ -394,7 +396,18 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 394 | cairo_surface_destroy(output); | 396 | cairo_surface_destroy(output); |
| 395 | cairo_destroy(ctx); | 397 | cairo_destroy(ctx); |
| 396 | cairo_destroy(xcb_ctx); | 398 | cairo_destroy(xcb_ctx); |
| 397 | return bg_pixmap; | 399 | } |
| 400 | |||
| 401 | static xcb_pixmap_t bg_pixmap = XCB_NONE; | ||
| 402 | |||
| 403 | /* | ||
| 404 | * Releases the current background pixmap so that the next redraw_screen() call | ||
| 405 | * will allocate a new one with the updated resolution. | ||
| 406 | * | ||
| 407 | */ | ||
| 408 | void free_bg_pixmap(void) { | ||
| 409 | xcb_free_pixmap(conn, bg_pixmap); | ||
| 410 | bg_pixmap = XCB_NONE; | ||
| 398 | } | 411 | } |
| 399 | 412 | ||
| 400 | /* | 413 | /* |
| @@ -403,12 +416,16 @@ xcb_pixmap_t draw_image(uint32_t *resolution) { | |||
| 403 | */ | 416 | */ |
| 404 | void redraw_screen(void) { | 417 | void redraw_screen(void) { |
| 405 | DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); | 418 | DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); |
| 406 | xcb_pixmap_t bg_pixmap = draw_image(last_resolution); | 419 | if (bg_pixmap == XCB_NONE) { |
| 420 | DEBUG("allocating pixmap for %d x %d px\n", last_resolution[0], last_resolution[1]); | ||
| 421 | bg_pixmap = create_bg_pixmap(conn, screen, last_resolution, color); | ||
| 422 | } | ||
| 423 | |||
| 424 | draw_image(bg_pixmap, last_resolution); | ||
| 407 | xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){bg_pixmap}); | 425 | xcb_change_window_attributes(conn, win, XCB_CW_BACK_PIXMAP, (uint32_t[1]){bg_pixmap}); |
| 408 | /* XXX: Possible optimization: Only update the area in the middle of the | 426 | /* XXX: Possible optimization: Only update the area in the middle of the |
| 409 | * screen instead of the whole screen. */ | 427 | * screen instead of the whole screen. */ |
| 410 | xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]); | 428 | xcb_clear_area(conn, 0, win, 0, 0, last_resolution[0], last_resolution[1]); |
| 411 | xcb_free_pixmap(conn, bg_pixmap); | ||
| 412 | xcb_flush(conn); | 429 | xcb_flush(conn); |
| 413 | } | 430 | } |
| 414 | 431 | ||
