¿Cómo funcionan la entrada del teclado y la salida de texto?

85

Supongamos que presiono la Atecla en un editor de texto y esto inserta el carácter aen el documento y lo muestra en la pantalla. Sé que la aplicación del editor no se está comunicando directamente con el hardware (hay un kernel y otras cosas en el medio), entonces, ¿qué está pasando dentro de mi computadora?

Gilles
fuente

Respuestas:

100

Hay varios escenarios diferentes; Describiré los más comunes. Los sucesivos eventos macroscópicos son:

  1. Entrada: el evento de pulsación de tecla se transmite desde el hardware del teclado a la aplicación.
  2. Procesamiento: la aplicación decide que debido a que Ase presionó la tecla , debe mostrar el carácter a.
  3. Salida: la aplicación da la orden de mostrar aen pantalla.

Aplicaciones GUI

La interfaz gráfica de usuario estándar de facto de los sistemas Unix es el sistema X Window , a menudo llamado X11 porque se estabilizó en la 11ª versión de su protocolo principal entre las aplicaciones y el servidor de visualización. Un programa llamado servidor X se ubica entre el núcleo del sistema operativo y las aplicaciones; proporciona servicios que incluyen mostrar ventanas en la pantalla y transmitir pulsaciones de teclas a la ventana que tiene el foco.

Entrada

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

Primero, la información sobre la pulsación y liberación de teclas se transmite desde el teclado a la computadora y dentro de la computadora. Los detalles dependen del tipo de hardware. No me detendré más en esta parte porque la información sigue siendo la misma en toda esta parte de la cadena: se presionó o soltó cierta tecla.

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

Cuando ocurre un evento de hardware, la CPU activa una interrupción , lo que hace que se ejecute algún código en el núcleo . Este código detecta que el evento de hardware es una pulsación de tecla o liberación de tecla que proviene de un teclado y registra el código de escaneo que identifica la tecla.

El servidor X lee los eventos de entrada a través de un archivo de dispositivo , por ejemplo /dev/input/eventNNNen Linux (donde NNN es un número). Cada vez que hay un evento, el núcleo señala que hay datos para leer desde ese dispositivo. El archivo del dispositivo transmite eventos clave arriba / abajo con un código de escaneo, que puede o no ser idéntico al valor transmitido por el hardware (el núcleo puede traducir el código de escaneo de un valor dependiente del teclado a un valor común, y Linux no no retransmita los códigos de escaneo que no conoce ).

X llama al código de escaneo que lee un código clave . El servidor X mantiene una tabla que traduce los códigos clave en keyyms (abreviatura de "símbolo clave"). Códigos de teclas son numéricos, mientras que las teclas keysyms son nombres como A, aacute, F1, KP_Add, Control_L, ... El keysym puede diferir dependiendo de la cual se presionan las teclas de modificación ( Shift, Ctrl, ...).

Hay dos mecanismos para configurar la asignación de códigos de teclas a símbolos de teclas:

  • xmodmap es el mecanismo tradicional. Es una tabla simple que asigna códigos clave a una lista de claves (no modificados, desplazados, ...).
  • XKB es un mecanismo más potente, pero más complejo, con mejor soporte para más modificadores, en particular para la configuración de dos idiomas, entre otros.

Las aplicaciones se conectan al servidor X y reciben una notificación cuando se presiona una tecla mientras una ventana de esa aplicación tiene el foco. La notificación indica que se presionó o liberó un cierto teclado, así como qué modificadores se presionan actualmente. Puede ver keyyms ejecutando el programa xevdesde una terminal. Lo que hace la aplicación con la información depende de ello; Algunas aplicaciones tienen combinaciones de teclas configurables.

En una configuración típica, cuando presiona la tecla etiquetada Asin modificadores, esto envía el teclado aa la aplicación; Si la aplicación está en un modo en el que está escribiendo texto, esto inserta el carácter a.

La relación entre el diseño del teclado y xmodmap entra en más detalles sobre la entrada del teclado. ¿Cómo funcionan los eventos del mouse en Linux? da una visión general de la entrada del mouse en los niveles inferiores.

Salida

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

Hay dos formas de mostrar un personaje.

