From fc353003f93883bf62a9865472e6f206a62b09f1 Mon Sep 17 00:00:00 2001 From: Mamoru TASAKA Date: Thu, 8 Jul 2021 23:06:46 +0900 Subject: [PATCH] window_init: check if asterisk font is available and provide fallback character Downstream bug: https://bugzilla.redhat.com/show_bug.cgi?id=1980173 On Fedora 34, using US locale (LANG=en_US.UTF-8), when both "dejavu-sans-fonts" and "bitstream-vera-sans-fonts" rpms are installed, * xscreensaver-auth requests "sans-serif" to xft * xft chooses bitstream-vera-sans (according to fontconfig settings) 45-latin.conf seems to be saying so. * gucharmap shows that while "dejavu-sans-fonts" contains glyph for "U+25CF", however bitstream-vera-sans-fonts does not. Then such people sees white rectangles when typing password. For now, check if corresponding font is available, and if not, provide fallback character --- driver/dialog.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/driver/dialog.c b/driver/dialog.c index 7f1ec8b..a17e9af 100644 --- a/driver/dialog.c +++ b/driver/dialog.c @@ -79,6 +79,7 @@ #include "font-retry.h" #include "prefs.h" #include "usleep.h" +#include "utf8wc.h" extern Bool debug_p; @@ -193,6 +194,7 @@ struct window_state { char *date_format; char *kbd_layout_label; char *newlogin_cmd; + const char *asterisk_utf8; /* Resources for fonts and colors */ XftDraw *xftdraw; @@ -674,6 +676,31 @@ get_int (window_state *ws, const char *name, const char *rclass) return get_integer_resource (ws->dpy, (char *) name, (char *) rclass); } +static const char *pickup_asterisk_utf8 (window_state *ws) +{ + static char picked_string[8]; + const unsigned long uc_list[] = { + 0x25CF, /* Black Circle */ + 0x2022, /* Bullet */ + '*' /* Fallback */ + }; + const unsigned long *uc_cand = uc_list; + int encoded_length; + size_t index; + + /* -1 is so that result will pick up fallback string as a last resort */ + for (index = 0; index < sizeof uc_list / sizeof *uc_list - 1; index++) { + /* borrowed from blank_character_p in texfont.c */ + if (XftCharExists (ws->dpy, ws->label_font, (FcChar32) *uc_cand)) break; + uc_cand++; + } + + encoded_length = utf8_encode(*uc_cand, picked_string, sizeof picked_string - 1); + picked_string[encoded_length] = 0; + + return picked_string; +} + /* Decide where on the X11 screen to place the dialog. This is complicated because, in the face of RANDR and Xinerama, we want @@ -983,6 +1010,8 @@ window_init (Widget root_widget, Bool splash_p) ws->label_font = get_font (ws, "labelFont"); ws->date_font = get_font (ws, "dateFont"); ws->hostname_font = get_font (ws, "unameFont"); + + ws->asterisk_utf8 = pickup_asterisk_utf8(ws); ws->foreground = get_color (ws, "foreground", "Foreground"); ws->background = get_color (ws, "background", "Background"); @@ -2003,9 +2032,7 @@ handle_keypress (window_state *ws, XKeyEvent *event) *out = 0; for (i = 0; i < MAX_PASSWD_CHARS && ws->plaintext_passwd_char_size[i]; i++) { - const char *b = /* "\xE2\x80\xA2"; */ /* U+2022 Bullet */ - "\xe2\x97\x8f"; /* U+25CF Black Circle */ - strcat (out, b); + strcat (out, ws->asterisk_utf8); out += strlen(out); } } -- 2.31.1