Jak działają wprowadzanie za pomocą klawiatury i tekst?


85

Załóżmy, że nacisnąłem Aklawisz w edytorze tekstu, a to wstawia znak ado dokumentu i wyświetla go na ekranie. Wiem, że aplikacja edytora nie komunikuje się bezpośrednio ze sprzętem (między nimi jest jądro i inne rzeczy), więc co się dzieje w moim komputerze?

Odpowiedzi:


100

Istnieje kilka różnych scenariuszy; Opiszę najczęstsze. Kolejne zdarzenia makroskopowe to:

  1. Wejście: zdarzenie naciśnięcia klawisza jest przesyłane ze sprzętu klawiatury do aplikacji.
  2. Przetwarzanie: aplikacja decyduje, że ponieważ klawisz Azostał naciśnięty, musi wyświetlić znak a.
  3. Dane wyjściowe: aplikacja wydaje polecenie wyświetlania ana ekranie.

Aplikacje GUI

De facto standardowym graficznym interfejsem użytkownika systemów uniksowych jest X Window System , często nazywany X11, ponieważ ustabilizował się w 11. wersji swojego podstawowego protokołu między aplikacjami a serwerem wyświetlania. Program o nazwie X serwer znajduje się między jądrem systemu operacyjnego a aplikacjami; świadczy usługi, w tym wyświetlanie okien na ekranie i przesyłanie naciśnięć klawiszy do okna, na którym jest ustawiony fokus.

Wejście

+----------+              +-------------+         +-----+
| keyboard |------------->| motherboard |-------->| CPU |
+----------+              +-------------+         +-----+
             USB, PS/2, …                 PCI, …
             key down/up

Po pierwsze, informacje o naciśnięciu i zwolnieniu klawisza są przesyłane z klawiatury do komputera i wewnątrz komputera. Szczegóły zależą od rodzaju sprzętu. Nie będę więcej rozwodził się nad tą częścią, ponieważ informacje pozostają takie same w tej części łańcucha: pewien klawisz został naciśnięty lub zwolniony.

         +--------+        +----------+          +-------------+
-------->| kernel |------->| X server |--------->| application |
         +--------+        +----------+          +-------------+
interrupt          scancode             keysym
                   =keycode            +modifiers

Kiedy nastąpi zdarzenie sprzętowe, procesor wyzwala przerwanie , które powoduje wykonanie kodu w jądrze . Ten kod wykrywa, że ​​zdarzenie sprzętowe to naciśnięcie klawisza lub zwolnienie klawisza pochodzące z klawiatury i zapisuje kod skanowania, który identyfikuje klawisz.

Serwer X odczytuje zdarzenia wejściowe za pomocą pliku urządzenia , na przykład /dev/input/eventNNNw systemie Linux (gdzie NNN jest liczbą). Ilekroć występuje zdarzenie, jądro sygnalizuje, że istnieją dane do odczytu z tego urządzenia. Plik urządzenia przesyła zdarzenia kluczowania w górę / w dół za pomocą kodu skanowania, który może być lub nie być identyczny z wartością przesyłaną przez sprzęt (jądro może tłumaczyć kod skanowania z wartości zależnej od klawiatury na wspólną wartość, a Linux nie nie przesyłaj ponownie skanowanych kodów, których nie zna ).

X wywołuje kod skanowania, który czyta kod klucza . Serwer X utrzymuje tabelę, która tłumaczy kody kluczy na breloki (skrót od „symbol klucza”). Są kody klawiszy numerycznych, zaś keysymy są nazwy, takie jak A, aacute, F1, KP_Add, Control_L, ... klawsym mogą się różnić w zależności od klawiszy modyfikujące są naciskane ( Shift, Ctrl...).

