Come funzionano l'input da tastiera e l'output di testo?


85

Supponiamo di premere il Atasto in un editor di testo e questo inserisce il carattere anel documento e lo visualizza sullo schermo. So che l'applicazione dell'editor non comunica direttamente con l'hardware (c'è un kernel e roba in mezzo), quindi cosa succede nel mio computer?

Risposte:


100

Esistono diversi scenari; Descriverò quelli più comuni. I successivi eventi macroscopici sono:

  1. Input: l'evento di pressione dei tasti viene trasmesso dall'hardware della tastiera all'applicazione.
  2. Elaborazione: l'applicazione decide che, poiché il tasto è Astato premuto, deve visualizzare il carattere a.
  3. Output: l'applicazione dà l'ordine di visualizzare asullo schermo.

Applicazioni GUI

L'interfaccia grafica utente standard de facto dei sistemi unix è l' X Window System , spesso chiamato X11 perché stabilizzato nell'undicesima versione del suo protocollo principale tra le applicazioni e il server di visualizzazione. Un programma chiamato X server si trova tra il kernel del sistema operativo e le applicazioni; fornisce servizi tra cui la visualizzazione di finestre sullo schermo e la trasmissione di pressioni di tasti alla finestra che ha lo stato attivo.

Ingresso

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

Innanzitutto, le informazioni sulla pressione del tasto e sul rilascio del tasto vengono trasmesse dalla tastiera al computer e all'interno del computer. I dettagli dipendono dal tipo di hardware. Non mi soffermerò più su questa parte perché le informazioni rimangono le stesse in tutta questa parte della catena: un certo tasto è stato premuto o rilasciato.

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

Quando si verifica un evento hardware, la CPU attiva un interrupt , che causa l' esecuzione di un codice nel kernel . Questo codice rileva che l'evento hardware è la pressione di un tasto o il rilascio di un tasto proveniente da una tastiera e registra il codice di scansione che identifica il tasto.

Il server X legge gli eventi di input attraverso un file di dispositivo , ad esempio /dev/input/eventNNNsu Linux (dove NNN è un numero). Ogni volta che c'è un evento, il kernel segnala che ci sono dati da leggere da quel dispositivo. Il file del dispositivo trasmette gli eventi chiave su / giù con un codice di scansione, che può essere o non essere identico al valore trasmesso dall'hardware (il kernel può tradurre il codice di scansione da un valore dipendente dalla tastiera a un valore comune, e Linux no non ritrasmettere i codici di scansione che non conosce ).

X chiama il codice di scansione che legge un codice chiave . Il server X mantiene una tabella che traduce i codici chiave in keysyms (abbreviazione di "simbolo chiave"). Keycodes sono numerici, che keysyms sono nomi quali A, aacute, F1, KP_Add, Control_L, ... La keysym può differire a seconda del tasti modificatori sono premuti ( Shift, Ctrl, ...).

Esistono due meccanismi per configurare la mappatura dai keycode ai keyyms:

  • xmodmap è il meccanismo tradizionale. Si tratta di una semplice tabella che associa i codici chiave a un elenco di palestre (non modificate, spostate, ...).
  • XKB è un meccanismo più potente, ma più complesso, con un migliore supporto per più modificatori, in particolare per la configurazione in doppia lingua, tra gli altri.

Le applicazioni si connettono al server X e ricevono una notifica quando viene premuto un tasto mentre una finestra di tale applicazione è attiva. La notifica indica che un certo keyym è stato premuto o rilasciato e quali modificatori sono attualmente premuti. È possibile visualizzare le palestre chiavi eseguendo il programma xevda un terminale. Ciò che l'applicazione fa con le informazioni dipende da esso; alcune applicazioni hanno combinazioni di tasti configurabili.

In una configurazione tipica, quando si preme il tasto etichettato Asenza modificatori, questo invia il keyym aall'applicazione; se l'applicazione è in una modalità in cui stai digitando del testo, questo inserisce il carattere a.

La relazione tra layout della tastiera e xmodmap è più dettagliata sull'input da tastiera. Come funzionano gli eventi del mouse in Linux? offre una panoramica dell'input del mouse ai livelli inferiori.

Produzione

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

