Konfiguracja polskiej klawiatury w X-serwerach XFree86 z użyciem rozszerzenia XKB


Copyright © 2001 by Marcin Woliński
2001/08/11

Najpierw wyjaśnijmy(?) tytuł. Zapewne wszyscy wiedzą, że XFree86 to implementacja X Window dostępna (m.in.) pod Linuksem. Poniższy opis dotyczy XFree86 co najmniej w wersji 3.3.x i 4.x. XKEYBOARD (w skrócie XKB) jest rozszerzeniem X-protokołu pozwalającym na lepszą obsługę klawiatury. X-serwer i biblioteki dostarczane przez XFree są świadome istnienia tego rozszerzenia.

Konfiguracji klawiatury dokonuje się przez umieszczenie odpowiednich zapisów w sekcji Keyboard pliku XF86Config (plik ten w wielu systemach znajduje się w katalogu /etc/X11/; plik konfiguracyjny wersji 4.x XFree86 nazywa się zwykle XF86Config-4).

Oto rozsądna sekcja Keyboard, w której polski układ klawiatury został zadeklarowany jako domyślny:

Section "Keyboard"
    Protocol	"Standard"
    AutoRepeat	500 5
    XkbRules    "xfree86"
    XkbModel    "pc104"
    XkbLayout   "pl"
    XkbOptions  "grp:switch"
EndSection
	      

Objaśnienia: XkbModel "pc104" to klawiatura zawierająca obok Alt-ów klawisze z okienkami (do czego można je wykorzystać, zob. tutaj). W przypadku starszych klawiatur można ustawić model pc102. Wiersz XkbLayout "pl" oznacza oczywiście, że zostanie załadowany polski układ klawiatury. Jeżeli tylko niektórzy użytkownicy komputera oczekują polskiej klawiatury, można w tym miejscu wpisać coś innego np. us, czyli układ amerykański. Układ klawiatury można przełączać w czasie pracy X-serwera poleceniem setxkbmap, np. setxkbmap pl. Linijka XkbOptions "grp:switch" oznacza, że znaki narodowe (w tym przypadku polske) uzyskuje się za pomocą prawego klawisza Alt.

Jeszcze jeden istotny komentarz do przedstawionych wyżej ustawień: ponieważ chcemy użyć XKB, nie ma wśród nich zapisu XkbDisable wstawianego domyślnie przez niektóre programy konfiguracyjne.

Po wprowadzeniu opisanych wyżej zapisów do pliku XF86Config (oczywiście wymaga to uprawnień administratora systemu) proponujemy uruchomić X Window i przetestować konfigurację za pomocą programu xev.

W tym celu najlepiej użyć naszej wersji programu xev. Wersja ze standardowej dystrybucji z tajemniczych przyczyn nie jest wrażliwa na ustawienia locale, czyli znakomicie nadaje się do testowania klawiatury, ale tylko angielskiej. Szkoda. [Wersję świadomą locale można też przygotować samodzielnie. Wystarczy pobrać standardowe źródła programu xev, dodać jako pierwszą instrukcję w funkcji main() następującą linijkę: setlocale(LC_CTYPE, ""); i przekompilować.]

A oto nasz test:

bash
export LANG=pl_PL
LC_ALL=
./xev-lc-aware
	      

Program xev raportuje na terminalu, z którego został uruchomiony, wszystkie docierające do niego zdarzenia, w szczególności te z klawiatury. Jeżeli konfiguracja się powiodła, po naciśnięciu prawego klawisza Alt powinniśmy zobaczyć:

KeyPress event, serial 24, synthetic NO, window 0x5800001,
    root 0x25, subw 0x0, time 1096502691, (545,357), root:(677,510),
    state 0x0, keycode 113 (keysym 0xff7e, Mode_switch), same_screen YES,
    XLookupString gives 0 characters:  ""
	      

W zapisie tym istotne jest, że klawiszowi o kodzie 113 odpowiada symbol Mode_switch.

Natomiast klawisze odpowiedzialne za polskie znaki (Alt_R-a, Alt_R-c, ...) powinny generować napisy podobne do poniższego:

KeyPress event, serial 24, synthetic NO, window 0x5800001,
    root 0x25, subw 0x0, time 1096730911, (461,573), root:(593,726),
    state 0x2000, keycode 38 (keysym 0x1b1, aogonek), same_screen YES,
    XLookupString gives 1 characters:  "ą"
	      

W tym zapisie istotne jest pojawianie się symboli (keysym), które nazywają polskie znaki, oraz to, że funkcja XLookupString produkuje odpowiadające im znaki. (Oczywiście trzeba mieć ustawiony w terminalu polski font, żeby się one wyświetlały poprawnie).

