Як працюють введення з клавіатури та вихід тексту?


85

Припустимо, я натискаю Aклавішу в текстовому редакторі, і вона вставляє символ aу документ і виводить його на екран. Я знаю, що програма редактора не зв’язується безпосередньо з обладнанням (між ними є ядро ​​та речі), і що відбувається всередині мого комп'ютера?

Відповіді:


100

Існує кілька різних сценаріїв; Я опишу найпоширеніші з них. Наступними макроскопічними подіями є:

  1. Введення: подія натискання клавіші передається від апаратного забезпечення клавіатури до програми.
  2. Обробка: програма вирішує, що оскільки натиснута клавіша A, вона повинна відображати символ a.
  3. Вихід: програма дає наказ відображатись aна екрані.

GUI-програми

Фактично стандартним графічним інтерфейсом користувача Unix є X Window System , часто його називають X11, оскільки він стабілізувався в 11-й версії свого основного протоколу між програмами та сервером відображення. Програма під назвою X-сервер сидить між ядром операційної системи та програмами; він надає послуги, включаючи показ вікон на екрані та передачу натискань клавіш на вікно, на якому фокусується.

Вхідні дані

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

По-перше, інформація про натискання клавіш і звільнення клавіш передається з клавіатури на комп'ютер і всередині комп'ютера. Деталі залежать від типу обладнання. Я не буду більше зупинятися на цій частині, оскільки інформація залишається однаковою у цій частині ланцюга: певна клавіша була натиснута або відпущена.

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

Коли трапляється апаратна подія, ЦП викликає переривання , що призводить до виконання деякого коду в ядрі . Цей код виявляє, що апаратною подією є натискання клавіші або звільнення клавіш, що надходить з клавіатури, і записує код сканування, який ідентифікує ключ.

Сервер X зчитує події введення через файл пристрою , наприклад /dev/input/eventNNNв Linux (де NNN - це число). Щоразу, коли відбувається подія, ядро ​​сигналізує, що є дані для читання з цього пристрою. Файл пристрою передає ключові події вгору / вниз з кодом сканування, який може бути або не бути ідентичним значенню, що передається обладнанням (ядро може перевести код сканування з значення, яке залежить від клавіатури, у загальне значення, а Linux не робить не повторно передайте коди сканування, які він не знає ).

X називає код сканування, який читає код ключа . Сервер X підтримує таблицю, яка переводить коди ключів у ключові символи (скорочення "символ ключа"). Кодові ключі є числами, тоді як символи клавіш назви , такі як A, aacute, F1, KP_Add, Control_L, ... The може відрізнятися символ клавіші в залежності від того, які клавіші - модифікатори натискаються ( Shift, Ctrl, ...).

Існує два механізми налаштування відображення від клавішних кодів до ключових символів:

  • xmodmap - традиційний механізм. Це просте табличне відображення клавішних кодів до списку ключових символів (немодифікованих, зміщених,…).
  • XKB - це більш потужний, але більш складний механізм з кращою підтримкою більшої кількості модифікаторів, зокрема для двомовної конфігурації, серед інших.

Програми підключаються до сервера X і отримують сповіщення, коли натискається клавіша, а у фокусі вікна цієї програми. У повідомленні вказується, що певна клавіша була натиснута або відпущена, а також які модифікатори в даний час натиснуті. Ви можете бачити ключі, запустивши програму xevз терміналу. Те, що додаток робить з інформацією, залежить від цього; деякі програми мають настроювані прив'язки клавіш.

У типовій конфігурації, коли ви натискаєте клавішу, позначену Aбез модифікаторів, це надсилає програму keyym a; якщо програма перебуває в режимі, коли ви вводите текст, у неї вставляється символ a.

Зв'язок розкладки клавіатури та xmodmap детальніше описується на введенні клавіатури. Як працюють події миші в Linux? дає огляд введення миші на нижчих рівнях.

Вихідні дані

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

Існує два способи відображення персонажа.