Esistono due modi per visualizzare un personaggio.

Vedi Quali sono gli scopi dei diversi tipi di caratteri XWindows? per una discussione sul rendering del testo lato client e lato server in X11.

Ciò che accade tra il server X e l' unità di elaborazione grafica (il processore sulla scheda video) dipende molto dall'hardware. Nei sistemi semplici il server X viene disegnato in un'area di memoria chiamata framebuffer , che la GPU raccoglie per la visualizzazione. Sistemi avanzati come quelli presenti su qualsiasi PC o smartphone del 21 ° secolo consentono alla GPU di eseguire alcune operazioni direttamente per prestazioni migliori. Alla fine, la GPU trasmette il contenuto dello schermo pixel per pixel ogni frazione di secondo al monitor.

Applicazione in modalità testo, in esecuzione in un terminale

Se il tuo editor di testo è un'applicazione in modalità testo in esecuzione in un terminale, allora è il terminale che è l'applicazione ai fini della sezione precedente. In questa sezione, spiego l'interfaccia tra l'applicazione in modalità testo e il terminale. Per prima cosa descrivo il caso di un emulatore di terminale che funziona con X11. Qual è la differenza esatta tra un 'terminale', una 'shell', una 'tty' e una 'console'? può essere utile sfondo qui. Dopo aver letto questo, potresti voler leggere molto più in dettaglio Quali sono le responsabilità di ciascun componente Pseudo-Terminale (PTY) (software, lato master, lato slave)?

Ingresso

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

L'emulatore di terminale riceve eventi come "è Leftstato premuto mentre Shiftera inattivo". L'interfaccia tra l'emulatore di terminale e l'applicazione in modalità testo è uno pseudo-terminale (pty) , un dispositivo a caratteri che trasmette byte. Quando l'emulatore di terminale riceve un evento di pressione dei tasti, lo trasforma in uno o più byte che l'applicazione può leggere dal dispositivo pty.

I caratteri stampabili al di fuori dell'intervallo ASCII vengono trasmessi come uno o più byte in base al carattere e alla codifica . Ad esempio, nella codifica UTF-8 del set di caratteri Unicode , i caratteri nell'intervallo ASCII sono codificati come singoli byte, mentre i caratteri al di fuori di tale intervallo sono codificati come più byte.

