Программное обеспечение клавиатуры

Число, фигурирующее в порте ввода-вывода, является номером клавиши, который называется скан-кодом (не следует его путать с кодом А8СП). У обычных клавиатур имеется не более 128 клавиш, поэтому для представления номера клавиши хватает семи битов.
Восьмой бит устанавливается в 0, когда клавишу нажимают, и в 1, когда ее отпускают. Состояние каждой клавиши (нижнее или верхнее ее положение) должен отслеживать драйвер клавиатуры. Следовательно, роль оборудования сводится к предоставлению прерывания нажатия и освобождения. Все остальное выполняется программными средствами.

К примеру, когда нажата клавиша A, ее скан-код (30) помещается в регистр ввода-вывода. Драйвер должен определить, в режиме какого регистра, верхнего или нижнего, работает клавиатура, в каком именно сочетании нажата эта клавиша, CTRL+A, ALT+A, CTRL+ALT+A или каком-нибудь другом. Поскольку драйвер может различить, какая клавиша была нажата, но еще не отпущена (например, SHIFT), у него вполне достаточно информации для успешной работы. К примеру, такая последовательность работы на клавиатуре: нажать SHIFT, нажать A, отпустить A, отпустить SHIFT — будет означать A в верхнем регистре. Но такая последовательность: нажать SHIFT, нажать A, отпустить SHIFT, отпустить A — также будет означать A в верхнем регистре. Хотя при таком клавиатурном интерфейсе все возлагается на программное обеспечение, он имеет исключительно гибкий характер. К примеру, пользовательской программе может быть интересно, где вводилась цифра, на верхнем ряду клавиатуры или на дополнительной цифровой клавиатуре, расположенной сбоку. В принципе, драйвер может предоставить и такую информацию.

Для драйвера могут быть приняты два основных подхода. Первый из них ограничивает работу драйвера восприятием входящей информации и передачей ее на более высокий уровень без всяких изменений. Программа чтения с клавиатуры получает необработанную последовательность ASCII-кодов. (Предоставлять пользовательским программам скан-коды было бы слишком примитивным решением, к тому же находящимся в сильной зависимости от используемой клавиатуры[32].)

Этот подход хорошо сочетается с потребностями таких сложных экранных редакторов, как emacs, которые позволяют пользователю привязывать произвольное действие к любым символу или последовательности символов. Но это означает, что если пользователь наберет dste вместо date, а затем исправит ошибку, нажав три раза на клавишу удаления (backspace) и набрав ate, и завершит все это вводом символа возврата каретки, пользовательская программа получит все 11 введенных ASCII-кодов:

dste^-^ate CR

Подобная детализация нужна не всем программам. Зачастую им нужен просто исправленный ввод, а не точная последовательность, в которой он был произведен. Это наблюдение приводит ко второму подходу: драйвер обрабатывает все редактирование внутри строки, а пользовательской программе предоставляются уже скорректированные строки. Первый подход является символьно-ориентированным, а второй — строчно-ориентированным. Первоначально они назывались соответственно режимом без обработки и режимом с обработкой. Для описания строчно-ориентированного подхода в стандарте POSIX используется менее образный термин канонический режим. А термин неканонический режим является эквивалентом для режима без обработки, хотя многие особенности его поведения могут быть изменены. POSIX-совместимые системы предоставляют несколько библиотечных функций, поддерживающих выбор обоих режимов и изменение многих параметров.

Если клавиатура находится в каноническом режиме (с обработкой), символы должны храниться до тех пор, пока не будет набрана вся строка, поскольку пользователь, приступив к набору, может впоследствии принять решение об удалении части строки. Даже если клавиатура находится в режиме без обработки, программа могла еще не запрашивать входные данные, поэтому символы должны храниться в буфере, позволяя пользователю осуществлять упреждающий ввод. Для этих целей должен использоваться либо специализированный буфер, либо буфер, выделенный из пула. В первом случае на упреждающий ввод накладывается определенный лимит, а во втором — нет. Наиболее четко необходимость буфера проявляется, когда пользователь осуществляет ввод в окне оболочки (или в окне командной строки, если говорить о Windows) в то время, когда предыдущая команда (например, на компиляцию) еще не завершена. Последовательно набираемые символы должны скапливаться в буфере, поскольку оболочка еще не готова их прочитать. Системных программистов, не дающих пользователям выполнять предварительный ввод с клавиатуры, нужно окунать в смолу и обваливать в перьях или, и того хуже, заставлять работать на их же собственных системах.

Хотя логически клавиатура и монитор являются отдельными устройствами, многие пользователи привыкли к тому, чтобы набираемые ими символы появлялись на экране. Этот процесс называется отображением (echoing)[33].

