Comment fonctionnent la saisie au clavier et la sortie texte?


85

Supposons que j'appuie sur la Atouche dans un éditeur de texte pour insérer le caractère adans le document et l'afficher à l'écran. Je sais que l'application de l'éditeur ne communique pas directement avec le matériel (il y a un noyau et des éléments intermédiaires), que se passe-t-il dans mon ordinateur?

Réponses:


100

Il existe plusieurs scénarios différents; Je vais décrire les plus communs. Les événements macroscopiques successifs sont:

  1. Saisie: l'événement de frappe est transmis du clavier à l'application.
  2. Traitement: l’application décide que, du fait que la touche a Aété enfoncée, elle doit afficher le caractère a.
  3. Sortie: l'application donne l'ordre à afficher aà l'écran.

Applications graphiques

L’interface utilisateur graphique standard de facto des systèmes unix est le système X Window , souvent appelé X11 car il s’est stabilisé dans la 11e version de son protocole principal entre les applications et le serveur d’affichage. Un programme appelé serveur X se situe entre le noyau du système d’exploitation et les applications; il fournit des services, notamment l'affichage de fenêtres à l'écran et la transmission de pressions de touches vers la fenêtre active.

Contribution

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

Tout d'abord, les informations sur les touches enfoncées et relâchées sont transmises du clavier à l'ordinateur et à l'intérieur de celui-ci. Les détails dépendent du type de matériel. Je ne m'attarderai pas davantage sur cette partie car les informations restent les mêmes tout au long de cette chaîne: une certaine touche a été pressée ou relâchée.

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

Lorsqu'un événement matériel se produit, la CPU déclenche une interruption , ce qui entraîne l' exécution de certains codes dans le noyau . Ce code détecte que l'événement matériel est une pression sur une touche ou une libération de clé provenant d'un clavier et enregistre le code de balayage qui identifie la clé.

Le serveur X lit les événements d'entrée via un fichier de périphérique , par exemple /dev/input/eventNNNsous Linux (où NNN est un nombre). Chaque fois qu'il y a un événement, le noyau signale qu'il y a des données à lire à partir de ce périphérique. Le fichier de périphérique transmet les événements de montée / descente de clé avec un code d'analyse, qui peut être identique ou non à la valeur transmise par le matériel (le noyau peut traduire le code d'analyse d'une valeur dépendante du clavier en une valeur commune, et Linux ne le fait pas. retransmettez les codes de balayage qu’il ne connaît pas ).

X appelle le code d'analyse qu'il lit un code clé . Le serveur X gère une table qui traduit les codes de clé en keysyms (abréviation de «symbole de clé»). Keycodes sont numériques, alors que keysyms sont des noms tels que A, aacute, F1, KP_Add, Control_L, ... Le keysym peut varier en fonction des touches de modification qui sont pressés ( Shift, Ctrl...).

Il existe deux mécanismes pour configurer le mappage des codes clés vers les clés d’application:

  • xmodmap est le mécanisme traditionnel. Il s’agit d’une simple table mappant des codes clés sur une liste de mots clés (non modifiés, décalés,…).
  • XKB est un mécanisme plus puissant, mais plus complexe, prenant mieux en charge davantage de modificateurs, notamment pour la configuration bilingue.

Les applications se connectent au serveur X et reçoivent une notification lorsqu'une touche est enfoncée alors qu'une fenêtre de cette application a le focus. La notification indique qu'une touche particulière a été pressée ou relâchée, ainsi que les modificateurs actuellement pressés. Vous pouvez voir les keysyms en exécutant le programme à xevpartir d'un terminal. Ce que l'application fait avec l'information est à la hauteur; Certaines applications ont des raccourcis clavier configurables.

Dans une configuration typique, lorsque vous appuyez sur la touche Asans modificateurs, la clé est envoyée aà l'application. si l'application est dans un mode où vous tapez du texte, le caractère est inséré a.

La relation entre la disposition du clavier et xmodmap donne plus de détails sur la saisie au clavier. Comment les événements de souris fonctionnent-ils sous Linux? donne un aperçu de la saisie de la souris aux niveaux inférieurs.

Sortie

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

Il y a deux façons d'afficher un caractère.

