Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 [ 100 ] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

интерпретации нажатия клавиши. Они имеют разное назначение. Например, флаг capslock переключается с TRUE на FALSE, и наоборот при нажатии клавиши Caps Lock. Флаг shift устанавливается в TRUE, когда нажимается клавиша SHIF, и сбрасывается, когда она отпускается. Переменная esc устанавливается, когда получен код опроса клавиатуры escape. Она всегда сбрасывается после того, как получен один символ.

Структура kb s необходима для отслеживания введенных кодов опросов клавиатуры. Коды опроса в этой структуре хранятся в циклическом буфере, ibuf, имеющем размер KB IN BYTES. Объявляется массив из таких структур, kb lines[NR CONS], содержащий по одной структуре на консоль, но фактически используется только первый его элемент, так как текущая kb s всегда определяется макросом kbaddr. Тем не менее мы обычно будем ссылаться на kb lines[0] при помощи указателя на эту структзфу, например kb->ihead, ради единства с рассмотрением других устройств. Конечно, неиспользуемые ячейки массива отнимают небольшое количество памяти, но, с другой стороны, если кто-либо выпустит компьютер, поддерживающий несколько клавиатур, ОС MINIX будет готова к такому нововведению, потребуется только изменить макрос kbaddr.

Макрос тар кеуО возвращает ASCII-код, соответствующий данному коду опроса, без учета модификаторов, то есть попадающий в первую колонку карты клавиатуры. Старший брат этого макроса тар кеу выполняет преобразование кода опроса в ASCII-код с учетом всех модификаторов, действующих при вводе символа.

Когда нажимается или отпускается клавиша, вызывается обработчик прерываний клавиатуры, подпрофамма kbd hwjnt. Чтобы узнать от контроллера клавиатуры код опроса, она вызывает scan keyboard. Когда прерывание инициировано отпусканием клавиши, у кода опроса устанавливается старший значащий бит, и в этом случае нажатие игнорируется, если это не одна из клавиш модификаторов. Если же прерывание обусловлено нажатием любой клавиши или отпусканием модификатора, необработанный код опроса помещается в круговой буфер, при наличии в нем свободного места. После этого устанавливается флаг tp-> tty events и вызывается force timeout, чтобы гарантировать, что при следующем сигнале таймера задача часов запустит задачу терминала. В табл. 3.16 представлен пример содержимого кругового буфера для короткой строки, содержащей два символа в верхнем регистре, каждый из которых предваряется кодом опроса, соответствующим нажатию SHIFT, а следом за кодом символа идет код отпускания SHIFT.

Таблица 3.16. Содержимое входного буфера для строки текста, введенной с клавиатуры. Вторая строка таблицы описывает нажатия клавиш. L+, L-, R+ и R-означают соответственно нажатие и отпускание правой и левой клавиши SHIFT. Код отпускания клавиши на 128 больше кода нажатия

170 18

38 38 24 57

54 17 182 24 19

38 32 28

L- е

1 1 0 SP

R+ W R- 0 г

1 d CR



Когда возникает прерывание от часов, задача терминала получит управление и, обнаружив, что у консоли установлен флаг tp->tty events, вызовет специфичную для данного устройства подпрофамму kb read, на которую ссылается поле tp->tty devread структуры tty консоли. Функция kb read извлекает из циклического буфера коды опроса и помещает в свой локальный буфер ASCII-коды. Этот локальный буфер должен быть достаточно емок для того, чтобы вместить ESC-последовательности, генерируемые в ответ на нажатия некоторых клавищ на цифровой клавиатуре. Затем, чтобы поместить символы во входную очередь, вызывается in process. Во избежание клавиатурного прерывания во время умень-щения значения переменной tp->icount, эта операция защищена вызовами lock и unlock. Вызов make bread возвращает ASCII-код в виде целого числа. В этой точке специальные клавищи, например клавищи цифровой клавиатуры и функциональные, имеют коды большие, чем ОхРР. Коды в диапазоне от НОМЕ до INSRT (от 0x101 до ОхЮС, эти константы задаются в include/minix/keymap.h) при помощи массива numpad map преобразуются в трехсимвольные ESC-последовательности, показанные в табл. 3.17. Эти последовательности затем передаются в in process. Большие по величине коды не передаются в in process, среди них ищутся коды, соответствующие комбинациям клавиш ALT-i-LEFT, ALT+RIGHT и от ALT4-F1 до ALT4-F12. Если обнаруживается одна из таких комбинаций, вызывается функция switch console, переключающая виртуальные консоли.