Consulte ¿Cuáles son los propósitos de los diferentes tipos de fuentes XWindows? para una discusión de la representación de texto del lado del cliente y del lado del servidor bajo X11.

Lo que sucede entre el servidor X y la unidad de procesamiento de gráficos (el procesador de la tarjeta de video) depende mucho del hardware. Los sistemas simples tienen el servidor X en una región de memoria llamada framebuffer , que la GPU recoge para mostrar. Los sistemas avanzados como los que se encuentran en cualquier PC o teléfono inteligente del siglo XXI permiten que la GPU realice algunas operaciones directamente para un mejor rendimiento. En última instancia, la GPU transmite el contenido de la pantalla píxel por píxel cada fracción de segundo al monitor.

Aplicación en modo texto, ejecutándose en una terminal

Si su editor de texto es una aplicación de modo de texto que se ejecuta en un terminal, entonces es el terminal el que es la aplicación para los fines de la sección anterior. En esta sección, explico la interfaz entre la aplicación en modo texto y el terminal. Primero describo el caso de un emulador de terminal que se ejecuta bajo X11. ¿Cuál es la diferencia exacta entre un 'terminal', un 'shell', un 'tty' y una 'consola'? puede ser útil fondo aquí. Después de leer esto, es posible que desee leer más detalladamente ¿Cuáles son las responsabilidades de cada componente de Pseudo-Terminal (PTY) (software, lado maestro, lado esclavo)?

Entrada

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

El emulador de terminal recibe eventos como " Leftse presionó mientras Shiftestaba inactivo". La interfaz entre el emulador de terminal y la aplicación de modo de texto es un pseudo-terminal (pty) , un dispositivo de caracteres que transmite bytes. Cuando el emulador de terminal recibe un evento de pulsación de tecla, lo transforma en uno o más bytes que la aplicación puede leer desde el dispositivo pty.

Los caracteres imprimibles fuera del rango ASCII se transmiten como uno o más bytes, dependiendo del carácter y la codificación . Por ejemplo, en la codificación UTF-8 del conjunto de caracteres Unicode , los caracteres en el rango ASCII se codifican como bytes únicos, mientras que los caracteres fuera de ese rango se codifican como bytes múltiples.