Voir Quels sont les objectifs des différents types de polices XWindows? pour une discussion sur le rendu de texte côté client et côté serveur sous X11.

Ce qui se passe entre le serveur X et l' unité de traitement graphique (le processeur de la carte vidéo) dépend beaucoup du matériel. Les systèmes simples ont dessiné le serveur X dans une région de la mémoire appelée framebuffer , que le GPU sélectionne pour l’affichage. Les systèmes avancés tels que ceux que l'on trouve sur n'importe quel PC ou smartphone du 21ème siècle permettent au GPU d'effectuer certaines opérations directement pour de meilleures performances. En fin de compte, le GPU transmet le contenu de l'écran pixel par pixel toutes les fractions de seconde au moniteur.

Application en mode texte, fonctionnant dans un terminal

Si votre éditeur de texte est une application en mode texte s'exécutant dans un terminal, c'est le terminal qui est l'application aux fins de la section ci-dessus. Dans cette section, j'explique l'interface entre l'application en mode texte et le terminal. Je décris tout d’abord le cas d’un émulateur de terminal fonctionnant sous X11. Quelle est la différence exacte entre un "terminal", un "shell", un "tty" et une "console"? peut être utile fond ici. Après avoir lu ceci, vous voudrez peut-être lire le document beaucoup plus détaillé. Quelles sont les responsabilités de chaque composant pseudo-terminal (PTY) (logiciel, côté maître, côté esclave)?

Contribution

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

L'émulateur de terminal reçoit des événements tels que «a Leftété enfoncé pendant que l'appareil Shiftétait en panne». L’interface entre l’émulateur de terminal et l’application en mode texte est un pseudo-terminal (pty) , un périphérique de caractères qui transmet des octets. Lorsque l'émulateur de terminal reçoit un événement de frappe, il le transforme en un ou plusieurs octets que l'application obtient en lecture à partir du périphérique pty.

Les caractères imprimables en dehors de la plage ASCII sont transmis sous la forme d'un ou plusieurs octets, en fonction du caractère et du codage . Par exemple, dans le codage UTF-8 du jeu de caractères Unicode , les caractères de la plage ASCII sont codés sous forme d'octets simples, tandis que les caractères situés en dehors de cette plage sont codés sous forme d'octets multiples.

Les touches correspondant à une touche de fonction ou à un caractère imprimable avec des modificateurs tels que Ctrlou Altsont envoyées en tant que séquence d'échappement . Les séquences d'échappement consistent généralement en un caractère d' échappement (valeur d'octet 27 = 0x1B = \033, parfois représenté par ^[ou \e) suivi d'un ou de plusieurs caractères imprimables. Quelques clés ou combinaisons de touches ont un caractère de contrôle correspondant dans les codages basés sur ASCII (qui sont pratiquement toutes utilisées aujourd'hui, y compris Unicode): Ctrl+ letterrenvoie une valeur de caractère comprise entre 1 et 26, Escest le caractère d'échappement vu ci-dessus et est également identique à Ctrl+ [, Tabest identique à Ctrl+ I,Returnest le même que Ctrl+ M, etc.

Différents terminaux envoient différentes séquences d'échappement pour une clé ou une combinaison de clés donnée. Heureusement, l'inverse n'est pas vrai: étant donné une séquence, il y a en pratique au plus une combinaison de touches qu'il code. La seule exception est le caractère 127 = 0x7f = \0177qui est souvent Backspacemais parfois Delete.

Dans un terminal, si vous tapez Ctrl+ Vsuivi d'une combinaison de touches, ceci insère littéralement le premier octet de la séquence d'échappement de la combinaison de touches. Comme les séquences d'échappement ne comprennent normalement que des caractères imprimables après la première, cela insère littéralement la séquence d'échappement complète. Voir le tableau des raccourcis clavier? pour une discussion de zsh dans ce contexte.

Le terminal peut transmettre la même séquence d'échappement pour certaines combinaisons de modificateurs (par exemple, de nombreux terminaux transmettent un caractère d'espacement à la fois Spaceet Shift+ Space; xterm dispose d'un mode permettant de distinguer les combinaisons de modificateurs, mais les terminaux basés sur la bibliothèque vte populaire ne le font pas ). Quelques clés ne sont pas du tout transmises, par exemple des touches de modification ou des touches qui déclenchent une liaison de l'émulateur de terminal (par exemple, une commande copier ou coller).