Таблица 3.17. ESC-последовательности, генерируемые для клавиш цифровой клавиатуры. Когда коды опроса преобразуются в ASCII-коды, специальным клавишам присваиваются пceвдoASCII -кoды, большие OxFF

Клавиша

Код опроса

ASCII

ESC-последовательность

Ноте

0x101

ESC [ H

0x103

ESC I A

PgUp

0x107

ESC[V

0x1 OA

ESC[S

Left

0x105

ESC[D

0x109

ESC[G

Right

0x106

ESC I С

0x1 OB

ESC[T

0x102

ESC[Y

Down

0x104

ESC I В

Pg Dn

0x108

ESC[U

0x1 ОС

ESC[@

Функция make break преобразует коды опроса в ASCII и обновляет значение переменных, отслеживающих значения модификаторов. Но перед этим она ищет волшебную комбинацию клавиш CTRL+ALT-i-DEL, которую все пользователи PC знают как универсальный способ решения многих проблем (в MS-DOS). Тем не менее желательно, чтобы система корректно завершила свою работу, поэтому вместо передачи управления подпрофаммам BIOS, процессу init - корню дере-



ва процессов - отправляется сигнал SIGABRT. Ожидается, что init обработает этот сигнал и в нормальном порядке завершит работу системы, прежде чем вернуться в монитор начальной загрузки, из которого можно управлять либо полным перезапуском системы, либо перезагрузкой MINIX. Конечно, было бы неправильно ожидать, что это сработает всегда. Большинство пользователей понимают опасность внезапной перезагрузки и не прибегают к CTRL+ALT+DEL до тех пор, пока не произойдет что-то действительно серьезное, после чего управлять системой будет невозможно. К этому моменту может сложиться ситуация, когда правильно отправить сигнал другому процессу уже невозможно. Именно потому в make break есть статическая переменная CAD count. При большинстве сбоев система обработки прерываний продолжает работать, значит, клавиатурный ввод продолжает поступать, и задача часов остается работоспособной. MINIX учитывает поведение пользователей, которые, когда система не реагирует на нажатия, начинают в сердцах лупцевать по клавишам. Если попытка отправить SIGABRT процессу init провалилась и пользователь обратился к магической комбинации CTRL+ALT+DEL во второй раз, делается прямой вызов wreboot, которая принудительно возвращает управление монитору начальной загрузки.

Основная часть make break устроена не сложно. Б переменную make записывается признак, было ли прерывание вызвано нажатием или отпусканием клавиши, после чего в переменную ch помещается ASCII-код, возвращаемый функцией тар кеу. Далее следует оператор switch, проверяющий значение ch. Рассмотрим два случая: случай обычной клавиши и случай специальной клавиши. Если нажата обычная клавиша, ни одно из условий в switch не будет выполнено, в варианте по умолчанию также ничего не произойдет, поскольку обычные символы принимаются только при нажатии клавиши. Если каким-то образом обычная клавиша была воспринята при отпускании, ее код заменяется значением -1, которое игнорируется вызывающей функцией. Обработка клавиш ALT, CALOCK, NLOCK и SLOCK сложнее, но во всех этих вариантах действия похожи: в переменную записывается либо новое состояние модификатора (если модификатор действует только тогда, когда удерживается клавиша), либо инвертированное старое состояние (для клавиш наподобие Caps Lock).

Нужно рассмотреть еще один вариант, код EXTKEY и переменную esc. Не путайте этот случай с клавишей ESC на клавиатуре, которой соответствует код опроса 0x1В. Код EXTKEY нельзя сгенерировать по отдельности, нажав какую-либо клавишу или их комбинацию. Это префикс расширенных клавиш для клавиатур PC, первый байт двухбайтового кода опроса, означающего, что передаваемый далее код опроса не является частью обычного набора клавиш PC. Во многих случаях профаммное обеспечение интерпретирует обычный и расширенный коды одинаково. Например, это почти всегда так для обычной клавиши / и серой клавиши / на цифровой клавиатуре. В других случаях может потребоваться различать их нажатия. Так, во многих раскладках клавиатур для языков, отличных от английского, левая и правая клавиши ALT интерпретируются по-разному, позволяя вводить три разных символа с одной клавиши. Код опроса у обеих клавиш одинаков и равен 56, но при нажатии правой ALT код опроса предваряется кодом EXTKEY. Когда получен код EXTKEY, устанавливается флаг esc, и в этом слу-



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 [ 100 ] 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.