diff options
Diffstat (limited to 'unlock_indicator.c')
| -rw-r--r-- | unlock_indicator.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/unlock_indicator.c b/unlock_indicator.c index 8f69972..6f6fbf7 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 Simeon Simeonov | 3 | * Copyright (C) 2020-2023 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 |
| @@ -31,6 +31,7 @@ | |||
| 31 | #include <string.h> | 31 | #include <string.h> |
| 32 | #include <math.h> | 32 | #include <math.h> |
| 33 | #include <xcb/xcb.h> | 33 | #include <xcb/xcb.h> |
| 34 | #include <xkbcommon/xkbcommon.h> | ||
| 34 | #include <ev.h> | 35 | #include <ev.h> |
| 35 | #include <cairo.h> | 36 | #include <cairo.h> |
| 36 | #include <cairo/cairo-xcb.h> | 37 | #include <cairo/cairo-xcb.h> |
| @@ -103,6 +104,9 @@ extern bool show_failed_attempts; | |||
| 103 | /* Number of failed unlock attempts. */ | 104 | /* Number of failed unlock attempts. */ |
| 104 | extern int failed_attempts; | 105 | extern int failed_attempts; |
| 105 | 106 | ||
| 107 | extern struct xkb_keymap *xkb_keymap; | ||
| 108 | extern struct xkb_state *xkb_state; | ||
| 109 | |||
| 106 | /******************************************************************************* | 110 | /******************************************************************************* |
| 107 | * Variables defined in xcb.c. | 111 | * Variables defined in xcb.c. |
| 108 | ******************************************************************************/ | 112 | ******************************************************************************/ |
| @@ -122,6 +126,44 @@ static xcb_visualtype_t *vistype; | |||
| 122 | unlock_state_t unlock_state; | 126 | unlock_state_t unlock_state; |
| 123 | auth_state_t auth_state; | 127 | auth_state_t auth_state; |
| 124 | 128 | ||
| 129 | /* check_modifier_keys describes the currently active modifiers (Caps Lock, Alt, | ||
| 130 | Num Lock or Super) in the modifier_string variable. */ | ||
| 131 | static void check_modifier_keys(void) { | ||
| 132 | xkb_mod_index_t idx, num_mods; | ||
| 133 | const char *mod_name; | ||
| 134 | |||
| 135 | num_mods = xkb_keymap_num_mods(xkb_keymap); | ||
| 136 | |||
| 137 | for (idx = 0; idx < num_mods; idx++) { | ||
| 138 | if (!xkb_state_mod_index_is_active(xkb_state, idx, XKB_STATE_MODS_EFFECTIVE)) | ||
| 139 | continue; | ||
| 140 | |||
| 141 | mod_name = xkb_keymap_mod_get_name(xkb_keymap, idx); | ||
| 142 | if (mod_name == NULL) | ||
| 143 | continue; | ||
| 144 | |||
| 145 | /* Replace certain xkb names with nicer, human-readable ones. */ | ||
| 146 | if (strcmp(mod_name, XKB_MOD_NAME_CAPS) == 0) { | ||
| 147 | mod_name = "Caps Lock"; | ||
| 148 | } else if (strcmp(mod_name, XKB_MOD_NAME_NUM) == 0) { | ||
| 149 | mod_name = "Num Lock"; | ||
| 150 | } else { | ||
| 151 | /* Show only Caps Lock and Num Lock, other modifiers (e.g. Shift) | ||
| 152 | * leak state about the password. */ | ||
| 153 | continue; | ||
| 154 | } | ||
| 155 | |||
| 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 | } | ||
| 165 | } | ||
| 166 | |||
| 125 | /* | 167 | /* |
| 126 | * Draws global image with fill color onto a pixmap with the given | 168 | * Draws global image with fill color onto a pixmap with the given |
| 127 | * resolution and returns it. | 169 | * resolution and returns it. |
| @@ -291,7 +333,7 @@ void draw_image(xcb_pixmap_t bg_pixmap, uint32_t *resolution) { | |||
| 291 | cairo_close_path(ctx); | 333 | cairo_close_path(ctx); |
| 292 | } | 334 | } |
| 293 | 335 | ||
| 294 | if (auth_state == STATE_AUTH_WRONG && (modifier_string != NULL)) { | 336 | if (modifier_string != NULL) { |
| 295 | cairo_text_extents_t extents; | 337 | cairo_text_extents_t extents; |
| 296 | double x, y; | 338 | double x, y; |
| 297 | 339 | ||
| @@ -432,6 +474,13 @@ void free_bg_pixmap(void) { | |||
| 432 | */ | 474 | */ |
| 433 | void redraw_screen(void) { | 475 | void redraw_screen(void) { |
| 434 | DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); | 476 | DEBUG("redraw_screen(unlock_state = %d, auth_state = %d)\n", unlock_state, auth_state); |
| 477 | |||
| 478 | if (modifier_string) { | ||
| 479 | free(modifier_string); | ||
| 480 | modifier_string = NULL; | ||
| 481 | } | ||
| 482 | check_modifier_keys(); | ||
| 483 | |||
| 435 | if (bg_pixmap == XCB_NONE) { | 484 | if (bg_pixmap == XCB_NONE) { |
| 436 | DEBUG("allocating pixmap for %d x %d px\n", last_resolution[0], last_resolution[1]); | 485 | DEBUG("allocating pixmap for %d x %d px\n", last_resolution[0], last_resolution[1]); |
| 437 | bg_pixmap = create_bg_pixmap(conn, screen, last_resolution, color); | 486 | bg_pixmap = create_bg_pixmap(conn, screen, last_resolution, color); |