Ten stan nazywamy dobrze skonfigurowanym X-serwerem. Stanowi on warunek konieczny, ale nie wystarczający poprawnego działania aplikacji, a to ze względu na Złotą Zasadę Programowania Dla X Window:

Program, który otwiera choć jedno okienko, musi być wrażliwy na locale. W przeciwnym wypadku będzie w stanie odebrać z klawiatury jedynie znaki alfabetu angielskiego.

To zaś pociąga za sobą Złotą Zasadę Numer Dwa:

Poprawnie napisany, a więc wrażliwy na locale, program dla X Window będzie poprawnie działał po polsku, tylko jeżeli zastanie locale ustawione na polskie.

Trzeba zatem sprawić, by wszystkie zainteresowane procesy uruchamiane pod X Window widziały w swoim środowisku np. takie ustawienie:

export LANG=pl_PL
	      

Zwracam uwagę na słowo wszystkie. Oznacza ono, że ustawienie locale musi nastąpić odpowiednio ,,wcześnie''. Jeżeli uruchamia się X Window poleceniem startx, a więc z shella, wystarczy umieścić powyższą linijkę w pliku startowym tego shella, np. ~/.profile. Jeżeli jednak korzystamy z tzw. graficznego loginu (xdm, gdm, kdm, itdm.), to część naszych procesów nie będzie miała jako rodzica żadnego shella, który mógłby przeczytać ~/.profile. W takim przypadku trzeba odnaleźć jakąś możliwość w procesie otwierania sesji X. Na przykład, jeżeli używamy desktopu Gnome, dobrym miejscem jest plik ~/.gnomerc.

Bieżące ustawienie locale można sprawdzić, wydając polecenie locale. Powinno to spowodować wyświetlenie komunikatu zawiadamiającego, że rozmaite tzw. kategorie locale są ustawione na pl_PL.

Wiąże się z tym jednak pewna pułapka. Jeżeli wydamy polecenie locale ,,w okienku xterma'', w istocie dowiemy się, jak jest ustawione locale w interpreterze poleceń pracującym ,,wewnątrz'' tego okienka (np. bashu) a nie w samym xtermie, który może mieć je ustawione inaczej (np. dlatego, że skrypt startowy interpretera zmienił zmienną LANG). Tymczasem dla poprawnego działania polskiej klawiatury ,,w xtermie'' on sam musi mieć poprawne ustawienie locale, a nie pracujący w nim interpreter poleceń. Podsumowując: polecenie locale może pomóc wykryć błędne ustawienie locale, ale nie pozwala udowodnić, że ustawienie jest poprawne.

Niektóre programy, poza ustawieniem LANG wymagają oddzielnej konfiguracji. Testy aplikacji proponujemy więc zacząć np. od Emacsa 20, który takich ustawień nie wymaga. W przypadku basha potrzebne są wpisy w plku ~/.inputrc aby zechciał on w ogóle czytać 8-bitowe znaki.

Nie od rzeczy będzie też kilka słów o niepoprawnych, czyli niewrażliwych na locale programach dla X Window. Otóż Złota Zasada Programowania wynika z tego, że większość programów pobiera znaki z klawiatury za pomocą funkcji Xlib o nazwie XLookupString. Funkcja ta sama jest wrażliwa na ustawienie locale. Dlatego jeżeli program nie zawiera w swojej części inicjalizacyjnej uaktywnienia mechanizmu locale, to XLookupString będzie reagować tylko na znaki z domyślnego zestawu ISO Latin-1.

Wnioski praktyczne są dwa: Po pierwsze, ku pożytkowi wszystkich użytkowników kodów różnych od ISO Latin-1 powinniśmy uświadamiać powyższe autorom niepoprawnych programów. (Szczęśliwie mamy w tym sojuszników w dużych grupach użytkowników np. kodów cyrylicznych.)
Po drugie, mając kod źródłowy programu, często można poprawić go samodzielnie (nawet nie umiejąc programować). Wystarczy (!) odnaleźć plik zawierający definicję funkcji main() i dopisać do niego jako pierwszy wiersz:

#include <locale.h>
	      

oraz jako pierwszą instrukcję funkcji main() (a więc bezpośrednio po deklaracjach zmiennych wewnątrz main):

setlocale(LC_CTYPE, "");
	      

i wreszcie przekompilować program (zwykle wystarczy wydać polecenie make).

Send mail to Marcin Woliński Strona wiodąca Linuksowe drobiazgi Color Free Zone certified page