summaryrefslogtreecommitdiff
path: root/unlock_indicator.c
diff options
context:
space:
mode:
Diffstat (limited to 'unlock_indicator.c')
-rw-r--r--unlock_indicator.c94
1 files changed, 63 insertions, 31 deletions
diff --git a/unlock_indicator.c b/unlock_indicator.c
index 6f6fbf7..7d620fd 100644
--- a/unlock_indicator.c
+++ b/unlock_indicator.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * This file is part of i3lock-extended 2 * This file is part of i3lock-extended
3 * Copyright (C) 2020-2023 Simeon Simeonov 3 * Copyright (C) 2020-2024 Simeon Simeonov
4 4
5 * i3lock-extended is free software: you can redistribute it and/or modify 5 * i3lock-extended is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -90,6 +90,8 @@ extern bool unlock_indicator;
90 90
91/* List of pressed modifiers, or NULL if none are pressed. */ 91/* List of pressed modifiers, or NULL if none are pressed. */
92extern char *modifier_string; 92extern char *modifier_string;
93/* Name of the current keyboard layout or NULL if not initialized. */
94char *layout_string = NULL;
93 95
94/* A Cairo surface containing the specified image (-i), if any. */ 96/* A Cairo surface containing the specified image (-i), if any. */
95extern cairo_surface_t *img; 97extern cairo_surface_t *img;
@@ -101,6 +103,8 @@ extern char color[7];
101 103
102/* Whether the failed attempts should be displayed. */ 104/* Whether the failed attempts should be displayed. */
103extern bool show_failed_attempts; 105extern bool show_failed_attempts;
106/* Whether keyboard layout should be displayed. */
107extern bool show_keyboard_layout;
104/* Number of failed unlock attempts. */ 108/* Number of failed unlock attempts. */
105extern int failed_attempts; 109extern int failed_attempts;
106 110
@@ -126,6 +130,53 @@ static xcb_visualtype_t *vistype;
126unlock_state_t unlock_state; 130unlock_state_t unlock_state;
127auth_state_t auth_state; 131auth_state_t auth_state;
128 132
133static void string_append(char **string_ptr, const char *appended) {
134 char *tmp = NULL;
135 if (*string_ptr == NULL) {
136 if (asprintf(&tmp, "%s", appended) != -1) {
137 *string_ptr = tmp;
138 }
139 } else if (asprintf(&tmp, "%s, %s", *string_ptr, appended) != -1) {
140 free(*string_ptr);
141 *string_ptr = tmp;
142 }
143}
144
145static void display_button_text(
146 cairo_t *ctx, const char *text, double y_offset, bool use_dark_text) {
147 cairo_text_extents_t extents;
148 double x, y;
149
150 cairo_text_extents(ctx, text, &extents);
151 x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
152 y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + y_offset;
153
154 cairo_move_to(ctx, x, y);
155 if (use_dark_text) {
156 cairo_set_source_rgb(ctx, 0., 0., 0.);
157 } else {
158 cairo_set_source_rgb(ctx, 1., 1., 1.);
159 }
160 cairo_show_text(ctx, text);
161 cairo_close_path(ctx);
162}
163
164static void update_layout_string() {
165 if (layout_string) {
166 free(layout_string);
167 layout_string = NULL;
168 }
169 xkb_layout_index_t num_layouts = xkb_keymap_num_layouts(xkb_keymap);
170 for (xkb_layout_index_t i = 0; i < num_layouts; ++i) {
171 if (xkb_state_layout_index_is_active(xkb_state, i, XKB_STATE_LAYOUT_EFFECTIVE)) {
172 const char *name = xkb_keymap_layout_get_name(xkb_keymap, i);
173 if (name) {
174 string_append(&layout_string, name);
175 }
176 }
177 }
178}
179
129/* check_modifier_keys describes the currently active modifiers (Caps Lock, Alt, 180/* check_modifier_keys describes the currently active modifiers (Caps Lock, Alt,
130 Num Lock or Super) in the modifier_string variable. */ 181 Num Lock or Super) in the modifier_string variable. */
131static void check_modifier_keys(void) { 182static void check_modifier_keys(void) {
@@ -152,15 +203,7 @@ static void check_modifier_keys(void) {
152 * leak state about the password. */ 203 * leak state about the password. */
153 continue; 204 continue;
154 } 205 }
155 206 string_append(&modifier_string, mod_name);
156 char *tmp;
157 if (modifier_string == NULL) {
158 if (asprintf(&tmp, "%s", mod_name) != -1)
159 modifier_string = tmp;
160 } else if (asprintf(&tmp, "%s, %s", modifier_string, mod_name) != -1) {
161 free(modifier_string);
162 modifier_string = tmp;
163 }
164 } 207 }
165} 208}
166 209
@@ -249,6 +292,8 @@ void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) {
249 } 292 }
250 cairo_fill_preserve(ctx); 293 cairo_fill_preserve(ctx);
251 294
295 bool use_dark_text = true;
296
252 switch (auth_state) { 297 switch (auth_state) {
253 case STATE_AUTH_VERIFY: 298 case STATE_AUTH_VERIFY:
254 case STATE_AUTH_LOCK: 299 case STATE_AUTH_LOCK:
@@ -265,6 +310,7 @@ void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) {
265 } 310 }
266 311
267 cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0); 312 cairo_set_source_rgb(ctx, 51.0 / 255, 125.0 / 255, 0);
313 use_dark_text = false;
268 break; 314 break;
269 } 315 }
270 cairo_stroke(ctx); 316 cairo_stroke(ctx);
@@ -321,31 +367,16 @@ void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) {
321 } 367 }
322 368
323 if (text) { 369 if (text) {
324 cairo_text_extents_t extents; 370 display_button_text(ctx, text, 0., use_dark_text);
325 double x, y;
326
327 cairo_text_extents(ctx, text, &extents);
328 x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing);
329 y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing);
330
331 cairo_move_to(ctx, x, y);
332 cairo_show_text(ctx, text);
333 cairo_close_path(ctx);
334 } 371 }
335 372
336 if (modifier_string != NULL) { 373 if (modifier_string != NULL) {
337 cairo_text_extents_t extents;
338 double x, y;
339
340 cairo_set_font_size(ctx, 14.0); 374 cairo_set_font_size(ctx, 14.0);
341 375 display_button_text(ctx, modifier_string, 28., use_dark_text);
342 cairo_text_extents(ctx, modifier_string, &extents); 376 }
343 x = BUTTON_CENTER - ((extents.width / 2) + extents.x_bearing); 377 if (show_keyboard_layout && layout_string != NULL) {
344 y = BUTTON_CENTER - ((extents.height / 2) + extents.y_bearing) + 28.0; 378 cairo_set_font_size(ctx, 14.0);
345 379 display_button_text(ctx, layout_string, -28., use_dark_text);
346 cairo_move_to(ctx, x, y);
347 cairo_show_text(ctx, modifier_string);
348 cairo_close_path(ctx);
349 } 380 }
350 381
351 /* After the user pressed any valid key or the backspace key, we 382 /* After the user pressed any valid key or the backspace key, we
@@ -480,6 +511,7 @@ void redraw_screen(void) {
480 modifier_string = NULL; 511 modifier_string = NULL;
481 } 512 }
482 check_modifier_keys(); 513 check_modifier_keys();
514 update_layout_string();
483 515
484 if (bg_pixmap == XCB_NONE) { 516 if (bg_pixmap == XCB_NONE) {
485 DEBUG("allocating pixmap for %d x %d px\n", last_resolution[0], last_resolution[1]); 517 DEBUG("allocating pixmap for %d x %d px\n", last_resolution[0], last_resolution[1]);