Istnieją dwa mechanizmy konfigurowania mapowania kodów kluczy na klucze:

  • xmodmap to tradycyjny mechanizm. Jest to prosty kod mapujący tabelę na listę kluczy (niezmodyfikowanych, przesuniętych,…).
  • XKB jest potężniejszym, ale bardziej złożonym mechanizmem z lepszą obsługą większej liczby modyfikatorów, w szczególności między innymi konfiguracji w dwóch językach.

Aplikacje łączą się z serwerem X i otrzymują powiadomienie po naciśnięciu klawisza, gdy fokus ma okno tej aplikacji. Powiadomienie wskazuje, że określony klawisz został naciśnięty lub zwolniony, a także jakie modyfikatory są aktualnie wciśnięte. Możesz zobaczyć klawisze, uruchamiając program xevz terminala. To, co aplikacja zrobi z informacjami, zależy od tego; niektóre aplikacje mają konfigurowalne przypisania klawiszy.

W typowej konfiguracji naciśnięcie klawisza oznaczonego Abez modyfikatorów powoduje wysłanie klawisza ado aplikacji; jeśli aplikacja jest w trybie, w którym piszesz tekst, powoduje to wstawienie znaku a.

Zależność układu klawiatury i xmodmap jest bardziej szczegółowa na temat wprowadzania danych z klawiatury. Jak działają zdarzenia myszy w systemie Linux? daje przegląd danych wejściowych myszy na niższych poziomach.

Wynik

+-------------+        +----------+          +-----+         +---------+
| application |------->| X server |---····-->| GPU |-------->| monitor |
+-------------+        +----------+          +-----+         +---------+
               text or              varies          VGA, DVI,
               image                                HDMI, …

Istnieją dwa sposoby wyświetlenia postaci.

Zobacz Jakie są cele różnych typów czcionek XWindows? do dyskusji na temat renderowania tekstu po stronie klienta i serwera w X11.

To, co dzieje się między serwerem X a modułem przetwarzania grafiki (procesorem na karcie graficznej), jest bardzo zależne od sprzętu. Proste systemy mają X serwer rysujący w obszarze pamięci zwanym buforem ramek , który GPU wybiera do wyświetlenia. Zaawansowane systemy, takie jak na dowolnym komputerze lub smartfonie XXI wieku, umożliwiają GPU wykonywanie niektórych operacji bezpośrednio w celu uzyskania lepszej wydajności. Ostatecznie GPU przesyła zawartość ekranu piksel po pikselu co ułamek sekundy na monitor.

Aplikacja w trybie tekstowym działająca w terminalu

Jeśli edytor tekstu jest aplikacją tekstową działającą w terminalu, to jest to terminal, który jest aplikacją do celów powyższej sekcji. W tej sekcji wyjaśniam interfejs między aplikacją w trybie tekstowym a terminalem. Najpierw opiszę przypadek emulatora terminala działającego pod X11. Jaka jest dokładna różnica między „terminalem”, „powłoką”, „tty” i „konsolą”? może być przydatnym tłem tutaj. Po przeczytaniu tego możesz przeczytać o wiele bardziej szczegółowe. Jakie są obowiązki każdego komponentu Pseudo-Terminal (PTY) (oprogramowanie, strona master, strona slave)?

Wejście

      +-------------------+               +-------------+
----->| terminal emulator |-------------->| application |
      +-------------------+               +-------------+
keysym                     character or
                           escape sequence

Emulator terminala odbiera zdarzenia typu „ Leftzostał naciśnięty, gdy Shiftbył wyłączony”. Interfejsem między emulatorem terminala a aplikacją w trybie tekstowym jest pseudo-terminal (pty) , urządzenie znakowe, które przesyła bajty. Gdy emulator terminala odbiera zdarzenie naciśnięcia klawisza, przekształca to w jeden lub więcej bajtów, które aplikacja może odczytać z urządzenia pty.

Znaki drukowalne poza zakresem ASCII są przesyłane jako jeden lub więcej bajtów, w zależności od znaku i kodowania . Na przykład, w UTF-8 kodowania Unicode zestawu znaków, znaków w ASCII zakresie są zakodowane jako pojedynczy bajtów, podczas gdy znaki poza tego zakresu są kodowane jako wiele bajtów.

