Linux Keyboard Setup Mini-Howto <author>Maintained by Stephen Lee, <htmlurl url="mailto:sl14@cornell.edu" name="<tt>sl14@cornell.edu</tt>"> <date>v1.3, 16 wrzesień 1995 <bf>Wersja polska: Gwidon S. Naskrent <htmlurl url="mailto:naskrent@hoth.amu.edu.pl" name="naskrent@hoth.amu.edu.pl"><newline> </bf> v1.0, luty 1998 <abstract> Ten dokument Mini-HOWTO opisuje konfigurację obsługi jądra i aplikacji tak aby obsługiwały klawisze kontrolne kursora </abstract> <sect>Wstęp<p> Było dla mnie denerwujące iż klawisze kursora nie pracują spójnie w różnych pogramach (i na różnych komputerach), tak więc poświęciłem nieco czasu i spróbowałem ponaprawiać je wszystkie. Tutaj dokumentuję swoje doświadczenia, tak aby inni nie potrzebowali przechodzić przez ten sam męczący cykl co ja. Używam Slackware 2.0.1, tak więc nazwy ścieżek do plików mogą się różnić od twoich, jeśli używasz innej dystrybucji. Część tutejszego materiału ukazała się we wcześniejszym "Backspace Mini-HOWTO". Chociaż metody tam opisane nadal działają, te uważam za lepsze rozwiązanie. <sect1>Typografia<p> <itemize> <item>To jest <tt/nazwa programu/. <item>To jest <verb>komenda</verb>, wpisywana z klawiatury <item>To jest (klawisz) na klawiaturze, np. (BackSpace), (Delete), (Shift-I), (Ctrl-Q) itd. <item>To jest [klawsym X11], którego użyć możesz odwzorowywując klawisze w X, np. [BackSpace], [Delete], [Left], [Home] itd. </itemize> <sect1>Terminologia<p> ESC - znak ASCII o kodzie 0x1B BS - znak ASCII o kodzie 0x08, albo control-h DEL - znak ASCII o kodzie 0x7F ^D - znak ASCII o kodzie 0x04, albo control-d. WK - Wirtualna Konsola Linuxa <sect1>Podziękowania<p> Dziękuję następującym osobom które nadesłały komentarze co do mojego "BackSpace Mini-HOWTO": John Copella, Andrew Rakowski, Dr. Jacques Gelinas, Michael Bischoff, Topher Hughes, Chuck Meyer, Alexis Kotte, a szczególnie Ted Stern oraz Steve Dunham. Dziękuję Jamie Zawinskiemu z Netscape Communications za wskazanie prawiłowego rozwiązania problemu wstecznej spacji w aplikacjach Motifowych, oraz za program xkeycaps(1). <sect>Konfiguracja nie-Xowa<p> Zakładam że przyszedłeś ze świata DOSu tak jak ja, i przywykły jesteś do takiego odwzorowywania klawiszy iż <BackSpace> kasuje znak na lewo od kursora a <Delete> kasuje znak nad (pod) kursorem. Wewnątrz powłoki najbardziej intuicyjnym odwzorowaniem jest <BackSpace> -> BS oraz (Delete) -> Del. Wszystko pięknie dopóki nie zechcesz używać emacsa. Emacs przypisuje (Ctrl-H) swojej funkcji pomocy, która to kombinacja, w ASCII, to niestety wsteczna spacja. Za każdym razem więc kiedy chcesz usunąć znak w tył, wywołujesz system pomocy. DEL w emacsie kasuje W TYŁ, tak jak spodziewałbyś się po BS. Jednym z wyborów jest przemapowanie klawiszy w emacsie. Niestety stracisz odwzorowanie <Ctrl-H> = help. Tak więc zdecydowałem się mapować <BackSpace> -> DEL. Pozostawia to BS na użytek <Ctrl-H>] w emacsie. Cóż więc uczynimy z klawiszem (Delete)? W poprzedniej wersji tego dokumentu używałem ^D, co działa i w emacsie, i w csh/tcsh jako funkcja "skasuj znak pod kursorem". Ale od tamtego czasu znalazłem lepsze rozwiązanie. Jądro domyślnie przypisuje (Delete) jako sekwencję klawiszy "Remove" terminala vt100 ("ESC[3~"). Niejest trudno nauczyć emacsa i tcsh aby ją rozpoznawały. Ma to ten pożytek że możesz ją przypisać inaczej niż do (Ctrl-D) w programach. Jest też bardziej spójna jeśli inaczej przypisujesz także inne klawisze kontrolne kursora. Niedogodnością jest to że możesz nie być zdolny użyć jej w pewnych aplikacjach w których nie możesz przypisywać sekwencji klawiszy (ale to odnosi się także do przypisania (Delete) = ^D). <sect1>Konsola linuxa<p> Przypisania klawiszy na konsoli Linuxa kontroluje jądro. Jądro domyślnie wypisuje poprawne przypisania dla (Backspace) i (Delete), więc nie powinieneś potrzebować tego zmieniać. Jednakże jeśli tak robisz, na przypisania klawiszy wpływają następujące programy (w pakiecie <tt/kbd/, który powinien znajdować się już w dystrybucji Slackware). <verb> <tt/showkeys/ "showkeys" pokazuje skankod linuxowy który wypisuje klawisz. Ów kod skanowy może zostać następnie użyty przez loadkeys(1) do zmiany układu klawiatury. <tt/dumpkeys/ Pokazuje bieżące przypisania klawiszy. Patrz manpage po szczegóły. <tt/loadkeys/ "loadkeys plik" ładuje przypisania klawiszy z pliku "plik". Zauważ że zmienia to przypisania klawiszy WSZYSTKICH wirtualnych konsol. Zwykle dokonywa się tego w czasie ładowania systemu w <tt>/etc/rc.d/rc.local</tt>. Zacząc możesz od jednego z plików układów klawiatury w <tt>/usr/lib/kbd/keytables/*.map</tt> i wyedytować je. Ta która wkompilowana jest w kernel to <tt>/usr/src/linux/drivers/char/defkeymap.map</tt>, jeśli posiadasz źródła jądra. Format pliku opisany jest w keytables(5). Klawisze szczególnie nas interesujące to (BackSpace), o skankodzie 14, oraz (Delete), o kodzie skanowym 111. <tt/setmetamode/ "setmetamode" kontroluje czy naciśnięcie klawiszy (Alt-x), gdzie x to jakiś klawisz, pośle kod klawisza M-x czy sekwencję klawiszy ESC plus x. Jest to zależne od wirtualnej konsoli; możesz mieć różne ustawienia na różnych konsolach. </verb> <sect1>tty (w tym konsola Linuxa)<p> "stty erase (k)" mówi terminalowi jaki znak wypisuje twój klawisz (BackSpace). NIE zmienia to przypisań klawiszy. Jeśli przypiszesz (Backspace) do DEL, a potem wykonasz "stty erase ^H", nie zmieni to automagicznie twojego klawisza (BackSpace) aby wypisywał ^H; zamiesza tylko w głowie komputerowi. Aby poprawnie ustawić klawisz "erase" twojego terminala na DEL, wpisz "stty erase ^?", gdzie ^? może być ^ plus ?, albo (Ctrl-V)(BackSpace) w linii komend powłoki. Możesz chcieć umieścić to w swoim pliku <tt>$(HOME)/.cshrc</tt> lub <tt>$(HOME)/.profile</tt>. Uwaga: chociaż csh/tcsh traktuje BS i DEL w ten sam sposób, inne programy tak nie robią. Tak więc twój układ może wydawać się działać pod csh/tcsh, ale w niektórych programach otrzymywać będziesz dziwne rezultaty w rodzaju ^?. Rozwiązanie: pamiętaj o komendzie "stty" jak wyżej. <sect1>Powłoki<p> <sect2>tcsh<p> tcsh dostarcza komendy "bindkey" dla przypisywania klawiszy: <verb> <tt/bindkey/ wypisuje wszystkie bieżące przypisania <tt/bindkey "ciąg" funkcja/ przypisuje ciąg wejściowy "ciąg" funkcji. Listę funkcji tcsh otrzymać można poprzez "bindkey -l". <tt/bindkey -k <up | down | left | right> funkcja/ przypisuje klawisz strzałkowy funkcji. </verb> Przykład: aby przypisać klawisze ruchu kursora, wstaw poniższe do <tt>$HOME/.cshrc</tt>: <tscreen><verb> if ($term == "xterm" || $term == "vt100" \ || $term == "vt102" || $term !~ "con*") then # przypisz klawisze z numerycznej dla console, vt100, vt102, \ xterm bindkey "\e[1~" beginning-of-line # Home bindkey "\e[2~" overwrite-mode # Ins bindkey "\e[3~" delete-char # Delete bindkey "\e[4~" end-of-line # End endif </verb></tscreen> Zobacz manpage dla tcsh(1) co do szczegółowego opisu. Przykład: możesz mieć w tcsh historię komend w stylu 4DOS używając pary funkcji tcsh history-search-backward (Meta-P) oraz history-search- forward (Meta-N). Wpisanie "abc(Meta-P)" pokaże tylko linie w historii zaczynające się od "abc". Funkcja magic-space rozszerza !-historie w trakcie pisania, a ja wolę je od wartości domyślnych, tak więc przypisałem je do klawiszy strzałek góra/dół oraz spacji: <tscreen><verb> bindkey -k up history-search-backward bindkey -k down history-search-forward bindkey " " magic-space </verb></tscreen> <sect2>bash<p> Plik <tt/.inputrc/ zawiera listę przypisań klawiszy do funkcji. Na przykład, jeśli wstawisz poniższe linie do <tt>$HOME/.inputrc</tt>: <tscreen><verb> "\e[1~": beginning-of-line "\e[3~": delete-char "\e[4~": end-of-line </verb></tscreen> przemapuje ona klawisze (Home), (Delete) oraz (End), odpowiednio, na odpowiednie funkcje. Możesz także chcieć użyć poniższej linii, jeśli twój klawisz (BackSpace) wysyła znak DEL ASCII: <tscreen><verb> DEL: backward-delete-char </verb></tscreen> Nie będziesz tego zapewne potrzebował (ja nie), ale warto tego spróbować jeśli wpakujesz się w kłopoty. <sect1>Edytory<p> <sect2>Emacs 19<p> Emacs 19 dostarcza funkcji elispowej define-key do przypisywania klawiszy. Możesz przypisać sekwencję klawiszy do klawisza funkcyjnego jak poniżej, w <tt>$HOME/.emacs</tt>: <tscreen><verb> ;; przypisz klawisze funkcyjne na klawiaturze PC (setq term (getenv "TERM")) (if (or (string= "xterm" term) (string= "con" (substring term 0 3)) ; konsole Linuxa (string= "vt100" term) (string= "vt102" term)) (progn (defun my-setkey-hook () (define-key function-key-map "\e[1~" [home]) (define-key function-key-map "\e[2~" [insert]) (define-key function-key-map "\e[3~" [delete]) (define-key function-key-map "\e[4~" [end]) ;; to są moje własne sekwencje ;; tak aby mógł używać tych klawiszy w Emacsie (define-key function-key-map "\e[40~" [C-prior]) (define-key function-key-map "\e[41~" [C-next]) ;; klawisze funkcyjne; użyj takiego układu jak w xtermie (define-key function-key-map "\e[11~" [f1]) (define-key function-key-map "\e[12~" [f2]) ;; ... (define-key function-key-map "\e[24~" [f12]) (define-key function-key-map "\e[25~" [S-f1]) (define-key function-key-map "\e[26~" [S-f2]) ;; ... (define-key function-key-map "\e[39~" [S-f12]) ) (add-hook 'term-setup-hook 'my-setkey-hook) ) () ) </verb></tscreen> Zauważ że nazwy klawiszy funkcyjnych pisane są małymi literami. Możesz także przypisywać klawisze funkcyjne (albo sekwencje klawiszy, ale nie będziemy tego tu używać) komendom emacsowym używając global-set-key, tak jak tu: <tscreen><verb> (global-set-key [delete] 'delete-char) (global-set-key [home] 'beginning-of-line) ; możesz nie chcieć tego (global-set-key [end] 'end-of-line) ; ani tego (global-set-key [C-prior] 'beginning-of-buffer) (global-set-key [C-next] 'end-of-buffer) (global-set-key [f1] 'help-for-help) ;; ... (global-set-key [S-f12] 'info) </verb></tscreen> <sect2>vi<p> Czy ktoś chce to napisać? <sect1>Inne programy<p> <sect2>less<p> lesskey(1) pozwala zmienić układ klawiszy dla pagera less(1). Wstaw poniższe linie do swojego <tt>$HOME/.lessrc</tt> (dla terminali podobnych do vt100): <tscreen><verb> ^[[A back-line ^[[B forw-line ^[[C next-file ^[[D prev-file ^[OA back-line ^[OB forw-line ^[OC next-file ^[OD prev-file ^[[6~ forw-scroll ^[[5~ back-scroll ^[[1~ goto-line ^[[4~ goto-end </verb></tscreen> zastępując "^[" znakiem ESC (ASCII 0x1B), potem wykonaj <tt>lesskey ~/.lessrc"</tt>, Możesz już używać klawiszy kursora do przewijania tekstu w less(1). <sect>Konfiguracja X<p> W systemie X Windows każdy klawisz może mieć przypisany mu odmienny klawsym, zamiast po prostu wartości ASCII czy sekwencji klawiszy. Tak więc aplikacje Xowe mogą łatwo rozróżnić między, na przykład, <Tab> (który generuje klawsym [Tab]) oraz <Ctrl-i> (który generuje klawsym [i] z modyfikatorem "Ctrl"). Jedną z konsekwencji jest to że chcemy aby <BackSpace> generowało klawsym [BackSpace]. Jednakże w większości systemów <BackSpace> tak samo jak <Delete> generuje domyślnie klawsym [Delete] z powodu sposobu w jaki napisany jest serwer XFree86 (czyta on ustawienia z układu klawiatury Linuxa). Czyni to oba te klawisze nieodróżnialnymi. Jest to przyczyna numer jeden problemu 'wsteczna spacja nie działa w mojej aplikacji Xowej'. Patrz manpage dla xmodmap(1) lub xkeycaps(1) co do poprawki. Listę klawsymów znaleźć można w <tt>X11/keysymdef.h</tt> (zwykle <tt>/usr/include/X11/keysymdef.h</tt>), bez przedrostka XK_, a także w <tt>/usr/lib/X11/XKeysymDB</tt>. Zauważ że w klawsymach X rozróżniane są małe i duże litery. Istnieje kilka modyfikatorów (takich jak 'Shift' czy 'Ctrl') które mogą zostać wygenerowane pod X: Shift, Ctrl, Meta, Alt, Super i Hyper. Zauważ że chociaż 'Alt' jest tu obecny, w większości wypadków klawisz <Alt> na klawiaturze PC jest związany z modyfikatorem 'Meta'; działa w ten sposób z większą liczbą aplikacji. <sect1>X server<p> <verb> <tt/xev/ xev(1) pozwala ci zobaczyć zdarzenia generowane w oknie, w tym zdarzenia <KeyPress> oraz <KeyRelease>, w których możesz znaleźć kod dla konkretnego klawisza. Gdy kod został już znaleziony, można mu przypisać klawsym X11 używając <tt/xmodmap/. <tt/xkeycaps/ Z pliku <tt/README/: <tt/xkeycaps/ jest graficzną nakładką na <tt/xmodmap/. Otwiera on okno które wygląda jak klawiatura; przesunięcie myszy nad klawisz pokazuje jakie ten klawisz generuje klawsymy i bity modyfikatorów. Kliknięcie na klawiszu symuluje zdarzenia KeyPress/KeyRelease w wybranym przez ciebie oknie. Można zmienić klawsymy i bity modyfikatorów poprzez oparty na myszce interfejs. Program ten potrafi także zapisać plik wejściowy dla <tt/xmodmap/, który odtwarza twoje zmiany w przyszłych sesjach. Patrz manpage po więcej szczegółów. Najnowszą wersję <tt/xkeycaps/ można zawsze ftpnąc z <tt>ftp.x. org</tt>. Możesz także pobrać ją z mojej strony WWW <tt>http://www.netscape.com/people/jwz/</tt>. <tt/xmodmap/ Jedną z funkcji xmodmap(1) jest przypisywanie kodów klawiszy w X do klawsymów. 'xmodmap plik' czyta tablicę kod klawisza -> klawsym z pliku 'plik' (zwykle zwanego <tt>.xmodmaprc</tt> lub <tt>.Xmodmap</tt> w katalogu domowym użytkownika). Robi to zwykle xinit(1) lub startx(1) podczas startu X. Slackware domyślnie ładuje plik <tt>$HOME/.Xmodmap</tt>, jeśli istnieje; tak więc wstawienie do niego poniższych dwóch linii powinno rozwiązać większość problemów. W przeciwnym razie, czytaj dalej. <tscreen><verb> keycode 22 = BackSpace keycode 107 = Delete </verb></tscreen> Można użyć 'xmodmap -e "komenda"' aby wykonać pojedynczą komendę <tt/xmodmap/, dla prostych zmian. Na przykład, możesz wstawić do swojego <tt>$HOME/.xinitrc</tt> następujące linie, zamiast używać pliku <tt>$HOME/.Xmodmap file</tt>: <tscreen><verb> # mapuj klawisz <BackSpace> do klawsymu [BackSpace] xmodmap -e "keycode 22 = BackSpace" # mapuj klawisz <Delete> do klawsymu [Delete] xmodmap -e "keycode 107 = Delete" </verb></tscreen> Ostrzeżenie: X kończy działanie po osiągnięciu ostatniej linii <tt/.xinitrc/, więc jeśli wcześniej nie miałeś <tt/.xinitrc/, musisz wstawić coś co będzie nadal pracowało (jak menadżer okien czy <tt/xterm/) po końcu <tt/.xinitrc/, i nie uruchamiaj tego w tle! W końcu, możesz wygenerować plik mapowań z pliku *.map loadkeys(1) używając <tt>/usr/lib/kbd/keytables/mk_modmap foo.map > foo.xmap</tt>; musisz usunąć wszystkie komendy 'compose' w pliku wynikowym. Zauważ że <BackSpace> zostałby przypisany do klawsymu [Delete], jeślibyś zaczął od domyślnego układu, upewnij się więc i wyedytuj foo.xmap dla kodu klawisza 22 (BackSpace) oraz 107 (Delete). <sect1>Aplikacje Xowe<p> Aplikacje Xowe konfiguruje się zwykle poprzez zasoby. Preferencje użytkownika wstawia się przeważnie do <tt>$HOME/.Xdefaults</tt> i ładuje poprzez <tt>xrdb -load $HOME/.Xdefaults</tt> w <tt/.xinitrc/ (patrz ostrzeżenie przy omawianiu <tt/xmodmap/). <sect2>Emulatory terminala<p> <sect3>xterm i rodzina<p> Tak można zmienić przypisania klawiszy w <tt>$(HOME)/.Xresources</tt>: <tscreen><verb> *VT100.Translations: #override <Key>BackSpace: string(0x7F)\n\ <Key>Delete: string(0x1b) string("[3~")\n\ <Key>Home: string(0x1b) string("[1~")\n\ <Key>End: string(0x1b) string("[4~")\n\ Ctrl<Key>Prior: string(0x1b) string("[40~")\n\ Ctrl<Key>Next: string(0x1b) string("[41~") </verb></tscreen> Stosuje się to do większości emulatorów opartych na <tt/xtermie/ (<tt/xterm/, <tt/color-xterm/, <tt/kterm/ itp., ale nie <tt/rxvt/). <sect3>rxvt<p> Nie istnieje najwyraźniej żaden sposób przemapowania klawiszy w <tt/rxvt/, z wyjątkiem poprawnienia źródła. Każdy dowód na okoliczność przeciwną mile widziany. <sect2>Edytory<p> <sect3>FSF Emacs 19<p> Do przypisywania klawiszy do komend emacsa można użyć <tt/global-set-key/. Patrz kawałek o Emacsie 19 w sekcji nie-Xowej. Żeby dowiedzieć się jaki symbol emacsowy wysyła dany klawisz, naciśnij go (w brudnobuforze, tak żeby nie zapaćkał ci twoich plików), a potem użyj komedy emacsa <tt/view-lossage/ (zwykle <Ctrl-h>), żeby zobaczyć co klawisz wypisał. Zwykle symbolem tym jest klawsym X11 małymi literami; na przykład <Insert>, (które generuje klawsym [Insert]) w emacsie brzmi [insert]. <Shift-fkey>, <Ctrl-fkey>, <Meta-fkey> generują [S-fkey], [C-fkey], i [M-fkey] odpowiednio. Kombinacje generują coś w rodzaju [C-M-fkey]. Inne modyfikatory to s- dla 'Super', H- dla 'Hyper' oraz A- dla 'Alt'. <sect3>XEmacs<p> Podobnie użyj <tt/define-key/ lub <tt/set-global-key/. Wierzę że działa zarówno metoda [klawsym], jak w FSF Emacsie, jak i 'klawsym (jak niżej). Metoda wyszczególniania <Ctrl-fkey> itd. jest odmienna: działać powinny i [(control fkey)] i '(control fkey). Zauważ jednak że <Ctrl-A> to '(control a), podczas gdy <Ctrl-Shift-A> to '<control A>. Zostaw '(shift fkey) dla klawiszy niealfabetycznych. <tscreen><verb> (define-key global-map 'delete 'delete-char) (define-key global-map 'backspace 'backward-delete-char-untabify) (define-key global-map '(control prior) 'fkey-beginning-of-buffer) (define-key global-map '(control next) 'fkey-end-of-buffer) (define-key global-map '(control home) 'fkey-scroll-right) (define-key global-map '(control end) 'fkey-scroll-left) (global-set-key 'f1 'help-for-help) (global-set-key 'f3 'isearch-forward) (global-set-key 'f4 'query-replace-regexp) (global-set-key '(shift f1) 'info) (global-set-key '(shift f3) 'isearch-backward) </verb></tscreen> Czasami klawisz <Delete> nie chce kasować w przód po zmianie trybu głównego, nawet jeśli przemapowałeś go jak wyżej. Wtedy możesz chcieć go przemapować w układzie klawiatury dla tegoż trybu głównego, jak w przykładzie poniżej: <tscreen><verb> ;; ;; Konfiguracja trybów lispowych ;; (defun my-lisp-mode-common-hook () (define-key shared-lisp-mode-map 'backspace 'backward-delete-char-untabify) (define-key shared-lisp-mode-map 'delete 'delete-char) ) (add-hook 'lisp-mode-hook 'my-lisp-mode-common-hook) (add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-common-hook) (add-hook 'lisp-interaction-mode-hook 'my-lisp-mode-common-hook) </verb></tscreen> <sect2>Inne programy<p> <sect3>Aplikacje motiffowe (np. Mosaic, Netscape)<p> <BackSpace> powinno działać w aplikacjach motiffowych jeśli generuje klawsym [BackSpace]. Patrz xmodmap(1). Poprzednie wersje tego dokumentu sugerowały poprawkę z użyciem zasobów <tt/*XmText.translations/ lub <tt/*XmTextField.translations/. Nie jest to już polecane, ponieważ może zepsuć coś innego. Patrz FAQ Netscape dla X (<tt>http://home.netscape.com/eng/mozilla/1.1/faq_navx.html</tt>) <sect>Więcej informacji<p> <tt/kbd.FAQ/ w pakiecie <tt/kbd/ (<tt>ftp://sunsite.unc.edu/pub/Linux/system/Keyboards/kbd-0.89.tar.gz</tt>) zawiera więcej przykładów co do przemapowywania klawiatury. Manpages dla programów wspomnianych wyżej są dobrymi źródłami informacji, zwłaszcza xterm(1), xmodmap(1x) oraz stty(1). Strony info dla emacsa powiedzą ci jak przemapować w nim klawisze; użyj <tt>info -f emacs</tt> żeby je przeczytać. Keystroke-mini-HOWTO (<tt>ftp://sunsite.unc.edu/pub/Linux/doc/HOWTO/mini/Keystroke</tt>) opisuje sposób przypisania specjalnych działań niektórym z klawiszy na klawiaturze. FAQ Netscape (<tt>http://home.netscape.com/eng/mozilla/1.1/faq_navx.html#x12</tt>)' zawiera rozwiązanie dla problemu niedziałania BackSpace w Netscape.