Див. Які цілі різних типів шрифтів XWindows? для обговорення відображення тексту на стороні клієнта та сервера під X11.

Що відбувається між сервером X та графічним процесором (процесор на відеокарті) дуже залежить від обладнання. Прості системи мають сервер X малювання в області пам'яті, що називається фреймбуфер , який GPU підбирає для відображення. Вдосконалені системи, такі як будь-який ПК 21 століття або смартфон, дозволяють GPU виконувати деякі операції безпосередньо для кращої продуктивності. Зрештою, GPU передає монітор піксель вмісту екрана кожну частку секунди.

Додаток в текстовому режимі, працює в терміналі

Якщо ваш текстовий редактор - це програма текстового режиму, що працює в терміналі, то саме термінал є додатком для цілей розділу вище. У цьому розділі я пояснюю інтерфейс між програмою текстового режиму та терміналом. Спочатку я описую випадок термінального емулятора, що працює під X11. Яка точна різниця між 'терміналом', 'оболонкою', 'tty' та 'консоллю'? може бути корисним фоном тут. Прочитавши це, ви, можливо, захочете прочитати набагато детальніше Які обов'язки кожного компонента Pseudo-Terminal (PTY) (програмне забезпечення, сторона ведучого, підлеглий)?

Вхідні дані

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

Емулятор терміналу приймає події типу " Leftнатискали, поки не Shiftбуло". Інтерфейс між емулятором терміналу та програмою текстового режиму - це псевдотермінал (pty) , символьний пристрій, який передає байти. Коли емулятор терміналу отримує ключову подію натискання, він перетворює це в один або декілька байтів, які програма отримує для читання з pty пристрою.

Друковані символи поза діапазоном ASCII передаються у вигляді одного або декількох байтів залежно від символу та кодування . Наприклад, в UTF-8 кодуванні Unicode , набір символів, символи в ASCII діапазоні кодуються як одного байта, в той час як символи за межами цього діапазону кодуються в вигляді декількох байт.