Il appartient à l'application de traduire les séquences d'échappement en noms de clés symboliques si elle le souhaite.

Sortie

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

La sortie est plutôt plus simple que l'entrée. Si l'application génère un caractère dans le fichier de périphérique pty, l'émulateur de terminal l'affiche à la position actuelle du curseur. (L’émulateur de terminal maintient la position du curseur et défile si le curseur tombe au bas de l’écran.) L’application peut également émettre des séquences d’échappement (commençant généralement par ^[ou ^]) pour indiquer au terminal d’effectuer des actions telles que le déplacement du curseur, changer les attributs du texte (couleur, gras,…) ou effacer une partie de l'écran.

Les séquences d'échappement prises en charge par l'émulateur de terminal sont décrites dans la base de données termcap ou terminfo . De nos jours, la plupart des émulateurs de terminaux sont assez proches de xterm . Voir la documentation sur les variables LESS_TERMCAP_ *? pour une discussion plus longue des bases de données d’informations sur les capacités des terminaux, et comment empêcher le curseur de clignoter et puis-je configurer les couleurs des terminaux de ma machine locale pour utiliser celles de la machine dans laquelle je ssh? pour quelques exemples d'utilisation.

Application s'exécutant dans une console de texte

Si l'application s'exécute directement dans une console de texte, c'est-à-dire un terminal fourni par le noyau plutôt que par une application d'émulateur de terminal, les mêmes principes s'appliquent. L'interface entre le terminal et l'application est toujours un flux d'octets transmettant des caractères, avec des touches et des commandes spéciales codées en tant que séquences d'échappement.

Application distante, accessible via le réseau

Application texte à distance

Si vous exécutez un programme sur une machine distante, par exemple via SSH , le protocole de communication réseau relaie les données au niveau pty.

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

Ceci est principalement transparent, sauf que parfois la base de données du terminal distant peut ne pas connaître toutes les capacités du terminal local.

Application X11 distante

Le protocole de communication entre les applications et le serveur est lui-même un flux d'octets pouvant être envoyé via un protocole réseau tel que SSH.

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

Cela est principalement transparent, sauf que certaines fonctionnalités d'accélération, telles que le décodage de film et le rendu 3D, nécessitant une communication directe entre l'application et l'écran, ne sont pas disponibles.


Pas tout à fait sûr, mais puisque la réponse est généralement je me demande si assez détaillée la partie qui dit « Application en cours d' exécution dans une console de texte » pourrait ne pas figurer qu'il ya des choses comme man 5 keymapssont utilisées pour traduire le keycodesà scancodes. Bien que, comme mentionné, des principes similaires, il existe encore un ensemble d’outils / programmes totalement différent, ce qui mériterait peut-être quelques éclaircissements supplémentaires. A côté de cela, la réponse est +1 et excellente en raison des questions liées intégrées.
humanite et

J'ai trouvé PgUpet suis Ctrl+PgUpindiscernable dans tty1 (TERM = linux). Le mappage keysym -> control sequence mapping peut-il être configuré?
stewbasic

@stewbasic Oui, avec un keymap chargé par loadkeys. Rechercher des questions marquées avec la disposition du clavier de la console linux .
Gilles

@ Gilles merci! Il est intéressant de noter que loadkeys modifie les deux mappages keycode -> keysym et keysym -> séquence d'échappement (ce n'était pas évident pour moi au départ).
stewbasic

1
Wow, cela doit être l'une des meilleures réponses que j'ai jamais vues sur Stackexchange - bien organisé, répond à la question, fournit un contexte pertinent, renvoie à d'autres réponses utiles, et a même un bel art ASCII!
Johntron

4

Si vous voulez voir cela dans un système Unix suffisamment petit pour être compréhensible, creusez dans Xv6 . C'est plus ou moins la mythique Unix 6th Edition qui est devenue la base du célèbre commentaire de John Lion , distribué depuis longtemps sous le nom de samizdat. Son code a été retravaillé pour être compilé sous ANSI C et en tenant compte des développements modernes, tels que les multiprocesseurs.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.