Отображение усложняется тем, что программа может выводить на экран другую информацию как раз в то время, когда пользователь что-нибудь набирает на клавиатуре (опять представьте, что вводите данные в окно оболочки). По крайней мере, драйвер клавиатуры должен определить, куда помещать новый ввод, чтобы на него не накладывался программный вывод.

Отображение ввода усложняется и тем, что при вводе более 80 символов их надо отображать в 80-символьных строках (или в строках другой длины). В зависимости от приложения в данном случае можно применить перенос на следующую строку. Некоторые драйверы просто урезают строку до 80 символов, отбрасывая все символы после 80-й позиции.

Другой проблемой является обработка символа табуляции. Обычно именно драйвер должен вычислять текущую позицию курсора, учитывая как вывод, осуществляемый программой, так и вывод в процессе отображения ввода, и вычислять точное количество отображаемых пробелов.

Теперь рассмотрим проблему эквивалентности устройств. Логически в конце строки текста одним из них нужен код возврата каретки, чтобы переместить курсор обратно на первую позицию, и код перевода строки, чтобы перейти на новую строку. Требования к пользователям ставить оба этих кода в конце каждой строки вряд ли было бы встречено с восторгом. Поэтому драйвер устройства должен конвертировать все в формат, используемый операционной системой, независимо от того, что именно было введено. В UNIX код клавиши ENTER конвертируется для внутреннего запоминания в код перевода строки, а в Windows он конвертируется в код возврата каретки, за которым следует код перевода строки.

Если стандартным является хранение кода перевода строки (как в соглашении UNIX), то коды возврата каретки (генерируемые при нажатии клавиши ENTER) должны быть превращены в коды перевода строки. Если внутренний формат предусматривает хранение обоих кодов (как в соглашении Windows), то драйвер должны сгенерировать код возврата строки при получении кода возврата каретки и код возврата каретки при получении кода перевода строки. Независимо от используемого внутреннего соглашения монитор для отображения ввода может потребовать и код перевода строки, и код возврата каретки, чтобы правильно обновлять экран. На многопользовательских системах, например на больших универсальных машинах, у разных пользователей могут быть разные типы терминалов, подключенных к машине, и драйвер клавиатуры должен получать всевозможные комбинации кодов возврата каретки/перевода строки и преобразовывать их во внутренний стандарт системы, а также выстраивать их таким образом, чтобы отображение выполнялось правильно.

При работе в каноническом режиме некоторые вводимые символы имеют специальное предназначение. В табл. 5.4 показаны все специальные символы, необходимые системе POSIX. Подразумевается, что все они являются символами управления, не конфликтующими с текстовым вводом или кодами, используемыми программами; все, кроме последних двух, могут быть изменены программным способом.

Таблица 5.4. Символы, обрабатываемые особым образом в каноническом режиме


Символ ERASE позволяет пользователю стереть только что введенный символ. Обычно для этого применяется клавиша удаления Backspace (CTRL+H). Он не добавляется в очередь символов, а вместо этого удаляет из нее предыдущий символ. Чтобы удалить предыдущий символ с экрана, он должен быть отображен в виде последовательности из трех символов: забивания, пробела и забивания. Если предыдущий символ был символом табуляции, его удаление зависит от того, как он был обработан при наборе. Если он немедленно был превращен в несколько пробелов, то для определения того, на сколько символов следует вернуться, нужна дополнительная информация. Если в очереди ввода сохранен сам символ табуляции, он может быть удален, а вся строка выведена на экран заново. В большинстве систем при забивании будут всего лишь стираться символы в текущей строке. Забивание не будет стирать возврат каретки и возвращать курсор на предыдущую строку. Если пользователь заметит ошибку при наборе в самом начале строки, ему чаще всего удобнее удалить всю строку и начать набор заново. Символ KILL удаляет всю строку. Многие системы убирают стертую строку с экрана, но к отображению ввода на некоторых старых системах добавляются возврат каретки и перевод строки, поскольку некоторые пользователи предпочитают видеть прежний вариант строки. В конечном счете, способ отображения ввода символа KILL — это дело вкуса. Как и в случае с символом ERASE, уйти назад за пределы текущей строки не представляется возможным. При удалении блока символов драйвер может испытывать, а может и не испытывать затруднения с возвратом задействованных буферов в пул.

Иногда символы ERASE или KILL должны вводиться как обычные данные. В этом случае в качестве эскейп-символа (escape character) служит LNEXT[34]. В UNIX для его ввода по умолчанию используется CTRL+V. К примеру, старые UNIX-системы часто используют в качестве символа KILL знак @, но почтовая система Интернета использует адреса вида linda@cs.washington.edu. Все, кому удобнее пользоваться старым соглашением, могут переопределить KILL и назначить для него знак @, но тогда им придется вводить знак @ в адресную строку электронной почты в буквальном виде. Это делается путем набора последовательности CTRL+V @. Сам символ CTRL+V тоже может быть введен в буквальном виде путем последовательного двойного набора CTRL+V. Как только драйвер встречает CTRL+V, он выставляет флажок, свидетельствующий о том, что следующий символ исключается из обработки особым способом. Сам символ LNEXT в очередь символов не заносится.