Натискання клавіш, які відповідають функціональній клавіші або символу для друку з модифікаторами, такими як Ctrlабо Altнадсилаються як послідовність виходу . Послідовності виходу, як правило, складаються з символу втечі (значення байта 27 = 0x1B = \033, іноді представлене як ^[або \e) з наступним одним або декількома символами для друку. Кілька клавіш або комбінацій клавіш мають відповідний їм символ керування в кодуваннях на основі ASCII (що майже всі вони використовуються сьогодні, включаючи Unicode): Ctrl+ letterдає значення символу в діапазоні 1–26, Escце символ втечі видно вище і також те саме, що і Ctrl+ [, Tabте саме, що і Ctrl+ I,Returnте саме, що і Ctrl+ Mтощо.

Різні термінали надсилають різні послідовності відходу для заданої комбінації клавіш або клавіш. На щастя, зворотне не відповідає дійсності: враховуючи послідовність, на практиці існує максимум одна комбінація клавіш, яку вона кодує. Єдиним винятком є ​​символ 127 = 0x7f = \0177який часто, Backspaceале іноді Delete.

У терміналі, якщо ви введете Ctrl+ з Vнаступною комбінацією клавіш, у цей параметр вводиться буквально перший байт послідовності запуску з комбінації клавіш. Оскільки послідовності втечі зазвичай складаються лише з символів для друку після першого, це вводить всю послідовність втечі буквально. Дивіться таблицю ключових прив'язок? для обговорення zsh в цьому контексті.

Термінал може передавати ту саму послідовність відхилення для деяких комбінацій модифікаторів (наприклад, багато термінали передають символ пробілу для обох Spaceі Shift+ Space; xterm має режим розрізнення комбінацій модифікаторів, але термінали на основі популярної бібліотеки vte не мають ). Кілька клавіш взагалі не передаються, наприклад клавіші-модифікатори або клавіші, які викликають прив'язку емулятора терміналу (наприклад, команда копіювання або вставки).

Додаток повинен перекласти послідовності втечі в символічні імена ключів, якщо цього забажає.

Вихідні дані

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

Вихід є більш простим, ніж введення. Якщо програма виводить символ у файл пристрою pty, емулятор термінала відображає його у поточному положенні курсора. (Емулятор терміналу підтримує позицію курсора і прокручує, якщо курсор потрапить під нижню частину екрана.) Додаток також може виводити послідовності втечі (переважно починаючи з ^[або ^]), щоб повідомити терміналу виконувати дії, такі як переміщення курсору, зміна текстових атрибутів (кольоровий, жирний,…) або стирання частини екрана.

Послідовності виходу, що підтримуються емулятором терміналу, описані в базі даних termcap або terminfo . Більшість термінальних емуляторів сьогодні досить тісно узгоджені з xterm . Див. Документацію щодо змінних LESS_TERMCAP_ *? для більш тривалого обговорення баз даних про можливості терміналу, а також як запобігти морганню курсору та чи можу я встановити кольори кінцевих термінів моєї локальної машини для використання кольорів машини, в яку я потрапляю? для деяких прикладів використання.

Запуск програми в текстовій консолі

Якщо програма працює безпосередньо в текстовій консолі, тобто терміналі, наданому ядром, а не програмою емулятора терміналу, застосовуються ті самі принципи. Інтерфейс між терміналом та програмою все ще є байтовим потоком, який передає символи, за допомогою спеціальних клавіш та команд, кодованих як послідовності відходу.

Віддалений додаток, доступ до якого здійснюється через мережу

Віддалений текстовий додаток

Якщо ви запускаєте програму на віддаленій машині, наприклад, через SSH , протокол мережевого зв’язку ретранслює дані на рівні pty.

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

Це здебільшого прозоро, за винятком того, що іноді база даних віддалених терміналів може не знати всіх можливостей локального терміналу.

Віддалений додаток X11

Протокол зв'язку між додатками та сервером сам по собі є байтовим потоком, який може бути відправлений через мережевий протокол, такий як SSH.

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

Це здебільшого прозоро, за винятком того, що деякі функції прискорення, такі як декодування фільмів та 3D-рендерінг, які потребують прямого зв’язку між програмою та дисплеєм, недоступні.


Не зовсім впевнений, але оскільки відповідь, як правило, досить детальна, мені цікаво, чи може в частині, що говорить "Програма, запущена на текстовій консолі", не передбачено, що такі речі man 5 keymapsвикористовуються для перекладу keycodesна scancodes. Хоча, як уже згадувалося, принципово подібне, але це цілком інший набір інструментів / програм, і це заслуговує, можливо, ще на деяку думку. Поруч із цим відповідь +1 і чудова через вбудовані відповідні запитання.
humanityANDpeace

Я знайшов PgUpі Ctrl+PgUpне відрізняються від tty1 (TERM = linux). Чи можна налаштувати відображення послідовності управління keyym ->?
тушканчик

@stewbasic Так, з завантаженою карткою loadkeys. Пошук питань із тегом клавіатури консолі Linux .
Жиль

@Gilles дякую! Варто відзначити, що loadkeys змінює як відображення keycode -> keyym, так і keyym -> послідовність втечі (для мене це спочатку не було очевидно).
тушканчик

1
Ого, це має бути одна з найкращих відповідей, яку я коли-небудь бачив на Stackexchange - добре організована, відповідає на питання, надає відповідний контекст, перехресні посилання інших корисних відповідей і навіть має приємне мистецтво ASCII!
Джоннтрон

4

Якщо ви хочете побачити це в системі Unix, яка є досить маленькою, щоб зрозуміти, зарибіться в Xv6 . Це більш-менш міфічна версія 6-го видання Unix, яка стала основою відомого коментаря Джона Лева , давно розповсюдженого як самвидав. Його код був перероблений для складання під ANSI C та врахування сучасних розробок, як багатопроцесорних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.