- •Клавиатура
- •2.1. Принципы работы клавиатуры
- •2.2. Порты для работы с клавиатурой
- •2.3. Аппаратное прерывание клавиатуры
- •2.4. Средства bios для работы с клавиатурой
- •2.4.1. Чтение символа с ожиданием
- •2.4.2. Проверка буфера на наличие в нем символов
- •2.4.3. Получение состояния переключающих клавиш
- •2.4.4. Установка временных характеристик клавиатуры
- •2.4.5. Запись символов в буфер клавиатуры
- •2.4.6 Чтение символа с ожиданием для 101-клавишной клавиатуры
- •2.4.7. Проверка буфера на наличие в нем символов для 101-клавишной клавиатуры
- •2.4.8. Получение состояния переключающих клавиш для 101-клавишной клавиатуры
- •2.5. Средства ms-dos для работы с клавиатурой
- •2.5.1. Буферизованный ввод с эхо-выводом
- •2.5.2. Буферизованный ввод без эхо-вывода
- •2.5.3. Нефильтрованный ввод без эхо-вывода
- •2.5.4. Ввод/вывод на консоль
- •2.5.5. Ввод строки символов
- •2.5.6. Проверка состояния стандартного ввода
- •2.5.7. Сброс буфера клавиатуры
- •2.6. Клавиатурные функции библиотеки Microsoft c
- •2.6. Драйвера режима ядра для ps/2 клавиатуры Стек драйверов для системных устройств ввода
- •Стек драйверов для Plug and Play ps/2-клавиатуры
- •Стек устройств для Plug and Play ps/2-клавиатуры
- •Обработка клавиатурного ввода приложениями Поток необработанного ввода (получение данных от драйвера)
- •Обработка сообщений конкретным окном
- •Массивы состояния клавиш клавиатуры
- •Клавиатурные ловушки
- •Общая схема обработки
- •Модель прямого ввода (Raw Input)
Общая схема обработки
Обобщим все полученные выше знания о процедуре клавиатурного ввода в едином алгоритме. Итак, алгоритм прохождения сигнала от нажатия пользователем клавиш на клавиатуре до появления символов на экране можно представить следующим образом:
Операционная система при старте создает в системной процессе csrss.exe поток необработанного ввода и системную очередь аппаратного ввода.
Поток необработанного ввода в цикле посылает запросы чтения драйверу класса клавиатуры, которые остаются в состоянии ожидания до появления событий от клавиатуры.
Когда пользователь нажимает или отпускает клавишу на клавиатуре, микроконтроллер клавиатуры фиксирует нажатие/отпускание клавиши и посылает в центральный компьютер скан-код нажатой клавиши и запрос на прерывание.
Системный контроллер клавиатуры получает скан-код, производит преобразование скан-кода, делает его доступным на порту ввода-вывода 60h и генерирует аппаратное прерывание центрального процессора.
Контроллер прерываний вызывает процедуру обработки прерывания IRQ 1, — ISR, зарегистрированную в системе функциональным драйвером клавиатуры i8042prt.
Процедура ISR считывает из внутренней очереди контроллера клавиатуры появившиеся данные, переводит скан-коды в коды виртуальных клавиш (независимые значения, определенные системой) и ставит в очередь вызов отложенной процедуры I8042KeyboardIsrDpc.
Как только это становится возможным, система вызывает DPC, которая в свою очередь вызывает процедуру обратного вызова KeyboardClassServiceCallback, зарегистрированную драйвером класса клавиатуры Kbdclass.
Процедура KeyboardClassServiceCallback извлекает из своей очереди ожидающий завершения запрос от потока необработанного ввода и возвращает в нем информацию о нажатой клавише.
Поток необработанного ввода сохраняет полученную информацию в системной очереди аппаратного ввода и формирует на ее основе базовые клавиатурные сообщения Windows WM_KEYDOWN, WM_KEYUP, которые ставятся в конец очереди виртуального ввода VIQ активного потока.
Цикл обработки сообщений потока удаляет сообщение из очереди и передает его соответствующей оконной процедуре для обработки. При этом может быть вызвана системная функция TranslateMessage, которая на основе базовых клавиатурных сообщений создает дополнительные «символьные» сообщения WM_CHAR, WM_SYSCHAR, WM_DEADCHAR и WM_SYSDEADCHAR.
Модель прямого ввода (Raw Input)
Описанная выше модель клавиатурного ввода имеет ряд недостатков с точки зрения разработчиков приложений. Так, для получения ввода от нестандартного устройства приложение должно выполнить значительное число операций: открыть устройство, периодически его опрашивать, заботиться о возможности параллельного использования устройства другим приложением и т.д. Поэтому в последних версиях ОС Windows была предложена альтернативная модель ввода, названная моделью прямого ввода, упрощающая разработку приложений, использующих нестандартные устройства ввода (см. рисунок 3, приложения DirectInput).
Модель прямого ввода отличается от оригинальной модели ввода Windows. В обычной модели приложение получает устройство-независимый ввод в форме сообщений (таких как WM_CHAR), которые посылаются окнам приложения. В модели прямого ввода приложение должно зарегистрировать устройства, от которых оно хочет получать ввод. Далее приложение получает пользовательский ввод через сообщение WM_INPUT. Поддерживается два способа передачи данных — стандартный и буферизированный; для интерпретации введенных данных приложению нужно получить информацию о природе устройства ввода, что можно сделать с помощью функции GetRawInputDeviceInfo.