Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

kbd_mode

4 views
Skip to first unread message

Helmut Hullen

unread,
Apr 7, 2013, 1:25:00 PM4/7/13
to
Hallo alle miteinander,

woher beziehen "kbd_mode" und "kbdinfo" ihre Informationen, dass/ob das
System ASCII oder UTF-8 (xlate oder unicode) benutzt?

Irgendwo muss das ja wohl vor-eingestellt sein (auch dann, wenn
nirgendwo förmlich "kbd_mode -a" oder "kbd_mode -u" gesetzt wurde), aber
noch habe ich diese Stelle nicht gefunden.

Viele Gruesse
Helmut

"Ubuntu" - an African word, meaning "Slackware is too hard for me".

Christoph 'Mehdorn' Weber

unread,
Apr 8, 2013, 10:32:51 AM4/8/13
to
Hallo!

* Helmut Hullen <Hel...@Hullen.de>:

> woher beziehen "kbd_mode" und "kbdinfo" ihre Informationen, dass/ob das
> System ASCII oder UTF-8 (xlate oder unicode) benutzt?

Im Debian-Paket gibt es das Binary "vt-is-UTF8", das unter
anderem vom ebenfalls enthaltenen "unicode-start" benutzt wird.
Ich kann mir durchaus vorstellen, daᅵ kbd_mode -- ebenfalls in
diesem Paket -- eine gemeinsame Funktion mit "vt-is-UTF8" benutzt.

Im Prinzip funktioniert "vt-is-UTF8" jedenfalls so, daᅵ die
aktuelle Cursorposition ermittelt und danach ein Multibyte-Zeichen
ausgegeben wird. Ist die Cursorposition dann sehr viel weiter
rechts als man bei UTF-8 erwarten wᅵrde, handelt es sich offenbar
nicht um ein UTF-8-Terminal.

Ist das Terminal zu dumm, die Cursorposition zu verraten,
funktioniert die Methode nicht.


Ein "kbdinfo" hab ich hier nicht und mag es gerade nicht
nachinstallieren.


> Irgendwo muss das ja wohl vor-eingestellt sein (auch dann, wenn
> nirgendwo fᅵrmlich "kbd_mode -a" oder "kbd_mode -u" gesetzt
> wurde), aber noch habe ich diese Stelle nicht gefunden.

Ich nehme an, der Kernel stellt einmalig ein. Zumindest kann man
es nachtrᅵglich per SysRq ("r") beeinflussen.

Christoph

--
Und die Feder ist maechtiger als das Schwert - aber nur wenn
es sich um eine ungewoehnlich grosse und spitze Feder handelt.
(Dietz Proepper)

Helmut Hullen

unread,
Apr 8, 2013, 11:24:00 AM4/8/13
to
Hallo, Christoph,

Du meintest am 08.04.13:

>> woher beziehen "kbd_mode" und "kbdinfo" ihre Informationen, dass/ob
>> das System ASCII oder UTF-8 (xlate oder unicode) benutzt?

> Im Debian-Paket gibt es das Binary "vt-is-UTF8", das unter
> anderem vom ebenfalls enthaltenen "unicode-start" benutzt wird.
> Ich kann mir durchaus vorstellen, da� kbd_mode -- ebenfalls in
> diesem Paket -- eine gemeinsame Funktion mit "vt-is-UTF8" benutzt.

Da w�re ich eher skeptisch (ohne dass ich Deine Vermutung widerlegen
k�nnte); im Quellcode von "kbd_mode.c" scheint der folgende Abschnitt
wichtig zu sein:

fd = getfd(console);

if (n == 0) {
/* report mode */
if (ioctl(fd, KDGKBMODE, &mode)) {
perror("KDGKBMODE");
fprintf(stderr, _("kbd_mode: error reading keyboard mode\n"));
exit(1);
}
switch(mode) {
case K_RAW:
printf(_("The keyboard is in raw (scancode) mode\n"));
break;
case K_MEDIUMRAW:
printf(_("The keyboard is in mediumraw (keycode) mode\n"));
break;
case K_XLATE:
printf(_("The keyboard is in the default (ASCII) mode\n"));
break;
case K_UNICODE:
printf(_("The keyboard is in Unicode (UTF-8) mode\n"));
break;
default:
printf(_("The keyboard is in some unknown mode\n"));
}
exit(0);
}

-------------------------------------
So �hnlich: der Abschnitt in "kbdinfo.c":

fd = getfd(console);

