From e7f1a509f20aa0a486ea81ddd88010bc56773628 Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Wed, 19 Feb 2020 13:17:12 -0800 Subject: [PATCH] Add a temporary feature to show locks and latches rather than indicators. This isn't quite what I want, so for now it's already marked deprecated. Only there for testing a solution to issue #95. --- ensure-documented-settings.sh | 1 + helpers/auth_x11.c | 107 +++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 29 deletions(-) diff --git a/ensure-documented-settings.sh b/ensure-documented-settings.sh index ac7a0810..5ef24b8c 100755 --- a/ensure-documented-settings.sh +++ b/ensure-documented-settings.sh @@ -33,6 +33,7 @@ XSECURELOCK_INSIDE_SAVER_MULTIPLEX # List of deprecated settings. These shall not be documented. deprecated_settings=' XSECURELOCK_PARANOID_PASSWORD +XSECURELOCK_SHOW_LOCKS_AND_LATCHES XSECURELOCK_WANT_FIRST_KEYPRESS ' diff --git a/helpers/auth_x11.c b/helpers/auth_x11.c index 7cd2fe3f..af47ceea 100644 --- a/helpers/auth_x11.c +++ b/helpers/auth_x11.c @@ -251,6 +251,11 @@ static int single_auth_window = 0; //! If set, we need to re-query monitor data and adjust windows. int per_monitor_windows_dirty = 1; +#ifdef HAVE_XKB_EXT +//! If set, we show Xkb lock/latch status rather than Xkb indicators. +int show_locks_and_latches = 0; +#endif + #define MAIN_WINDOW 0 #define MAX_WINDOWS 16 @@ -406,18 +411,21 @@ const char *GetIndicators(int *warning, int *have_multiple_layouts) { XkbFreeKeyboard(xkb, 0, True); return ""; } - unsigned int istate; - if (XkbGetIndicatorState(display, XkbUseCoreKbd, &istate) != Success) { - Log("XkbGetIndicatorState failed"); - XkbFreeKeyboard(xkb, 0, True); - return ""; + unsigned int istate = 0; + if (!show_locks_and_latches) { + if (XkbGetIndicatorState(display, XkbUseCoreKbd, &istate) != Success) { + Log("XkbGetIndicatorState failed"); + XkbFreeKeyboard(xkb, 0, True); + return ""; + } } // Detect Caps Lock. // Note: in very pathological cases the modifier might be set without an // XkbIndicator for it; then we show the line in red without telling the user // why. Such a situation has not been observd yet though. - if (state.mods & LockMask) { + unsigned int implicit_mods = state.latched_mods | state.locked_mods; + if (implicit_mods & LockMask) { *warning = 1; } @@ -458,33 +466,70 @@ const char *GetIndicators(int *warning, int *have_multiple_layouts) { have_output = 1; } - for (int i = 0; i < XkbNumIndicators; i++) { - if (!(istate & (1U << i))) { - continue; - } - Atom namea = xkb->names->indicators[i]; - if (namea == None) { - continue; - } - if (have_output) { - if (2 >= sizeof(buf) - (p - buf)) { - Log("Not enough space to store another modifier name"); + if (show_locks_and_latches) { +#define ADD_INDICATOR(mask, name) \ + do { \ + if (!(implicit_mods & (mask))) { \ + continue; \ + } \ + if (have_output) { \ + if (2 >= sizeof(buf) - (p - buf)) { \ + Log("Not enough space to store another modifier name"); \ + break; \ + } \ + memcpy(p, ", ", 2); \ + p += 2; \ + } \ + size_t n = strlen(name); \ + if (n >= sizeof(buf) - (p - buf)) { \ + Log("Not enough space to store modifier name '%s'", name); \ + XFree(name); \ + break; \ + } \ + memcpy(p, (name), n); \ + p += n; \ + have_output = 1; \ + } while (0) + // TODO(divVerent): There must be a better way to get the names of the + // modifiers than explicitly enumerating them. Also, there may even be + // something that knows that Mod1 is Alt/Meta and Mod2 is Num lock. + ADD_INDICATOR(ShiftMask, "Shift"); + ADD_INDICATOR(LockMask, "Lock"); + ADD_INDICATOR(ControlMask, "Control"); + ADD_INDICATOR(Mod1Mask, "Mod1"); + ADD_INDICATOR(Mod2Mask, "Mod2"); + ADD_INDICATOR(Mod3Mask, "Mod3"); + ADD_INDICATOR(Mod4Mask, "Mod4"); + ADD_INDICATOR(Mod5Mask, "Mod5"); + } else { + for (int i = 0; i < XkbNumIndicators; i++) { + if (!(istate & (1U << i))) { + continue; + } + Atom namea = xkb->names->indicators[i]; + if (namea == None) { + continue; + } + if (have_output) { + if (2 >= sizeof(buf) - (p - buf)) { + Log("Not enough space to store another modifier name"); + break; + } + memcpy(p, ", ", 2); + p += 2; + } + char *name = XGetAtomName(display, namea); + size_t n = strlen(name); + if (n >= sizeof(buf) - (p - buf)) { + Log("Not enough space to store modifier name '%s'", name); + XFree(name); break; } - memcpy(p, ", ", 2); - p += 2; - } - char *name = XGetAtomName(display, namea); - size_t n = strlen(name); - if (n >= sizeof(buf) - (p - buf)) { - Log("Not enough space to store modifier name '%s'", name); + memcpy(p, name, n); XFree(name); - break; + p += n; + have_output = 1; } - memcpy(p, name, n); - XFree(name); - p += n; - have_output = 1; } *p = 0; XkbFreeKeyboard(xkb, 0, True); @@ -1565,6 +1610,10 @@ int main(int argc_local, char **argv_local) { auth_sounds = GetIntSetting("XSECURELOCK_AUTH_SOUNDS", 0); single_auth_window = GetIntSetting("XSECURELOCK_SINGLE_AUTH_WINDOW", 0); auth_cursor_blink = GetIntSetting("XSECURELOCK_AUTH_CURSOR_BLINK", 1); +#ifdef HAVE_XKB_EXT + show_locks_and_latches = + GetIntSetting("XSECURELOCK_SHOW_LOCKS_AND_LATCHES", 0); +#endif password_prompt = GetPasswordPromptFromFlags(paranoid_password_flag, password_prompt_flag);