NCURSES_NO_UTF8_ACS: ncurses zu Unicode-Rahmen zwingen
Die Diagnose auf dem betroffenen Terminal war eindeutig: Zeile A (echte
UTF-8-Rahmenzeichen) zeichnete Linien, Zeile B (VT100-Umschaltung ESC(0)
nicht. Locale war bereits C.UTF-8, dialog war installiert - und die
Oberflaeche sah trotzdem falsch aus.
Grund: ncurses benutzt die VT100-Umschaltung AUCH mit UTF-8-Locale,
solange das terminfo sie anbietet - bei TERM=xterm der Fall. Die
Locale-Korrektur allein reichte deshalb nicht, und der Wechsel von
whiptail zu dialog machte es sogar schlechter, weil whiptail (slang)
bei UTF-8-Locale von sich aus Unicode zeichnet, ncurses aber nicht.
Abhilfe ist NCURSES_NO_UTF8_ACS=1. Mit dialog unter LANG=C.UTF-8 und
TERM=xterm gemessen:
ohne Schalter : 38 ESC(0, 0 Rahmenbytes, 182 rohe q
mit Schalter : 0 ESC(0, 220 Rahmenbytes, 0 rohe q
ui_init setzt den Schalter jetzt, sobald eine UTF-8-Locale gilt.
CMK_TUI_ACS=1 stellt das alte Verhalten wieder her - fuer Terminals, die
ESC(0 beherrschen, aber kein UTF-8.
tui-check zeigt den Stand des Schalters an und erklaert bei "A Linien,
B Buchstaben" jetzt, dass genau dieser Fall abgefangen wird und die
Oberflaeche trotzdem sauber aussehen muss.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1798,11 +1798,28 @@ und zeigen stattdessen die rohen Buchstaben.
|
|||||||
Nachgemessen: bei `LC_ALL=C` schickt `whiptail` eine `ESC(0`-Umschaltung und
|
Nachgemessen: bei `LC_ALL=C` schickt `whiptail` eine `ESC(0`-Umschaltung und
|
||||||
**91 rohe `q`**; mit UTF-8-Locale keine einzige.
|
**91 rohe `q`**; mit UTF-8-Locale keine einzige.
|
||||||
|
|
||||||
**Das Skript behebt das selbst.** Beim Start der Oberfläche setzt es
|
**Das Skript behebt das auf zwei Wegen selbst.**
|
||||||
|
|
||||||
|
**1. UTF-8-Locale.** Beim Start der Oberfläche setzt es
|
||||||
`LC_CTYPE` auf die erste verfügbare UTF-8-Locale (`C.UTF-8`, `en_US.UTF-8`, …).
|
`LC_CTYPE` auf die erste verfügbare UTF-8-Locale (`C.UTF-8`, `en_US.UTF-8`, …).
|
||||||
Nur `LC_CTYPE`, damit Sortierung und Zahlenformat unberührt bleiben. Ist
|
Nur `LC_CTYPE`, damit Sortierung und Zahlenformat unberührt bleiben. Ist
|
||||||
`LC_ALL` auf einen Nicht-UTF-8-Wert gesetzt, wird es dabei entfernt – sonst
|
`LC_ALL` auf einen Nicht-UTF-8-Wert gesetzt, wird es dabei entfernt – sonst
|
||||||
würde es `LC_CTYPE` aushebeln. Prüfen lässt sich das mit:
|
würde es `LC_CTYPE` aushebeln. **2. Unicode statt VT100.** Das allein genügt nicht: **ncurses benutzt die
|
||||||
|
VT100-Umschaltung auch mit UTF-8-Locale**, solange das terminfo sie anbietet –
|
||||||
|
bei `TERM=xterm` der Fall. Deshalb wird zusätzlich `NCURSES_NO_UTF8_ACS=1`
|
||||||
|
gesetzt, womit ncurses echte Unicode-Rahmenzeichen zeichnet. Mit `dialog` unter
|
||||||
|
`LANG=C.UTF-8` und `TERM=xterm` gemessen:
|
||||||
|
|
||||||
|
| | `ESC(0` | UTF-8-Rahmenbytes | rohe `q` |
|
||||||
|
|---|---|---|---|
|
||||||
|
| ohne Schalter | 38 | 0 | **182** |
|
||||||
|
| **mit Schalter** | **0** | **220** | **0** |
|
||||||
|
|
||||||
|
`whiptail` braucht das nicht – es zeichnet bei UTF-8-Locale von sich aus
|
||||||
|
Unicode. Wer den umgekehrten Fall hat – ein Terminal, das `ESC(0` beherrscht,
|
||||||
|
aber kein UTF-8 – stellt mit `CMK_TUI_ACS=1` das alte Verhalten wieder her.
|
||||||
|
|
||||||
|
Prüfen lässt sich das mit:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/cmk-manage.sh selftest # Abschnitt "Zeichensatz fuer die Oberflaeche"
|
./scripts/cmk-manage.sh selftest # Abschnitt "Zeichensatz fuer die Oberflaeche"
|
||||||
|
|||||||
+19
-2
@@ -1799,11 +1799,28 @@ instead.
|
|||||||
Measured: with `LC_ALL=C`, `whiptail` emits one `ESC(0` switch and **91 raw
|
Measured: with `LC_ALL=C`, `whiptail` emits one `ESC(0` switch and **91 raw
|
||||||
`q`** characters; with a UTF-8 locale, none at all.
|
`q`** characters; with a UTF-8 locale, none at all.
|
||||||
|
|
||||||
**The script fixes this itself.** When starting the interface it sets
|
**The script fixes this in two ways.**
|
||||||
|
|
||||||
|
**1. UTF-8 locale.** When starting the interface it sets
|
||||||
`LC_CTYPE` to the first available UTF-8 locale (`C.UTF-8`, `en_US.UTF-8`, …) –
|
`LC_CTYPE` to the first available UTF-8 locale (`C.UTF-8`, `en_US.UTF-8`, …) –
|
||||||
only `LC_CTYPE`, so sorting and number formats stay untouched. If `LC_ALL` is
|
only `LC_CTYPE`, so sorting and number formats stay untouched. If `LC_ALL` is
|
||||||
set to a non-UTF-8 value it is removed, since it would otherwise override
|
set to a non-UTF-8 value it is removed, since it would otherwise override
|
||||||
`LC_CTYPE`. Verify with:
|
`LC_CTYPE`. **2. Unicode instead of VT100.** That alone is not enough: **ncurses uses the
|
||||||
|
VT100 switch even with a UTF-8 locale** as long as the terminfo offers it –
|
||||||
|
which it does for `TERM=xterm`. So `NCURSES_NO_UTF8_ACS=1` is set as well,
|
||||||
|
making ncurses draw real Unicode box-drawing characters. Measured with
|
||||||
|
`dialog` under `LANG=C.UTF-8` and `TERM=xterm`:
|
||||||
|
|
||||||
|
| | `ESC(0` | UTF-8 box bytes | raw `q` |
|
||||||
|
|---|---|---|---|
|
||||||
|
| without the switch | 38 | 0 | **182** |
|
||||||
|
| **with the switch** | **0** | **220** | **0** |
|
||||||
|
|
||||||
|
`whiptail` does not need this – with a UTF-8 locale it draws Unicode by itself.
|
||||||
|
For the opposite case – a terminal that handles `ESC(0` but not UTF-8 –
|
||||||
|
`CMK_TUI_ACS=1` restores the old behaviour.
|
||||||
|
|
||||||
|
Verify with:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/cmk-manage.sh selftest # section "Zeichensatz fuer die Oberflaeche"
|
./scripts/cmk-manage.sh selftest # section "Zeichensatz fuer die Oberflaeche"
|
||||||
|
|||||||
@@ -4692,6 +4692,8 @@ cmd_tui_check() {
|
|||||||
printf ' LC_CTYPE : %s\n' "${LC_CTYPE:-<leer>}"
|
printf ' LC_CTYPE : %s\n' "${LC_CTYPE:-<leer>}"
|
||||||
printf ' Zeichensatz : %s\n' "$(locale charmap 2>/dev/null || echo unbekannt)"
|
printf ' Zeichensatz : %s\n' "$(locale charmap 2>/dev/null || echo unbekannt)"
|
||||||
printf ' Programm : %s\n' "${UI_BIN:-keines (dialog/whiptail fehlt)}"
|
printf ' Programm : %s\n' "${UI_BIN:-keines (dialog/whiptail fehlt)}"
|
||||||
|
printf ' Unicode-ACS : %s\n' \
|
||||||
|
"$([ -n "${NCURSES_NO_UTF8_ACS:-}" ] && echo 'ein (ncurses zeichnet Unicode)' || echo 'aus (ncurses nutzt ESC(0)')"
|
||||||
[ -n "${UI_LOCALE_NOTE:-}" ] && printf ' Angepasst : %s\n' "$UI_LOCALE_NOTE"
|
[ -n "${UI_LOCALE_NOTE:-}" ] && printf ' Angepasst : %s\n' "$UI_LOCALE_NOTE"
|
||||||
|
|
||||||
printf '\n%sZeile A - echte UTF-8-Rahmenzeichen%s\n' "$C_BLD" "$C_RST"
|
printf '\n%sZeile A - echte UTF-8-Rahmenzeichen%s\n' "$C_BLD" "$C_RST"
|
||||||
@@ -4711,8 +4713,13 @@ ${C_BLD}Auswertung${C_RST}
|
|||||||
Alles in Ordnung - die Oberflaeche muss sauber aussehen.
|
Alles in Ordnung - die Oberflaeche muss sauber aussehen.
|
||||||
|
|
||||||
A zeigt Linien, B zeigt lqqqk / x / mqqj
|
A zeigt Linien, B zeigt lqqqk / x / mqqj
|
||||||
Das Terminal macht die VT100-Umschaltung nicht mit.
|
Das Terminal macht die VT100-Umschaltung nicht mit - der
|
||||||
Genau das ist der PuTTY-Fall. Abhilfe in PuTTY:
|
PuTTY-Fall. Das Skript faengt das ab: es setzt
|
||||||
|
NCURSES_NO_UTF8_ACS=1, womit ncurses (und damit dialog)
|
||||||
|
dieselben Zeichen wie in Zeile A verwendet. Die Oberflaeche
|
||||||
|
muss dadurch sauber aussehen, obwohl Zeile B es nicht tut.
|
||||||
|
|
||||||
|
Sieht sie trotzdem falsch aus, hilft in PuTTY:
|
||||||
Window -> Translation -> Remote character set: UTF-8
|
Window -> Translation -> Remote character set: UTF-8
|
||||||
Window -> Translation -> Handling of line drawing characters:
|
Window -> Translation -> Handling of line drawing characters:
|
||||||
"Use Unicode line drawing code points"
|
"Use Unicode line drawing code points"
|
||||||
|
|||||||
+23
-1
@@ -308,12 +308,33 @@ ui_calc_text() { # text zusatzzeilen
|
|||||||
# Nachgemessen: bei LC_ALL=C schickt whiptail eine ESC(0-Umschaltung und
|
# Nachgemessen: bei LC_ALL=C schickt whiptail eine ESC(0-Umschaltung und
|
||||||
# 91 rohe "q"; mit UTF-8-Locale keine einzige. Es genuegt, LC_CTYPE zu
|
# 91 rohe "q"; mit UTF-8-Locale keine einzige. Es genuegt, LC_CTYPE zu
|
||||||
# setzen - Sortierung und Zahlenformat bleiben damit unberuehrt.
|
# setzen - Sortierung und Zahlenformat bleiben damit unberuehrt.
|
||||||
|
# Zwingt ncurses zu echten Unicode-Rahmenzeichen.
|
||||||
|
#
|
||||||
|
# Auch mit UTF-8-Locale benutzt ncurses die VT100-Umschaltung ESC(0,
|
||||||
|
# solange das terminfo sie anbietet (bei TERM=xterm der Fall). Terminals
|
||||||
|
# im UTF-8-Modus - PuTTY - machen die nicht mit und zeigen q, x, l, m.
|
||||||
|
# Gemessen mit dialog unter LANG=C.UTF-8, TERM=xterm:
|
||||||
|
# ohne Schalter : 38 ESC(0, 0 Rahmenbytes, 182 rohe q
|
||||||
|
# mit Schalter : 0 ESC(0, 220 Rahmenbytes, 0 rohe q
|
||||||
|
# whiptail (slang) braucht ihn nicht, es zeichnet bei UTF-8-Locale schon
|
||||||
|
# von sich aus Unicode.
|
||||||
|
ui_use_unicode_acs() {
|
||||||
|
# CMK_TUI_ACS=1 erzwingt umgekehrt das alte Verhalten - fuer
|
||||||
|
# Terminals, die ESC(0 koennen, aber kein UTF-8.
|
||||||
|
if [ -n "${CMK_TUI_ACS:-}" ]; then
|
||||||
|
unset NCURSES_NO_UTF8_ACS 2>/dev/null || true
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
export NCURSES_NO_UTF8_ACS=1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
ui_fix_locale() {
|
ui_fix_locale() {
|
||||||
[ -n "${UI_LOCALE_DONE:-}" ] && return 0
|
[ -n "${UI_LOCALE_DONE:-}" ] && return 0
|
||||||
UI_LOCALE_DONE=1
|
UI_LOCALE_DONE=1
|
||||||
UI_LOCALE_NOTE=""
|
UI_LOCALE_NOTE=""
|
||||||
case "${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" in
|
case "${LC_ALL:-${LC_CTYPE:-${LANG:-}}}" in
|
||||||
*UTF-8*|*utf-8*|*UTF8*|*utf8*) return 0 ;;
|
*UTF-8*|*utf-8*|*UTF8*|*utf8*) ui_use_unicode_acs; return 0 ;;
|
||||||
esac
|
esac
|
||||||
local l
|
local l
|
||||||
for l in C.UTF-8 C.utf8 en_US.UTF-8 en_US.utf8 de_DE.UTF-8 de_DE.utf8; do
|
for l in C.UTF-8 C.utf8 en_US.UTF-8 en_US.utf8 de_DE.UTF-8 de_DE.utf8; do
|
||||||
@@ -323,6 +344,7 @@ ui_fix_locale() {
|
|||||||
if [ -n "${LC_ALL:-}" ]; then unset LC_ALL; fi
|
if [ -n "${LC_ALL:-}" ]; then unset LC_ALL; fi
|
||||||
export LC_CTYPE="$l"
|
export LC_CTYPE="$l"
|
||||||
UI_LOCALE_NOTE="LC_CTYPE auf $l gesetzt (war nicht UTF-8)"
|
UI_LOCALE_NOTE="LC_CTYPE auf $l gesetzt (war nicht UTF-8)"
|
||||||
|
ui_use_unicode_acs
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user