Чтобы дать возможность пользователям остановить прокрутку изображения на экране за пределы видимости, предоставляются управляющие коды для остановки и последующего возобновления прокрутки. В UNIX для этого используются коды STOP (CTRL+S) и START (CTRL+Q) соответственно. Они не сохраняются, а используются для установки и снятия флажка в структуре данных клавиатуры. Когда предпринимается попытка вывода информации на экран, проверяется состояние этого флажка. Если он установлен, вывод не осуществляется. Наряду с программным выводом обычно подавляется и отображение ввода.

Довольно часто возникает необходимость прервать работу вышедшей из-под контроля отлаживаемой программы. Для этого могут быть использованы символы INTR (DEL) и QUIT (CTRL+\). В UNIX клавиша DEL посылает сигнал SIGINTвсем процессам, запущенным с этой клавиатуры. Реализация работы клавиши DEL может быть крайне затруднена, поскольку UNIX с самого начала разрабатывалась для одновременной работы с несколькими пользователями. Поэтому обычно приходится иметь дело с множеством процессов, запущенных от имени многих пользователей, и клавиша DEL должна послать сигнал только процессу, принадлежащему данному пользователю. Трудности возникают при получении информации от драйвера той частью операционной системы, которая обрабатывает сигналы и которая, ко всему прочему, эту информацию и не запрашивает.

Действие сочетания клавиш CTRL+\ подобно действию клавиши DEL, за исключением того, что посылается сигнал SIGQUIT, вызывающий вывод дампа ядра, если этот сигнал не перехватывается или не игнорируется. При нажатии любой из этих клавиш драйвер должен отобразить возврат каретки и перевод строки и сбросить весь накопленный ввод, позволяя начать все с чистого листа. Зачастую для INTR используется сочетание CTRL+C, а не клавиша DEL, поскольку многие программы используют DEL наряду с клавишей забивания для редактирования ввода.

Следующий специальный символ, EOF (CTRL+D), вызывает в UNIX выполнение для терминала всех отложенных запросов на чтение, используя все содержимое буфера, даже если буфер пуст. Ввод CTRL+D в самом начале строки заставляет программу прочитать нуль байтов, что условно воспринимается как конец файла и заставляет многие программы действовать точно так же, как при встрече кода конца файла во входном файле.

<< | >>
Источник: Э. ТАНЕНБАУМ Х. БОС. СОВРЕМЕННЫЕ ОПЕРАЦИОННЫЕ СИСТЕМ Ы 4-е ИЗДАНИЕ. 2015

Еще по теме Программное обеспечение клавиатуры:

  1. Программное обеспечение
  2. Богомазова Г.Н.. Установка и обслуживание программного обеспечения персональных компьютеров, серверов, периферийных устройств и оборудования, 2015
  3. Эд САЛЛИВАН. ВРЕМЯ — ДЕНЬГИ Создание команды разработчиков, программного обеспечения, 2001
  4. Том ДеМарко. Вальсируя с Медведями Управление рисками в проектах по разработке программного обеспечения, 2005
  5. Алистэр Коуберн. Люди как нелинейные и наиболее важные компоненты в создании программного обеспечения, 1999
  6. 2.4.1. Программный анализатор
  7. КОНЦЕПЦИЯ ПРОГРАММНО - РОЛЕВАЯ
  8. 2.4.1. Программный анализатор
  9. Перевод программных вопросов в анкетные
  10. Глава 39 О ПРОГРАММНЫХ СВОЙСТВАХ ХУДОЖЕСТВЕННОЙ ЛИТЕРАТУРЫ
  11. Статья 361-1. Создание, использование и распространение или сбыта вредных программных или технических средств, а также их распространение или сбыт
  12. Н.В.СТРУМПЭ, В.Д.СИДОРОВ. АППАРАТНОЕ ОБЕСПЕЧЕНИЕ ЭВМ, 2014
  13. В.Д.СИДОРОВ, Н.В.СТРУМП. АППАРАТНОЕ ОБЕСПЕЧЕНИЕ ЭВМ, 2014
  14. Обеспечение морально-психологической подготовки.
  15. Тема 20. Обеспечение исполнения обязательств
  16. Глава 25 ОБЕСПЕЧЕНИЕ ИСПОЛНЕНИЯ ОБЯЗАТЕЛЬСТВ