Las pulsaciones de teclas que corresponden a una tecla de función o un carácter imprimible con modificadores como Ctrlo Altse envían como una secuencia de escape . Las secuencias de escape generalmente consisten en el escape de caracteres (valor de byte 27 = 0x1B = \033, a veces representado como ^[o \e) seguido de uno o más caracteres imprimibles. Algunas teclas o combinaciones de teclas tienen un carácter de control que se corresponde con ellas en codificaciones basadas en ASCII (que prácticamente se utilizan en la actualidad, incluido Unicode): Ctrl+ letterproduce un valor de carácter en el rango 1–26, Esces el carácter de escape visto arriba y también es lo mismo que Ctrl+ [, Tabes lo mismo que Ctrl+ I,Returnes lo mismo que Ctrl+ M, etc.

Diferentes terminales envían diferentes secuencias de escape para una determinada tecla o combinación de teclas. Afortunadamente, lo contrario no es cierto: dada una secuencia, en la práctica existe como máximo una combinación de teclas que codifica. La única excepción es el carácter 127 = 0x7f = \0177que es frecuente Backspacepero a veces Delete.

En una terminal, si escribe Ctrl+ Vseguido de una combinación de teclas, esto inserta literalmente el primer byte de la secuencia de escape de la combinación de teclas. Dado que las secuencias de escape normalmente consisten solo en caracteres imprimibles después del primero, esto inserta literalmente toda la secuencia de escape. Ver tabla de enlaces de teclas? para una discusión de zsh en este contexto.

El terminal puede transmitir la misma secuencia de escape para algunas combinaciones de modificadores (por ejemplo, muchos terminales transmiten un carácter de espacio para ambos Spacey Shift+ Space; xterm tiene un modo para distinguir combinaciones de modificadores, pero los terminales basados ​​en la popular biblioteca vte no lo hacen ). Algunas teclas no se transmiten en absoluto, por ejemplo, teclas modificadoras o teclas que desencadenan un enlace del emulador de terminal (por ejemplo, un comando copiar o pegar).

Depende de la aplicación traducir las secuencias de escape en nombres clave simbólicos si así lo desea.

Salida

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

La salida es bastante más simple que la entrada. Si la aplicación genera un carácter en el archivo del dispositivo pty, el emulador de terminal lo muestra en la posición actual del cursor. (El emulador de terminal mantiene la posición del cursor y se desplaza si el cursor se encuentra debajo de la parte inferior de la pantalla). La aplicación también puede generar secuencias de escape (principalmente comenzando con ^[o ^]) para indicarle al terminal que realice acciones como mover el cursor, cambiar los atributos del texto (color, negrita, ...) o borrar parte de la pantalla.

Las secuencias de escape compatibles con el emulador de terminal se describen en la base de datos termcap o terminfo . La mayoría de los emuladores de terminal hoy en día están bastante alineados con xterm . ¿Ver documentación sobre LESS_TERMCAP_ * variables? para una discusión más larga de las bases de datos de información de capacidad de terminal, y cómo evitar que el cursor parpadee y ¿puedo configurar los colores de terminal de mi máquina local para usar los de la máquina en la que ssh? para algunos ejemplos de uso

Aplicación ejecutándose en una consola de texto

Si la aplicación se ejecuta directamente en una consola de texto, es decir, un terminal proporcionado por el núcleo en lugar de una aplicación de emulador de terminal, se aplican los mismos principios. La interfaz entre el terminal y la aplicación sigue siendo un flujo de bytes que transmite caracteres, con teclas y comandos especiales codificados como secuencias de escape.

Aplicación remota, a la que se accede a través de la red

Aplicación de texto remoto

Si ejecuta un programa en una máquina remota, por ejemplo, a través de SSH , el protocolo de comunicación de red transmite los datos al nivel pty.

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

Esto es principalmente transparente, excepto que a veces la base de datos del terminal remoto puede no conocer todas las capacidades del terminal local.

Aplicación remota X11

El protocolo de comunicación entre aplicaciones y el servidor es en sí mismo un flujo de bytes que puede enviarse a través de un protocolo de red como SSH.

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

Esto es principalmente transparente, excepto que algunas funciones de aceleración, como la decodificación de películas y la representación en 3D, que requieren comunicación directa entre la aplicación y la pantalla no están disponibles.

Gilles
fuente
No del todo seguro, pero ya que la respuesta es generalmente bastante detallada Me pregunto si la parte que dice "La aplicación se ejecuta en una consola de texto" podría no cuentan con que hay cosas como man 5 keymapsse utilizan para traducir el keycodesa scancodes. Si bien, como se mencionó en principio, es similar, pero es un conjunto completamente diferente de herramientas / programas y esto merecería tal vez algunas ideas más. Además de eso, la respuesta es +1 y excelente debido a las preguntas relacionadas incrustadas.
humanityANDpeace
Encontré PgUpy no Ctrl+PgUpse puede distinguir en tty1 (TERM = linux). ¿Se puede configurar el mapeo de claves -> control de secuencia de control?
stewbasic
@stewbasic Sí, con un mapa de teclas cargado por loadkeys. Busque preguntas etiquetadas con el diseño de teclado de la consola de Linux .
Gilles
@Gilles gracias! Vale la pena señalar que loadkeys cambia el código clave de ambas asignaciones -> keysym y keysym -> secuencia de escape (esto no era inicialmente obvio para mí).
stewbasic
1
Wow, esta tiene que ser una de las mejores respuestas que he visto en Stackexchange: bien organizada, responde a la pregunta, proporciona contexto relevante, hace referencias cruzadas a otras respuestas útiles, ¡e incluso tiene un bonito arte ASCII!
Johntron
4

Si desea ver esto en un sistema Unix que es lo suficientemente pequeño como para ser comprensible, busque en Xv6 . Es más o menos la mítica 6ta edición de Unix la que se convirtió en la base del famoso comentario de John Lion , circulado durante mucho tiempo como samizdat. Su código fue reelaborado para compilar bajo ANSI C y teniendo en cuenta los desarrollos modernos, como los multiprocesadores.

vonbrand
fuente