Tasti premuti che corrispondono a un tasto funzione o un carattere stampabile con modificatori come Ctrlo Altvengono inviati come sequenza di escape . Le sequenze di escape consistono in genere di escape di caratteri (valore byte 27 = 0x1B = \033, talvolta rappresentato come ^[o \e) seguito da uno o più caratteri stampabili. Alcune chiavi o combinazioni di tasti hanno un carattere di controllo corrispondente a loro nelle codifiche basate su ASCII (che è praticamente tutte in uso oggi, incluso Unicode): Ctrl+ letterrestituisce un valore di carattere nell'intervallo 1–26, Escè il carattere di escape visto sopra ed è anche uguale a Ctrl+ [, Tabè uguale a Ctrl+ I,Returnè uguale a Ctrl+ M, ecc.

Terminali diversi inviano sequenze di escape diverse per una determinata chiave o combinazione di tasti. Fortunatamente, il contrario non è vero: data una sequenza, in pratica esiste al massimo una combinazione di tasti che codifica. L'unica eccezione è il carattere 127 = 0x7f = \0177che è spesso Backspacema a volte Delete.

In un terminale, se si digita Ctrl+ Vseguito da una combinazione di tasti, questo inserisce letteralmente il primo byte della sequenza di escape dalla combinazione di tasti. Poiché le sequenze di escape normalmente consistono solo di caratteri stampabili dopo la prima, ciò inserisce letteralmente l'intera sequenza di escape. Vedi la tabella delle associazioni dei tasti? per una discussione di zsh in questo contesto.

Il terminale può trasmettere la stessa sequenza di escape per alcune combinazioni di modificatori (ad es. Molti terminali trasmettono un carattere di spazio per entrambi Spacee Shift+ Space; xterm ha una modalità per distinguere le combinazioni di modificatori ma i terminali basati sulla popolare libreria vte no ). Alcuni tasti non vengono affatto trasmessi, ad esempio tasti modificatori o tasti che attivano un'associazione dell'emulatore di terminale (ad esempio un comando copia o incolla).

Spetta all'applicazione tradurre sequenze di escape in nomi di chiavi simboliche se lo desidera.

Produzione

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

L'output è piuttosto più semplice dell'input. Se l'applicazione genera un carattere nel file del dispositivo pty, l'emulatore di terminale lo visualizza nella posizione corrente del cursore. (L'emulatore di terminale mantiene la posizione del cursore e scorre se il cursore cade sotto la parte inferiore dello schermo.) L'applicazione può anche generare sequenze di escape (principalmente a partire da ^[o ^]) per dire al terminale di eseguire azioni come spostare il cursore, cambiando gli attributi del testo (colore, grassetto, ...) o cancellando parte dello schermo.

Le sequenze di escape supportate dall'emulatore di terminale sono descritte nel database termcap o terminfo . Oggi la maggior parte dell'emulatore di terminale è abbastanza allineata con xterm . Vedi la documentazione sulle variabili LESS_TERMCAP_ *? per una più lunga discussione sui database di informazioni sulla capacità del terminale e su Come fermare il lampeggiamento del cursore e Posso impostare i colori del terminale del mio computer locale per usare quelli del computer in cui mi trovo? per alcuni esempi di utilizzo.

Applicazione in esecuzione in una console di testo

Se l'applicazione è in esecuzione direttamente in una console di testo, ovvero un terminale fornito dal kernel anziché da un'applicazione di emulazione di terminale, si applicano gli stessi principi. L'interfaccia tra il terminale e l'applicazione è ancora un flusso di byte che trasmette caratteri, con tasti speciali e comandi codificati come sequenze di escape.

Applicazione remota, accessibile tramite la rete

Applicazione di testo remota

Se si esegue un programma su una macchina remota, ad esempio tramite SSH , il protocollo di comunicazione di rete inoltra i dati a livello di pty.

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

Ciò è per lo più trasparente, tranne per il fatto che a volte il database del terminale remoto potrebbe non conoscere tutte le funzionalità del terminale locale.

Applicazione X11 remota

Il protocollo di comunicazione tra le applicazioni e il server è esso stesso un flusso di byte che può essere inviato su un protocollo di rete come SSH.

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

Ciò è per lo più trasparente, tranne per il fatto che alcune funzioni di accelerazione come la decodifica dei filmati e il rendering 3D che richiedono la comunicazione diretta tra l'applicazione e il display non sono disponibili.


Non del tutto sicuro, ma dal momento che la risposta è in genere piuttosto dettagliata Mi chiedo se la parte che dice "applicazione in esecuzione in una console di testo" non potrebbe caratteristica che ci cose come man 5 keymapssono utilizzati per la traduzione della keycodesa scancodes. Mentre come detto principalmente simile è ancora un insieme completamente diverso di strumenti / programmi e questo meriterebbe forse alcune intuizioni in più. Accanto a ciò la risposta è +1 e ottima per via delle domande correlate.
umanità e

Ho trovato PgUpe Ctrl+PgUpsono indistinguibili in tty1 (TERM = linux). È possibile configurare la mappatura della sequenza di controllo keysym ->?
Stewbasic,

@stewbasic Sì, con una keymap caricata da loadkeys. Cerca domande taggate layout tastiera console linux .
Gilles,

@Gilles grazie! Vale la pena notare che loadkeys modifica entrambi i mapping keycode -> keysym e keysym -> sequenza di escape (questo inizialmente non era ovvio per me).
Stewbasic,

1
Wow, questa deve essere una delle migliori risposte che io abbia mai visto su Stackexchange: ben organizzata, risponde alla domanda, fornisce un contesto pertinente, riferimenti incrociati ad altre risposte utili e ha persino una bella arte ASCII!
Johntron,

4

Se vuoi vederlo in un sistema Unix abbastanza piccolo da essere comprensibile, scava in Xv6 . È più o meno la mitica sesta edizione di Unix che è diventata la base del famoso commento di John Lion , a lungo distribuito come samizdat. Il suo codice è stato rielaborato per essere compilato sotto ANSI C e tenendo conto degli sviluppi moderni, come i multiprocessori,.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.