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 
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 }
uint32_t mode
Режим работы (0 - Обычный | 1 - Режим логирования)
Definition: bootscreen.c:23
void keyboardHandler(registers_t regs)
Обработчик клавиатуры
Definition: keyboard.c:298
char * getCharKeyboard(int key, bool mode)
Выводит символ, в зависимости от кода полученного с клавиатуры
Definition: keyboard.c:67
uint8_t kbdstatus
Статус клавиатуры
Definition: keyboard.c:36
bool SHIFT
Включен ли SHIFT.
Definition: keyboard.c:33
bool echo
Включен ли вывод?
Definition: keyboard.c:37
char * __getCharKeyboard(char *en_s, char *en_b, char *ru_s, char *ru_b)
Выводит правильный символ, в зависимости от языка и шифта
Definition: keyboard.c:55
void keyboardInit()
Выполняет инициализацию клавиатуры
Definition: keyboard.c:350
void tty_backspace()
Удаление последнего символа
Definition: tty.c:225
volatile int lastKey
Последний индекс клавишы
Definition: keyboard.c:35
bool RU
Печатаем русскими?
Definition: keyboard.c:34
char * strcat(char *destination, const char *source)
Объединение строк
Definition: string.c:463
bool mutex_get(mutex_t *mutex, bool wait)
Получить мьютекс
Definition: sync.c:19
void mutex_release(mutex_t *mutex)
Получить ближайщий свободный блок
Definition: sync.c:36
void CallTrigger(int type, void *data1, void *data2, void *data3, void *data4, void *data5)
Функция для вызовов триггеров (Если самостоятельно надо вызвать триггер)
Definition: trigger.c:93