Naciśnięcia klawiszy odpowiadające klawiszowi funkcyjnemu lub znakowi drukowanemu z modyfikatorami takimi jak Ctrllub Altsą wysyłane jako sekwencja zmiany znaczenia . Sekwencje specjalne zwykle składają się ze znaku ucieczki (wartość bajtu 27 = 0x1B = \033, czasami reprezentowana jako ^[lub \e), po którym następuje jeden lub więcej znaków do wydrukowania. Kilka klawiszy lub kombinacji klawiszy ma odpowiadający im znak kontrolny w kodowaniu opartym na ASCII (który jest prawie wszystkie używane dzisiaj, w tym Unicode): Ctrl+ letterdaje wartość znaku z zakresu 1–26, Escjest znakiem ucieczki widziane powyżej i jest również takie samo jak Ctrl+ [, Tabjest takie samo jak Ctrl+ I,Returnjest taki sam jak Ctrl+ Mitp.

Różne terminale wysyłają różne sekwencje specjalne dla danego klucza lub kombinacji klawiszy. Na szczęście odwrotność nie jest prawdziwa: biorąc pod uwagę sekwencję, w praktyce istnieje co najwyżej jedna kluczowa kombinacja, którą koduje. Jedynym wyjątkiem jest znak 127 = 0x7f =, \0177który często, Backspaceale czasem Delete.

W terminalu, jeśli wpiszesz Ctrl+, Va następnie kombinację klawiszy, to dosłownie wstawia pierwszy bajt sekwencji ucieczki od kombinacji klawiszy. Ponieważ sekwencje specjalne zwykle składają się tylko z drukowalnych znaków po pierwszej, wstawia to dosłownie całą sekwencję wyjściową. Zobacz tabelę powiązań klawiszy? do dyskusji na temat zsh w tym kontekście.

Terminal może przesyłać tę samą sekwencję zmiany znaczenia dla niektórych kombinacji modyfikatorów (np. Wiele terminali przesyła znak spacji dla obu Spacei Shift+ Space; xterm ma tryb rozróżniania kombinacji modyfikatorów, ale terminale oparte na popularnej bibliotece vte nie .) Kilka kluczy nie jest w ogóle przesyłanych, na przykład klawisze modyfikujące lub klucze, które wyzwalają wiązanie emulatora terminala (np. Polecenie kopiuj lub wklej).

Jeśli to pożądane, aplikacja przekształca sekwencje specjalne w symboliczne nazwy kluczy.

Wynik

+-------------+               +-------------------+
| application |-------------->| terminal emulator |--->
+-------------+               +-------------------+
               character or
               escape sequence

Wyjście jest raczej prostsze niż wejście. Jeśli aplikacja wyśle ​​znak do pliku urządzenia pty, emulator terminala wyświetli go w bieżącej pozycji kursora. (Emulator terminala utrzymuje pozycję kursora i przewija, jeśli kursor spadnie poniżej dolnej krawędzi ekranu.) Aplikacja może również generować sekwencje specjalne (najczęściej zaczynające się od ^[lub ^]), aby poinformować terminal, aby wykonał takie czynności, jak przesunięcie kursora, zmieniając atrybuty tekstu (kolor, pogrubienie,…) lub usuwając część ekranu.

Sekwencje specjalne obsługiwane przez emulator terminala są opisane w bazie danych termcap lub terminfo . Obecnie większość emulatorów terminali jest dość ściśle związana z xterm . Zobacz dokumentację dotyczącą zmiennych LESS_TERMCAP_ *? na dłuższą dyskusję na temat baz danych informacji o możliwościach terminali oraz Jak zatrzymać miganie kursora i Czy mogę ustawić kolory terminali mojego komputera lokalnego, aby używały kolorów komputera, na którym ssh? dla niektórych przykładów użycia.

Aplikacja działa w konsoli tekstowej

Jeśli aplikacja działa bezpośrednio w konsoli tekstowej, tj. Terminalu dostarczonym przez jądro, a nie przez aplikację emulatora terminala, obowiązują te same zasady. Interfejs między terminalem a aplikacją nadal jest strumieniem bajtów, który przesyła znaki, ze specjalnymi klawiszami i poleceniami zakodowanymi jako sekwencje specjalne.

Aplikacja zdalna, dostępna przez sieć

Zdalna aplikacja tekstowa

Jeśli uruchamiasz program na zdalnej maszynie, np. Przez SSH , wówczas protokół komunikacji sieciowej przekazuje dane na poziomie pty.

+-------------+           +------+           +-----+           +----------+
| application |<--------->| sshd |<--------->| ssh |<--------->| terminal |
+-------------+           +------+           +-----+           +----------+
               byte stream        byte stream       byte stream
               (char/seq)         over TCP/…        (char/seq)

Jest to w większości przezroczyste, z tym że czasami zdalna baza danych terminali może nie znać wszystkich możliwości lokalnego terminala.

Zdalna aplikacja X11

Protokół komunikacyjny między aplikacjami a serwerem sam jest strumieniem bajtów, który może być przesyłany za pośrednictwem protokołu sieciowego, takiego jak SSH.

+-------------+            +------+        +-----+            +----------+
| application |<---------->| sshd |<------>| ssh |<---------->| X server |
+-------------+            +------+        +-----+            +----------+
               X11 protocol        X11 over       X11 protocol
                                   TCP/…

Jest to w większości przezroczyste, z wyjątkiem tego, że niektóre funkcje przyspieszania, takie jak dekodowanie filmów i renderowanie 3D, które wymagają bezpośredniej komunikacji między aplikacją a wyświetlaczem, nie są dostępne.


Nie całkowicie pewny, ale ponieważ odpowiedź jest zazwyczaj dość szczegółowy Zastanawiam się, czy ta część, która mówi „Aplikacja działa w konsoli tekstowej” Może nie posiadają, że takie rzeczy man 5 keymapssą używane do tłumacząc keycodessię scancodes. Chociaż, jak wspomniano, zasadniczo podobny, to jednak jest to zupełnie inny zestaw narzędzi / programów, co zasługuje na więcej informacji. Poza tym odpowiedź wynosi +1 i jest świetna ze względu na osadzone pytania pokrewne.
ludzkośćANDpeace

Znalazłem PgUpi Ctrl+PgUpsą nie do odróżnienia w tty1 (TERM = linux). Czy można skonfigurować mapowanie sekwencji klawiszy -> control?
stewbasic

@stewbasic Tak, z załadowaną mapą klawiszy loadkeys. Wyszukaj pytania oznaczone układem klawiatury konsoli Linuksa .
Gilles

@Gilles dzięki! Warto zauważyć, że loadkeys zmienia oba klawisze mapowania -> keyym i keyym -> sekwencja ucieczki (początkowo nie było to dla mnie oczywiste).
stewbasic

1
Wow, to musi być jedna z najlepszych odpowiedzi, jakie kiedykolwiek widziałem na Stackexchange - dobrze zorganizowana, odpowiada na pytanie, zapewnia odpowiedni kontekst, odsyłacze do innych przydatnych odpowiedzi, a nawet ma ładną grafikę ASCII!
Johntron

4

Jeśli chcesz zobaczyć to w systemie uniksowym, który jest wystarczająco mały, aby być zrozumiałym, kop w Xv6 . To mniej więcej mityczna 6. edycja Uniksa, która stała się podstawą słynnego komentarza Johna Lwa , długo rozpowszechnianego jako samizdat. Jego kod został przerobiony w celu skompilowania pod ANSI C i biorąc pod uwagę nowoczesne rozwiązania, takie jak wieloprocesory.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.