SayoriOS 0.3.3

keyboard.c
См. документацию.
1
9 extern void tty_backspace();
10
11 #include <lib/string.h>
12 #include <io/ports.h>
13 #include <sys/trigger.h>
14 #include "drv/input/keyboard.h"
15 #include "sys/sync.h"
16 #include "sys/timer.h"
17 #include "io/tty.h"
18 #include "drv/psf.h"
19 #include "sys/isr.h"
20 #include "drv/ps2.h"
21
22 #define KEY_BUFFER_SIZE 16
23 #define KBD_IS_READDATA (1 << 0)
24 #define KBD_IS_WRITEDATA (1 << 1)
25 #define KBD_IS_RESET (1 << 2)
26 #define KBD_IS_CMD (1 << 3)
27 #define KBD_IS_LOCK (1 << 4)
28 #define KBD_IS_MOUSEDATA (1 << 5)
29 #define KBD_IS_TIMEOUT (1 << 6)
30 #define KBD_IS_ODDERROR (1 << 7)
31 #define KBD_CTRL_REG 0x61
32
33 bool SHIFT = false,
34 RU = false;
35 volatile int lastKey = 0;
36 uint8_t kbdstatus = 0;
37 bool echo = true;
38 bool key_ctrl = false;
39 bool key_alt = false;
40
41 volatile char kmode = 0;
42 volatile char* curbuf = 0;
43 volatile uint32_t chartyped = 0;
44
55 char* __getCharKeyboard(char* en_s, char* en_b, char* ru_s, char* ru_b){
56 return (RU?(SHIFT?ru_b:ru_s):(SHIFT?en_b:en_s));
57 }
58
67 char* getCharKeyboard(int key, bool mode){
68 // TODO: Make a layout manager that supports any custom keyboard layout.
69 char* b;// = kmalloc(sizeof(char)*3);
70 bool found = false;
71
72 switch(key) {
73 // case 0: b = "?"; found = false; break;
74 case 0x29: b = __getCharKeyboard("`","~","ё","Ё"); found = true; break;
75 case 0x02: b = __getCharKeyboard("1","!","1","!"); found = true; break;
76 case 0x03: b = __getCharKeyboard("2","@","2","\"");found = true; break;
77 case 0x04: b = __getCharKeyboard("3","#","3","№"); found = true; break;
78 case 0x05: b = __getCharKeyboard("4","$","4",";"); found = true; break;
79 case 0x06: b = __getCharKeyboard("5","%","5","%"); found = true; break;
80 case 0x07: b = __getCharKeyboard("6","^","6",":"); found = true; break;
81 case 0x08: b = __getCharKeyboard("7","&","7","?"); found = true; break;
82 case 0x09: b = __getCharKeyboard("8","*","8","*"); found = true; break;
83 case 0x0A: b = __getCharKeyboard("9","(","9","("); found = true; break;
84 case 0x0B: b = __getCharKeyboard("0",")","0",")"); found = true; break;
85 case 0x0C: b = __getCharKeyboard("-","_","-","_"); found = true; break;
86 case 0x0D: b = __getCharKeyboard("=","+","=","+"); found = true; break;
87
88 case 0x10: b = __getCharKeyboard("q","Q","й","Й"); found = true; break;
89 case 0x11: b = __getCharKeyboard("w","W","ц","Ц"); found = true; break;
90 case 0x12: b = __getCharKeyboard("e","E","у","У"); found = true; break;
91 case 0x13: b = __getCharKeyboard("r","R","к","К"); found = true; break;
92 case 0x14: b = __getCharKeyboard("t","T","е","Е"); found = true; break;
93 case 0x15: b = __getCharKeyboard("y","Y","н","Н"); found = true; break;
94 case 0x16: b = __getCharKeyboard("u","U","г","Г"); found = true; break;
95 case 0x17: b = __getCharKeyboard("i","I","ш","Ш"); found = true; break;
96 case 0x18: b = __getCharKeyboard("o","O","щ","Щ"); found = true; break;
97 case 0x19: b = __getCharKeyboard("p","P","з","З"); found = true; break;
98 case 0x1A: b = __getCharKeyboard("[","{","х","Х"); found = true; break;
99 case 0x1B: b = __getCharKeyboard("]","}","ъ","Ъ"); found = true; break;
100
101 case 0x1E: b = __getCharKeyboard("a","A","ф","Ф"); found = true; break;
102 case 0x1F: b = __getCharKeyboard("s","S","ы","Ы"); found = true; break;
103 case 0x20: b = __getCharKeyboard("d","D","в","В"); found = true; break;
104 case 0x21: b = __getCharKeyboard("f","F","а","А"); found = true; break;
105 case 0x22: b = __getCharKeyboard("g","G","п","П"); found = true; break;
106 case 0x23: b = __getCharKeyboard("h","H","р","Р"); found = true; break;
107 case 0x24: b = __getCharKeyboard("j","J","о","О"); found = true; break;
108 case 0x25: b = __getCharKeyboard("k","K","л","Л"); found = true; break;
109 case 0x26: b = __getCharKeyboard("l","L","д","Д"); found = true; break;
110 case 0x27: b = __getCharKeyboard(";",":","ж","Ж"); found = true; break;
111 case 0x28: b = __getCharKeyboard("'","\"","э","Э");found = true; break;
112 case 0x2B: b = __getCharKeyboard("\\","|","\\","/");found = true; break;
113
114 case 0x2C: b = __getCharKeyboard("z","Z","я","Я"); found = true; break;
115 case 0x2D: b = __getCharKeyboard("x","X","ч","Ч"); found = true; break;
116 case 0x2E: b = __getCharKeyboard("c","C","с","С"); found = true; break;
117 case 0x2F: b = __getCharKeyboard("v","V","м","М"); found = true; break;
118 case 0x30: b = __getCharKeyboard("b","B","и","И"); found = true; break;
119 case 0x31: b = __getCharKeyboard("n","N","т","Т"); found = true; break;
120 case 0x32: b = __getCharKeyboard("m","M","ь","Ь"); found = true; break;
121 case 0x33: b = __getCharKeyboard(",","<,","б","Б"); found = true; break;
122 case 0x34: b = __getCharKeyboard(".",">","ю","Ю"); found = true; break;
123 case 0x35: b = __getCharKeyboard("/","?",".",","); found = true; break;
124
125 // case 0x0E: b = __getCharKeyboard("\b","\b","\b","\b"); found = true; break; // Backspace
126 case 0x0E: b = __getCharKeyboard("","","",""); found = true; break; // Backspace
127 case 0x0F: b = __getCharKeyboard("\t","\t","\t","\t"); found = true; break; // Tab
128 case 0x39: b = __getCharKeyboard(" "," "," "," "); found = true; break; // Space
129 case 0x1C: b = __getCharKeyboard("\n","\n","\n","\n"); found = true; break; // Enter
130
131 case 0xA9: b = __getCharKeyboard("`","~","ё","Ё"); found = true; break;
132 case 0x82: b = __getCharKeyboard("1","!","1","!"); found = true; break;
133 case 0x83: b = __getCharKeyboard("2","@","2","\"");found = true; break;
134 case 0x84: b = __getCharKeyboard("3","#","3","№"); found = true; break;
135 case 0x85: b = __getCharKeyboard("4","$","4",";"); found = true; break;
136 case 0x86: b = __getCharKeyboard("5","%","5","%"); found = true; break;
137 case 0x87: b = __getCharKeyboard("6","^","6",":"); found = true; break;
138 case 0x88: b = __getCharKeyboard("7","&","7","?"); found = true; break;
139 case 0x89: b = __getCharKeyboard("8","*","8","*"); found = true; break;
140 case 0x8A: b = __getCharKeyboard("9","(","9","("); found = true; break;
141 case 0x8B: b = __getCharKeyboard("0",")","0",")"); found = true; break;
142 case 0x8C: b = __getCharKeyboard("-","_","-","_"); found = true; break;
143 case 0x8D: b = __getCharKeyboard("=","+","=","+"); found = true; break;
144
145 case 0x90: b = __getCharKeyboard("q","Q","й","Й"); found = true; break;
146 case 0x91: b = __getCharKeyboard("w","W","ц","Ц"); found = true; break;
147 case 0x92: b = __getCharKeyboard("e","E","у","У"); found = true; break;
148 case 0x93: b = __getCharKeyboard("r","R","к","К"); found = true; break;
149 case 0x94: b = __getCharKeyboard("t","T","е","Е"); found = true; break;
150 case 0x95: b = __getCharKeyboard("y","Y","н","Н"); found = true; break;
151 case 0x96: b = __getCharKeyboard("u","U","г","Г"); found = true; break;
152 case 0x97: b = __getCharKeyboard("i","I","ш","Ш"); found = true; break;
153 case 0x98: b = __getCharKeyboard("o","O","щ","Щ"); found = true; break;
154 case 0x99: b = __getCharKeyboard("p","P","з","З"); found = true; break;
155 case 0x9A: b = __getCharKeyboard("[","{","х","Х"); found = true; break;
156 case 0x9B: b = __getCharKeyboard("]","}","ъ","Ъ"); found = true; break;
157
158 case 0x9E: b = __getCharKeyboard("a","A","ф","Ф"); found = true; break;
159 case 0x9F: b = __getCharKeyboard("s","S","ы","Ы"); found = true; break;
160 case 0xA0: b = __getCharKeyboard("d","D","в","В"); found = true; break;
161 case 0xA1: b = __getCharKeyboard("f","F","а","А"); found = true; break;
162 case 0xA2: b = __getCharKeyboard("g","G","п","П"); found = true; break;
163 case 0xA3: b = __getCharKeyboard("h","H","р","Р"); found = true; break;
164 case 0xA4: b = __getCharKeyboard("j","J","о","О"); found = true; break;
165 case 0xA5: b = __getCharKeyboard("k","K","л","Л"); found = true; break;
166 case 0xA6: b = __getCharKeyboard("l","L","д","Д"); found = true; break;
167 case 0xA7: b = __getCharKeyboard(";",":","ж","Ж"); found = true; break;
168 case 0xA8: b = __getCharKeyboard("'","\"","э","Э");found = true; break;
169 case 0xAB: b = __getCharKeyboard("\\","|","\\","/");found = true; break;
170
171 case 0xAC: b = __getCharKeyboard("z","Z","я","Я"); found = true; break;
172 case 0xAD: b = __getCharKeyboard("x","X","ч","Ч"); found = true; break;
173 case 0xAE: b = __getCharKeyboard("c","C","с","С"); found = true; break;
174 case 0xAF: b = __getCharKeyboard("v","V","м","М"); found = true; break;
175 case 0xB0: b = __getCharKeyboard("b","B","и","И"); found = true; break;
176 case 0xB1: b = __getCharKeyboard("n","N","т","Т"); found = true; break;
177 case 0xB2: b = __getCharKeyboard("m","M","ь","Ь"); found = true; break;
178 case 0xB3: b = __getCharKeyboard(",","<,","б","Б"); found = true; break;
179 case 0xB4: b = __getCharKeyboard(".",">","ю","Ю"); found = true; break;
180 case 0xB5: b = __getCharKeyboard("/","?",".",","); found = true; break;
181
182 case 0xB9: b = __getCharKeyboard(" "," "," "," "); found = true; break; // Space
183
184 default: b = "?"; found = false; break;
185 }
186
187 return mode?(char*)key:(found?b:0);
188 }
189
190 uint8_t getPressReleaseKeyboard() {
191 return lastKey & 0x80; // if true -> Released / else - Pressed
192 }
193
194 void keyboardctl(uint8_t param, bool value) {
195 if(param == KEYBOARD_ECHO) {
196 echo = value;
197 }
198 }
199
200 int getCharRaw() {
201 return lastKey;
202 }
203
204 bool is_lctrl_key() {
205 return key_ctrl;
206 }
207
208 int getIntKeyboardWait(){
209 bool kmutex = false;
210 mutex_get(&kmutex, true);
211
212 while(lastKey==0 || (lastKey & 0x80)) {}
213
214 mutex_release(&kmutex);
215 return lastKey;
216 }
217
218 void* getCharKeyboardWait(bool ints) {
219 kmode = 2;
220 while(kmode==2) {
221 if (lastKey != 0 && !(lastKey & 0x80)) {
222 kmode = 0;
223 lastKey = 0;
224 }
225 }
226
227 if(ints) {
228 return curbuf;
229 } else {
230 return getCharKeyboard((int)curbuf, ints);
231 }
232 }
233
234 void kbd_add_char(char *buf, char* key) {
235 if(kmode == 1 && curbuf != 0) {
236 if (!(lastKey == 0x1C || lastKey == 0x0E)) {
237 strcat(buf, key);
238 chartyped++;
239 }
240
241 if(lastKey == 0x0E) { // BACKSPACE
242 if(chartyped > 0) {
243 tty_backspace();
244 chartyped--;
245 buf[chartyped] = 0;
246 }
247 }
248 } else if(kmode == 2) {
249 curbuf = key;
250 }
251 }
252
253 void gets(char *buffer) { // TODO: Backspace
254 // qemu_log("KMODE is: %d, curbuf at: %x", kmode, (int)((void*)curbuf));
255
256 kmode = 1;
257 curbuf = buffer;
258
259 while(kmode == 1) {
260 if (lastKey == 0x9C) { // Enter key pressed
261 curbuf = 0;
262 lastKey = 0;
263 kmode = 0;
264 chartyped = 0;
265 }
266 }
267 }
268
269 // Limited version of gets.
270 // Returns 0 if okay, returns 1 if you typed more than `length` keys.
271 int gets_max(char *buffer, int length) { // TODO: Backspace
272 kmode = 1;
273 curbuf = buffer;
274
275 while(kmode == 1) {
276 if(chartyped >= length) {
277 curbuf = 0;
278 lastKey = 0;
279 kmode = 0;
280 chartyped = 0;
281 return 1;
282 }
283
284 if (lastKey == 0x9C) { // Enter key pressed
285 curbuf = 0;
286 lastKey = 0;
287 kmode = 0;
288 chartyped = 0;
289 }
290 }
291
292 return 0;
293 }
294
298 void keyboardHandler(registers_t regs){
299 kbdstatus = inb(PS2_STATE_REG);
300
301 if (kbdstatus & 0x01) {
302 lastKey = inb(PS2_DATA_PORT);
303 int cl = 1;
304
305 CallTrigger(
306 0x0001,
307 (void*)(lastKey % 0x80),
308 (void*)!getPressReleaseKeyboard(),
309 0,
310 0,
311 &cl
312 );
313
314 //qemu_log("[N-CL] %x | %d",cl,cl);
315 if (cl == 0)
316 return;
317
318 if (lastKey == 42) { // SHIFT press
319 SHIFT = true;
320 return;
321 } else if (lastKey == 0x3B){ // F1
322 RU = !RU;
323 return;
324 } else if (lastKey == 170) { // Shift release
325 SHIFT = false;
326 } else if (lastKey == 29) { // Left Ctrl press
327 key_ctrl = true;
328 } else if (lastKey == 157) { // Left Ctrl release
329 key_ctrl = false;
330 } else if (lastKey == 0x38) { // Left Alt press
331 key_alt = true;
332 } else if (lastKey == 0xb8) { // Left Alt release
333 key_alt = false;
334 }
335
336 char* key = getCharKeyboard(lastKey, false);
337 if (key != 0 && lastKey < 128){
338 if(echo) {
339 if(!key_ctrl && lastKey != 0x0E)
340 tty_printf("%s", key);
341 }
342 kbd_add_char(curbuf, key);
343 }
344 }
345 }
346
350 void keyboardInit() {
351 uint8_t stat;
352
353 ps2_in_wait_until_empty();
354
355 outb(PS2_DATA_PORT, 0xf4);
356 stat = ps2_read();
357
358 if(stat != 0xfa) {
359 qemu_err("Keyboard error: Enable fail");
360 return;
361 }
362
363 ps2_in_wait_until_empty();
364
365 outb(PS2_DATA_PORT, 0xf0);
366 stat = ps2_read();
367
368 if(stat != 0xfa) {
369 qemu_err("Keyboard error: Scancode set fail");
370 return;
371 }
372
373 ps2_in_wait_until_empty();
374
375 outb(PS2_DATA_PORT, 0);
376 stat = ps2_read();
377
378 if(stat != 0xfa) {
379 qemu_err("Keyboard error: Zero fail");
380 return;
381 }
382
383 size_t scancode = ps2_read() & 0b11;
384
385 qemu_note("SCANCODE SET: %d", scancode);
386
387 ps2_in_wait_until_empty();
388
389 outb(PS2_DATA_PORT, 0xf3);
390 stat = ps2_read();
391
392 if(stat != 0xfa) {
393 qemu_err("Keyboard error: Repeat fail");
394 return;
395 }
396
397 ps2_in_wait_until_empty();
398
399 outb(PS2_DATA_PORT, 0);
400 stat = ps2_read();
401
402 if(stat != 0xfa) {
403 qemu_err("Keyboard error: Zero fail (phase 2)");
404 return;
405 }
406
407 uint8_t conf = ps2_read_configuration_byte();
408
409 qemu_log("%d%d%d%d%d%d%d%d", (conf >> 0) & 1, (conf >> 1) & 1, (conf >> 2) & 1, (conf >> 3) & 1, (conf >> 4) & 1, (conf >> 5) & 1, (conf >> 6) & 1, (conf >> 7) & 1);
410
411 ps2_write_configuration_byte(conf | 0b1000001);
412 }
413
414 void ps2_keyboard_install_irq() {
415 // Register interrupts
416 register_interrupt_handler(IRQ1, &keyboardHandler);
417 qemu_log("Keyboard installed");
418 }
mode
uint32_t mode
Режим работы (0 - Обычный | 1 - Режим логирования)
Definition: bootscreen.c:23
keyboardHandler
void keyboardHandler(registers_t regs)
Обработчик клавиатуры
Definition: keyboard.c:298
getCharKeyboard
char * getCharKeyboard(int key, bool mode)
Выводит символ, в зависимости от кода полученного с клавиатуры
Definition: keyboard.c:67
kbdstatus
uint8_t kbdstatus
Статус клавиатуры
Definition: keyboard.c:36
SHIFT
bool SHIFT
Включен ли SHIFT.
Definition: keyboard.c:33
echo
bool echo
Включен ли вывод?
Definition: keyboard.c:37
__getCharKeyboard
char * __getCharKeyboard(char *en_s, char *en_b, char *ru_s, char *ru_b)
Выводит правильный символ, в зависимости от языка и шифта
Definition: keyboard.c:55
keyboardInit
void keyboardInit()
Выполняет инициализацию клавиатуры
Definition: keyboard.c:350
tty_backspace
void tty_backspace()
Удаление последнего символа
Definition: tty.c:225
lastKey
volatile int lastKey
Последний индекс клавишы
Definition: keyboard.c:35
RU
bool RU
Печатаем русскими?
Definition: keyboard.c:34
strcat
char * strcat(char *destination, const char *source)
Объединение строк
Definition: string.c:463
registers
Definition: common.h:59
mutex_get
bool mutex_get(mutex_t *mutex, bool wait)
Получить мьютекс
Definition: sync.c:19
mutex_release
void mutex_release(mutex_t *mutex)
Получить ближайщий свободный блок
Definition: sync.c:36
CallTrigger
void CallTrigger(int type, void *data1, void *data2, void *data3, void *data4, void *data5)
Функция для вызовов триггеров (Если самостоятельно надо вызвать триггер)
Definition: trigger.c:93