if (!strcasecmp("GETMODE", action)) {
if (ioctl(fd, KDGETMODE, &mode) == -1)
error(EXIT_FAILURE, errno, "ioctl");

switch (mode) {
case KD_TEXT: rc = answer("text"); break;
case KD_GRAPHICS: rc = answer("graphics"); break;
}

} else if (!strcasecmp("GKBMODE", action)) {
if (ioctl(fd, KDGKBMODE, &mode) == -1)
error(EXIT_FAILURE, errno, "ioctl");

switch (mode) {
case K_RAW: rc = answer("raw"); break;
case K_XLATE: rc = answer("xlate"); break;
case K_MEDIUMRAW: rc = answer("mediumraw"); break;
case K_UNICODE: rc = answer("unicode"); break;
}

---------------------------------------


wobei ich die einzelnen Zeilen zwar lesen kann, aber nicht so recht
weiss, was da in welcher Weise ausgewertet wird.

"KDGKBMODE" ist u.a. in

http://www.linuxjournal.com/article/2783

erl�utert (und da taucht auch "VT" wieder auf) ...

Aber: bisher habe ich noch nicht gefunden, wo der Startwert f�r
"kbd_mode" gesetzt wird; die o.g. Routinen zeigen nur, wie er ausgelesen
werden kann.

>> Irgendwo muss das ja wohl vor-eingestellt sein (auch dann, wenn
>> nirgendwo f�rmlich "kbd_mode -a" oder "kbd_mode -u" gesetzt
>> wurde), aber noch habe ich diese Stelle nicht gefunden.

> Ich nehme an, der Kernel stellt einmalig ein. Zumindest kann man
> es nachtr�glich per SysRq ("r") beeinflussen.

Hmmm - das sieht nach einem anderen Spezialprogramm aus, vielleicht auch
nach einer Spezialit�t einzelner Distributionen.

Rene Scholz

unread,
Apr 9, 2013, 3:51:07 AM4/9/13
to
Christoph 'Mehdorn' Weber <spam...@das-mehdorn.de> wrote:
> Hallo!
>
> * Helmut Hullen <Hel...@Hullen.de>:
>
>> woher beziehen "kbd_mode" und "kbdinfo" ihre Informationen, dass/ob das
>> System ASCII oder UTF-8 (xlate oder unicode) benutzt?
>
> Im Debian-Paket gibt es das Binary "vt-is-UTF8", das unter
> anderem vom ebenfalls enthaltenen "unicode-start" benutzt wird.
> Ich kann mir durchaus vorstellen, daᅵ kbd_mode -- ebenfalls in
> diesem Paket -- eine gemeinsame Funktion mit "vt-is-UTF8" benutzt.
>
> Im Prinzip funktioniert "vt-is-UTF8" jedenfalls so, daᅵ die
> aktuelle Cursorposition ermittelt und danach ein Multibyte-Zeichen
> ausgegeben wird. Ist die Cursorposition dann sehr viel weiter
> rechts als man bei UTF-8 erwarten wᅵrde, handelt es sich offenbar
> nicht um ein UTF-8-Terminal.
>
> Ist das Terminal zu dumm, die Cursorposition zu verraten,
> funktioniert die Methode nicht.

Hi,

genau ein solches Tool suche ich fᅵr X11-Terminals (rxvt, mrxvt, XFCE-Terminal etc.).
Ich gehe oft per SSH von unterschiedlichen Systemen auf unterschiedliche Systeme.

Wenn mein gerade benutztes Terminal UTF-8 unterstᅵtzt (und das Zielsystem entsprechende
Locales hat), wᅵrde ich das gerne erkennen kᅵnnen, damit ich in der .profile
ein "LANG=de_DE.UTF-8" machen kann (oder ein "LANG=de_DE", falls das Terminal kein
UTF-8 unterstᅵtzt).

Ich habe schon mehrmals nach sowas gesucht, aber bisher nur dieses gefunden:

http://unix.stackexchange.com/questions/10698/timing-out-in-a-shell-script

Gibt es da nicht schᅵneres?

Danke,
rene
--
Renᅵ Scholz, Intershop Consulting
Intershop Communications AG, Intershop Tower, 07740 Jena, GERMANY
Tel +49-3641-503485, Fax +49-3641-503222, http://www.intershop.de/

Christoph 'Mehdorn' Weber

unread,
Apr 13, 2013, 4:21:50 PM4/13/13
to
Hallo!

* Rene Scholz <r.sc...@intershop.de>:

> Ich gehe oft per SSH von unterschiedlichen Systemen auf
> unterschiedliche Systeme.
>
> Wenn mein gerade benutztes Terminal UTF-8 unterstᅵtzt (und das
> Zielsystem entsprechende Locales hat), wᅵrde ich das gerne
> erkennen kᅵnnen, damit ich in der .profile ein
> "LANG=de_DE.UTF-8" machen kann (oder ein "LANG=de_DE", falls das
> Terminal kein UTF-8 unterstᅵtzt).

Das Problem hatte ich auch hin und wieder, aber bisher keine
schᅵne Lᅵsung gefunden. Aktuelle Suche mit

| debtags search 'devel::i18n && (interface::commandline || interface::shell)'
| debtags search 'culture::* && (interface::commandline || interface::shell)'

bringen auch keine neuen Erkenntnisse. Wenn man erst einmal die
passende Locale eingestellt hat, ist 'language-env' mᅵglicherweise
hilfreich. Aber so weit muᅵ man erst kommen.

> Gibt es da nicht schᅵneres?

Mein bevorzugter Workaround ist es bisher, sich auf den
Umgebungsvariablen-Kopiermechanismus von SSH zu verlassen:
| $ grep Env /etc/ssh/ssh*_config
| /etc/ssh/ssh_config: SendEnv LANG LC_*
| /etc/ssh/sshd_config:AcceptEnv LANG LC_*

Typischerweise bekommt man die meisten Admins mit entsprechenden
Anfragen dazu, die benᅵtigten Einstellungen beim Server-sshd zu
tᅵtigen und die nᅵtigen Locales nachzuinstallieren -- oder man ist
selbst der Admin.

Allerdings muᅵ man beachten, daᅵ das Zielsystem die Variablen
dann nicht ᅵberschreibt. Bei Debian muᅵ man dazu beim
dpkg-reconfigure locales die Frage nach der Default-Locale mit
"None" beantworten oder manuell "schon gesetzt"-Tests in
/etc/default/locale einbauen (und darauf achten, daᅵ
/etc/environment nicht existiert/berᅵcksichtigt wird).


Das sind leider einige Bedingungen, damit es funktioniert.
Andererseits ist das Nicht-ᅵberschreiben der Variablen auch
ein guter Ansatz, um ein Script oder dergleichen zu bauen,
was deinem Wunsch zur Auswahl einer vorhandenen, geeigneten
Locale am Ziel vornimmt.

Meine Idee dazu war, die Variablen entsprechend zu prᅵfen. Was
nicht gesetzt ist oder auf 'C' oder 'POSIX' steht, darf so
bleiben. Gibt es ein LC_ALL, muᅵ man sich nur darum kᅵmmern. Der
Rest kᅵnnte Formate haben wie (keine sinnvolle Kombination):

| LANG=en_US.ISO-8859-1
| LC_MESSAGES=en_GB.UTF8
| LC_CTYPE=de_DE@euro

Soweit ich das Locale-System richtig verstanden habe, ist die
Groᅵ- und Kleinschreibung und das Vorhandensein von Bindestrichen
hinter dem Punkt egal -- zumindest auf meinem Debian.

Das kᅵnnte man dann mit den vorhandenen Locales abgleichen:
| $locale -a | grep de_DE
| de_DE
| de_DE.iso88591
| de_DE.iso885915@euro
| de_DE.utf8
| de_DE@euro

Wie man sieht, herrscht hier hinter dem Punkt offenbar immer
Kleinschreibung und es gibt keine Bindestriche. Die Umwandlung
kᅵnnte man mit "tr" erledigen, da das zumindest unter Debian ein
immer installiertes Standardtools sind. Damit kann man dann
zumindest schon gucken, ob eine bestimmte Locale unterstᅵtzt wird.

Dann kommt der komplizierte Teil: Wenn man z.B. das ᅵbermittelte
LANG=de_DE.UTF-8 zerlegt hat in "de_DE" und das wie oben umgebaute
"utf8", und man kein "de_DE.utf8" in der Ausgabe von "locale -a",
kann man es mit Fallbacks versuchen. Erste Idee: Am Unterstrich
auf "de_" kᅵrzen und gucken, welche Locales mit "de_" und ".utf8"
man findet. Ist es nur eine, nimmt man ebendiese. Sind es mehrere,
kᅵnnte man zufᅵllig wᅵhlen oder sortieren und immer die
erste/letzte. Gibt es keine, ist man erst einmal aufgeschmissen.

Nachdem mir die weitere Beschreibung zu kompliziert wurde, hab
ich mich an einem Shellscript namens "locale-fix" versucht:

#v+
#!/bin/dash
#

lfix () {
LFIX_CONFIG="$HOME/.locale-fixrc"
LFIX_FALLBACKS='en_US en_GB en_'
unset LFIX_IGNORE_LANG

if test -f "$LFIX_CONFIG"; then
. "$LFIX_CONFIG"
else
{
echo "# Configuration file for ${0##*/}"
echo
echo '# Locale fallback list (prefixes for locale names)'
echo "LFIX_FALLBACKS='$LFIX_FALLBACKS'"
echo
echo '# set to overwrite LANG with LC_ALL/LC_MESSAGES'
echo '# (useful if LANG get overwritten on ssh logins)'
echo '# LFIX_IGNORE_LANG=1'
} > "$LFIX_CONFIG"
fi

if test -n "$LFIX_IGNORE_LANG"; then
LANG=${LC_ALL:-LC_MESSAGES}
fi

for LFIX_VAR in \
LANG \
LC_ADDRESS \
LC_ALL \
LC_COLLATE \
LC_CTYPE \
LC_IDENTIFICATION \
LC_MEASUREMENT \
LC_MESSAGES \
LC_MONETARY \
LC_NAME \
LC_NUMERIC \
LC_PAPER \
LC_TELEPHONE \
LC_TIME \
; do
eval LFIX_VAL=\$$LFIX_VAR
if
test -z "$LFIX_VAL" -o 'C' = "$LFIX_VAL" -o 'POSIX' = "$LFIX_VAL"
then
# empty or C/POSIX, nothing to do
continue
fi

LFIX_LOC=${LFIX_VAL%%.*}
LFIX_ENC=${LFIX_VAL#*.}
if test "$LFIX_LOC" = "$LFIX_ENC"; then
# contained no dot
LFIX_ENC=''
else
# lowercase, remove dashes
LFIX_ENC=`echo $LFIX_ENC | tr A-Z a-z | tr -d -`
fi

# check if supported
if
# locale may croak on unsupported locales
locale -a 2>/dev/null |
grep --quiet "^$LFIX_LOC${LFIX_ENC:+[.]}$LFIX_ENC$"
then
# it is!
continue
else
if test -n "$1"; then
echo "Unsupported locale: $LFIX_VAR=$LFIX_LOC $LFIX_ENC"
fi
fi

# first fallback, try to remove the region
LFIX_LANG=${LFIX_VAL%%_*}
if test "$LFIX_LOC" != "$LFIX_LANG"; then
# region was removed
LFIX_LANGS=`
locale -a 2>/dev/null |
grep "^${LFIX_LANG}_.*${LFIX_ENC:+[.]}$LFIX_ENC$"
`
if test `echo "$LFIX_LANGS" | wc -l` -eq 1; then
# exactly one match, use it
if test -n "$1"; then
echo "Falling back to $LFIX_VAR=$LFIX_LANGS"
fi
eval $LFIX_VAR=$LFIX_LANGS
continue
fi
fi

# second fallback: use fallback list
for LFIX_LANG in $LFIX_FALLBACKS; do
LFIX_LANGS=`
locale -a 2>/dev/null |
grep "^$LFIX_LANG.*${LFIX_ENC:+[.]}$LFIX_ENC$" |
head -n 1
`
if test -n "$1"; then
echo "Falling back to $LFIX_VAR=$LFIX_LANGS"
fi
eval $LFIX_VAR=$LFIX_LANGS
continue 2
done
done

unset LFIX_CONFIG
unset LFIX_ENC
unset LFIX_FALLBACKS
unset LFIX_IGNORE_LANG
unset LFIX_LANG
unset LFIX_LANGS
unset LFIX_LOC
unset LFIX_VAL
unset LFIX_VAR
}

if test -z "$LFIX_DONE"; then
lfix $@
LFIX_DONE=1
export LFIX_DONE
fi

unset -f lfix
# vim: ft=sh
#v-

Unter Debian scheint es das zu tun, was ich oben beschrieben
habe, und beherrscht zusᅵtzlich eine Fallback-Liste mit
Sprachprᅵfixen. Wenn die auch versagt, sollte es nichts ᅵndern.
Ruft man es einfach so mit einem Parameter auf, zeigt es, was es
ᅵndern wᅵrde. Die Idee ist aber eigentlich, daᅵ man es per
"source" in der Shell, z.B. per .profile, einbindet. Erfolgreich
getestet habe ich es lokal mit dash und bash.

In "~/.fix-localerc" mag man vielleicht die Fallback-Variable
am Anfang um "de_DE de_" erweitern, damit es zunᅵchst auf deutsche
Varianten zurᅵckfᅵllt.

Wie man sieht, hab ich mir die Sonderbehandlung von LC_ALL
gespart. Eventuell wᅵre es auch sinnvoll, das so umzubauen, daᅵ
man es nicht mehr sourcen muᅵ, sondern die Variablen ausgibt und
dann per "eval" einliest. Dann kᅵnnte man jederzeit mit Exit raus,
statt alles in die Funktion zu pressen. Ich hᅵtte sogar mehrere
Funktionen benutzt, aber die muᅵ man beim Sourcen hinterher alle
wieder undefinieren, sonst hat man sie dauerhaft in der Shell, und
das macht das Script noch lᅵnger ...

Christoph

--
telnet ist vollkommen ueberladen. Das kann Mail, News, HTTP
und so weiter. Unix-Philosophie ist, dass man ein Tool fuer
genau eine Aufgabe benutzt. telnet ist was fuer Windows-Leute.
(Christian Garbs)
0 new messages