web-dev-qa-db-fra.com

Comment fonctionnent la saisie au clavier et la sortie de texte?

Supposons que j'appuie sur A entrez un éditeur de texte et cela insère le caractère a dans le document et l'affiche à l'écran. Je sais que l'application de l'éditeur ne communique pas directement avec le matériel (il y a un noyau et d'autres choses entre les deux), alors que se passe-t-il à l'intérieur de mon ordinateur?

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

  1. Entrée: l'événement de pression de touche est transmis du matériel du clavier à l'application.
  2. Traitement: l'application décide que parce que la clé A a été pressé, il doit afficher le caractère a.
  3. Sortie: l'application donne l'ordre d'afficher a à l'écran.

Applications GUI

L'interface utilisateur graphique standard de facto des systèmes Unix est le X Window System , souvent appelé X11 car il s'est stabilisé dans la 11e version de son protocole de base entre les applications et le serveur d'affichage. Un programme appelé le 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 des pressions de touches à la fenêtre qui a le focus.

Contribution

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

Tout d'abord, les informations sur la pression et le relâchement des touches sont transmises du clavier à l'ordinateur et à l'intérieur de l'ordinateur. 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 partie de la chaîne: une certaine touche a été enfoncée ou relâchée.

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

Lorsqu'un événement matériel se produit, le CPU déclenche un interruption , ce qui provoque l'exécution de code dans le kernel . Ce code détecte que l'événement matériel est une pression sur une touche ou une libération de touche 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/eventNNN sous 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 sur ce périphérique. Le fichier de périphérique transmet les événements de montée/descente des touches avec un code de balayage, qui peut être identique ou non à la valeur transmise par le matériel (le noyau peut traduire le code de balayage d'une valeur dépendante du clavier en une valeur commune, et Linux - ne retransmet pas les codes de scan qu'il ne connaît pas ).

X appelle le code de numérisation qu'il lit un code clé . Le serveur X gère une table qui traduit les codes clés en keysymes (abréviation de "key symbol"). Les codes clés sont numériques, tandis que les noms clés sont des noms tels que A, aacute, F1, KP_Add, Control_L,… Le keysym peut différer selon les touches de modification qui sont enfoncées (ShiftCtrl,…).

Il existe deux mécanismes pour configurer le mappage des codes-clés vers les keysymes:

  • xmodmap est le mécanisme traditionnel. Il s'agit d'un simple tableau mappant les codes-clés à une liste de keyymes (non modifiés, décalés,…).
  • XKB est un mécanisme plus puissant mais plus complexe avec un meilleur support pour plus de modificateurs, en particulier pour la configuration bilingue, entre autres.

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 est active. La notification indique qu'un certain jeu de touches a été enfoncé ou relâché ainsi que les modificateurs actuellement enfoncés. Vous pouvez voir les keysymes en exécutant le programme xev à partir d'un terminal. Ce que l'application fait des informations dépend de lui; certaines applications ont des raccourcis clavier configurables.

Dans une configuration typique, lorsque vous appuyez sur la touche intitulée A sans modificateurs, cela envoie le keysym a à l'application; si l'application est dans un mode où vous tapez du texte, cela insère le caractère a.

Relation entre la disposition du clavier et xmodmap va plus en détail sur la saisie au clavier. Comment les événements de souris fonctionnent-ils sous linux? donne un aperçu de l'entrée de la souris aux niveaux inférieurs.

Production

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

Il existe deux façons d'afficher un personnage.

Voir À quoi servent les 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 le Graphics Processing Unit (le processeur de la carte vidéo) est très dépendant du matériel. Les systèmes simples ont le serveur X dessiner dans une région de mémoire appelée framebuffer , que le GPU récupère pour l'affichage. Les systèmes avancés tels que ceux que l'on trouve sur n'importe quel PC ou smartphone du 21e siècle permettent au GPU d'effectuer directement certaines opérations pour de meilleures performances. En fin de compte, le GPU transmet le contenu de l'écran pixel par pixel chaque fraction de seconde au moniteur.

Application en mode texte, exécutée 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 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 un fond utile ici. Après avoir lu ceci, vous voudrez peut-être lire le 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 comme "Left a été enfoncé alors que Shift était en panne". L'interface entre l'émulateur de terminal et l'application en mode texte est un pseudo-terminal (pty) , a périphérique de caractères qui transmet les octets. Lorsque l'émulateur de terminal reçoit un événement de pression de touche, il le transforme en un ou plusieurs octets que l'application peut lire à 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 selon le caractère et encodage . Par exemple, dans TF-8 = codage du jeu de caractères nicode , les caractères de la plage ASCII sont codés sur un seul octet, tandis que les caractères en dehors de cette plage sont codé en plusieurs octets.

Appui sur les touches correspondant à une touche de fonction ou à un caractère imprimable avec des modificateurs tels que Ctrl ou Alt sont envoyés sous la forme d'une séquence d'échappement . Les séquences d'échappement se composent généralement du caractère escape (valeur d'octet 27 = 0x1B = \033, parfois représenté par ^[ ou \e) suivi d'un ou plusieurs caractères imprimables. Quelques touches ou combinaisons de touches ont un caractère de contrôle qui leur correspond dans les encodages basés sur ASCII (qui sont à peu près tous utilisés aujourd'hui, y compris Unicode): Ctrl+letter renvoie une valeur de caractère comprise entre 1 et 26, Esc est le caractère d'échappement vu ci-dessus et est également le même que Ctrl+[Tab est le même que Ctrl+IReturn est le même que Ctrl+M, etc.

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

Dans un terminal, si vous tapez Ctrl+V suivi d'une combinaison de touches, ceci insère littéralement le premier octet de la séquence d'échappement de la combinaison de touches. Étant donné que les séquences d'échappement ne sont normalement composées que de caractères imprimables après le premier, cela insère littéralement la séquence d'échappement entière. Voir 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 espace pour les deux Space et Shift+Space; xterm a un mode pour distinguer les combinaisons de modificateurs mais les terminaux basés sur la bibliothèque vte populaire ne le font pas ). Quelques touches ne sont pas transmises du tout, par exemple des touches de modification ou des touches qui déclenchent une liaison de l'émulateur de terminal (par exemple une commande copier-coller).

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

Production

+-------------+               +-------------------+
| 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 conserve la position du curseur et défile si le curseur tombe sous le bas de l'écran.) L'application peut également générer des séquences d'échappement (commençant généralement par ^[ ou ^]) pour indiquer au terminal d'effectuer des actions telles que déplacer le curseur, modifier 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 . La plupart des émulateurs de terminaux sont de nos jours assez étroitement alignés avec xterm . Voir Documentation sur les variables LESS_TERMCAP_ *? pour une discussion plus longue des bases de données d'informations sur les capacités du terminal, et Comment empêcher le curseur de clignoter et Puis-je définir le terminal de ma machine locale couleurs pour utiliser celles de la machine dans laquelle je ssh? pour quelques exemples d'utilisation.

Application s'exécutant dans une console texte

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

Application à distance, accessible via le réseau

Application de texte à distance

Si vous exécutez un programme sur une machine distante, par ex. sur SSH , puis 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 à distance

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

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

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

101

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 6ème édition qui est devenue la base du célèbre --- de Lion Lion commentaire , longtemps diffusé sous le nom de samizdat. Son code a été retravaillé pour être compilé sous ANSI C et en tenant compte des développements modernes, comme les multiprocesseurs.

4
vonbrand