1 #include "keyboard.h"
2 #include <libc/src/unistd.h>
3 // 功能键标志变量
4 static bool shift_l = 0, shift_r = 0, ctrl_l = 0, ctrl_r = 0, alt_l = 0, alt_r = 0;
5 static bool gui_l = 0, gui_r = 0, apps = 0, insert = 0, home = 0, pgup = 0, del = 0, end = 0, pgdn = 0, arrow_u = 0, arrow_l = 0, arrow_d = 0, arrow_r = 0;
6 static bool kp_forward_slash = 0, kp_en = 0;
7
8 // 键盘扫描码有三种:
9 // 0xE1开头的PauseBreak键
10 // 0xE0开头的功能键
11 // 1byte的普通按键
12
13 // pause break键的扫描码,没错,它就是这么长
14 unsigned char pause_break_scan_code[] = {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5};
15
16 // 第一套键盘扫描码 及其对应的字符
17 uint32_t keycode_map_normal[NUM_SCAN_CODES * MAP_COLS] =
18 {
19 /*scan-code unShift Shift */
20 /*--------------------------------------------------------------*/
21 /*0x00*/ 0,
22 0,
23 /*0x01*/ 0,
24 0, // ESC
25 /*0x02*/ '1',
26 '!',
27 /*0x03*/ '2',
28 '@',
29 /*0x04*/ '3',
30 '#',
31 /*0x05*/ '4',
32 '$',
33 /*0x06*/ '5',
34 '%',
35 /*0x07*/ '6',
36 '^',
37 /*0x08*/ '7',
38 '&',
39 /*0x09*/ '8',
40 '*',
41 /*0x0a*/ '9',
42 '(',
43 /*0x0b*/ '0',
44 ')',
45 /*0x0c*/ '-',
46 '_',
47 /*0x0d*/ '=',
48 '+',
49 /*0x0e*/ '\b',
50 '\b', // BACKSPACE
51 /*0x0f*/ '\t',
52 '\t', // TAB
53
54 /*0x10*/ 'q',
55 'Q',
56 /*0x11*/ 'w',
57 'W',
58 /*0x12*/ 'e',
59 'E',
60 /*0x13*/ 'r',
61 'R',
62 /*0x14*/ 't',
63 'T',
64 /*0x15*/ 'y',
65 'Y',
66 /*0x16*/ 'u',
67 'U',
68 /*0x17*/ 'i',
69 'I',
70 /*0x18*/ 'o',
71 'O',
72 /*0x19*/ 'p',
73 'P',
74 /*0x1a*/ '[',
75 '{',
76 /*0x1b*/ ']',
77 '}',
78 /*0x1c*/ '\n',
79 '\n', // ENTER
80 /*0x1d*/ 0x1d,
81 0x1d, // CTRL Left
82 /*0x1e*/ 'a',
83 'A',
84 /*0x1f*/ 's',
85 'S',
86
87 /*0x20*/ 'd',
88 'D',
89 /*0x21*/ 'f',
90 'F',
91 /*0x22*/ 'g',
92 'G',
93 /*0x23*/ 'h',
94 'H',
95 /*0x24*/ 'j',
96 'J',
97 /*0x25*/ 'k',
98 'K',
99 /*0x26*/ 'l',
100 'L',
101 /*0x27*/ ';',
102 ':',
103 /*0x28*/ '\'',
104 '"',
105 /*0x29*/ '`',
106 '~',
107 /*0x2a*/ 0x2a,
108 0x2a, // SHIFT Left
109 /*0x2b*/ '\\',
110 '|',
111 /*0x2c*/ 'z',
112 'Z',
113 /*0x2d*/ 'x',
114 'X',
115 /*0x2e*/ 'c',
116 'C',
117 /*0x2f*/ 'v',
118 'V',
119
120 /*0x30*/ 'b',
121 'B',
122 /*0x31*/ 'n',
123 'N',
124 /*0x32*/ 'm',
125 'M',
126 /*0x33*/ ',',
127 '<',
128 /*0x34*/ '.',
129 '>',
130 /*0x35*/ '/',
131 '?',
132 /*0x36*/ 0x36,
133 0x36, // SHIFT Right
134 /*0x37*/ '*',
135 '*',
136 /*0x38*/ 0x38,
137 0x38, // ALT Left
138 /*0x39*/ ' ',
139 ' ',
140 /*0x3a*/ 0,
141 0, // CAPS LOCK
142 /*0x3b*/ 0,
143 0, // F1
144 /*0x3c*/ 0,
145 0, // F2
146 /*0x3d*/ 0,
147 0, // F3
148 /*0x3e*/ 0,
149 0, // F4
150 /*0x3f*/ 0,
151 0, // F5
152
153 /*0x40*/ 0,
154 0, // F6
155 /*0x41*/ 0,
156 0, // F7
157 /*0x42*/ 0,
158 0, // F8
159 /*0x43*/ 0,
160 0, // F9
161 /*0x44*/ 0,
162 0, // F10
163 /*0x45*/ 0,
164 0, // NUM LOCK
165 /*0x46*/ 0,
166 0, // SCROLL LOCK
167 /*0x47*/ '7',
168 0, /*PAD HONE*/
169 /*0x48*/ '8',
170 0, /*PAD UP*/
171 /*0x49*/ '9',
172 0, /*PAD PAGEUP*/
173 /*0x4a*/ '-',
174 0, /*PAD MINUS*/
175 /*0x4b*/ '4',
176 0, /*PAD LEFT*/
177 /*0x4c*/ '5',
178 0, /*PAD MID*/
179 /*0x4d*/ '6',
180 0, /*PAD RIGHT*/
181 /*0x4e*/ '+',
182 0, /*PAD PLUS*/
183 /*0x4f*/ '1',
184 0, /*PAD END*/
185
186 /*0x50*/ '2',
187 0, /*PAD DOWN*/
188 /*0x51*/ '3',
189 0, /*PAD PAGEDOWN*/
190 /*0x52*/ '0',
191 0, /*PAD INS*/
192 /*0x53*/ '.',
193 0, /*PAD DOT*/
194 /*0x54*/ 0,
195 0,
196 /*0x55*/ 0,
197 0,
198 /*0x56*/ 0,
199 0,
200 /*0x57*/ 0,
201 0, // F11
202 /*0x58*/ 0,
203 0, // F12
204 /*0x59*/ 0,
205 0,
206 /*0x5a*/ 0,
207 0,
208 /*0x5b*/ 0,
209 0,
210 /*0x5c*/ 0,
211 0,
212 /*0x5d*/ 0,
213 0,
214 /*0x5e*/ 0,
215 0,
216 /*0x5f*/ 0,
217 0,
218
219 /*0x60*/ 0,
220 0,
221 /*0x61*/ 0,
222 0,
223 /*0x62*/ 0,
224 0,
225 /*0x63*/ 0,
226 0,
227 /*0x64*/ 0,
228 0,
229 /*0x65*/ 0,
230 0,
231 /*0x66*/ 0,
232 0,
233 /*0x67*/ 0,
234 0,
235 /*0x68*/ 0,
236 0,
237 /*0x69*/ 0,
238 0,
239 /*0x6a*/ 0,
240 0,
241 /*0x6b*/ 0,
242 0,
243 /*0x6c*/ 0,
244 0,
245 /*0x6d*/ 0,
246 0,
247 /*0x6e*/ 0,
248 0,
249 /*0x6f*/ 0,
250 0,
251
252 /*0x70*/ 0,
253 0,
254 /*0x71*/ 0,
255 0,
256 /*0x72*/ 0,
257 0,
258 /*0x73*/ 0,
259 0,
260 /*0x74*/ 0,
261 0,
262 /*0x75*/ 0,
263 0,
264 /*0x76*/ 0,
265 0,
266 /*0x77*/ 0,
267 0,
268 /*0x78*/ 0,
269 0,
270 /*0x79*/ 0,
271 0,
272 /*0x7a*/ 0,
273 0,
274 /*0x7b*/ 0,
275 0,
276 /*0x7c*/ 0,
277 0,
278 /*0x7d*/ 0,
279 0,
280 /*0x7e*/ 0,
281 0,
282 /*0x7f*/ 0,
283 0,
284 };
285
286 /**
287 * @brief 解析键盘扫描码
288 *
289 */
keyboard_analyze_keycode(int fd)290 int keyboard_analyze_keycode(int fd)
291 {
292 bool flag_make = false;
293
294 int c = keyboard_get_scancode(fd);
295 // 循环队列为空
296 if (c == -1)
297 return 0;
298
299 unsigned char scancode = (unsigned char)c;
300
301 int key = 0;
302 if (scancode == 0xE1) // Pause Break
303 {
304 key = PAUSE_BREAK;
305 // 清除缓冲区中剩下的扫描码
306 for (int i = 1; i < 6; ++i)
307 if (keyboard_get_scancode(fd) != pause_break_scan_code[i])
308 {
309 key = 0;
310 break;
311 }
312 }
313 else if (scancode == 0xE0) // 功能键, 有多个扫描码
314 {
315 // 获取下一个扫描码
316 scancode = keyboard_get_scancode(fd);
317 switch (scancode)
318 {
319 case 0x2a: // print screen 按键被按下
320 if (keyboard_get_scancode(fd) == 0xe0)
321 if (keyboard_get_scancode(fd) == 0x37)
322 {
323 key = PRINT_SCREEN;
324 flag_make = true;
325 }
326 break;
327 case 0xb7: // print screen 按键被松开
328 if (keyboard_get_scancode(fd) == 0xe0)
329 if (keyboard_get_scancode(fd) == 0xaa)
330 {
331 key = PRINT_SCREEN;
332 flag_make = false;
333 }
334 break;
335 case 0x1d: // 按下右边的ctrl
336 ctrl_r = true;
337 key = OTHER_KEY;
338 break;
339 case 0x9d: // 松开右边的ctrl
340 ctrl_r = false;
341 key = OTHER_KEY;
342 break;
343 case 0x38: // 按下右边的alt
344 alt_r = true;
345 key = OTHER_KEY;
346 break;
347 case 0xb8: // 松开右边的alt
348 alt_r = false;
349 key = OTHER_KEY;
350 break;
351 case 0x5b:
352 gui_l = true;
353 key = OTHER_KEY;
354 break;
355 case 0xdb:
356 gui_l = false;
357 key = OTHER_KEY;
358 break;
359 case 0x5c:
360 gui_r = true;
361 key = OTHER_KEY;
362 break;
363 case 0xdc:
364 gui_r = false;
365 key = OTHER_KEY;
366 break;
367 case 0x5d:
368 apps = true;
369 key = OTHER_KEY;
370 break;
371 case 0xdd:
372 apps = false;
373 key = OTHER_KEY;
374 break;
375 case 0x52:
376 insert = true;
377 key = OTHER_KEY;
378 break;
379 case 0xd2:
380 insert = false;
381 key = OTHER_KEY;
382 break;
383 case 0x47:
384 home = true;
385 key = OTHER_KEY;
386 break;
387 case 0xc7:
388 home = false;
389 key = OTHER_KEY;
390 break;
391 case 0x49:
392 pgup = true;
393 key = OTHER_KEY;
394 break;
395 case 0xc9:
396 pgup = false;
397 key = OTHER_KEY;
398 break;
399 case 0x53:
400 del = true;
401 key = OTHER_KEY;
402 break;
403 case 0xd3:
404 del = false;
405 key = OTHER_KEY;
406 break;
407 case 0x4f:
408 end = true;
409 key = OTHER_KEY;
410 break;
411 case 0xcf:
412 end = false;
413 key = OTHER_KEY;
414 break;
415 case 0x51:
416 pgdn = true;
417 key = OTHER_KEY;
418 break;
419 case 0xd1:
420 pgdn = false;
421 key = OTHER_KEY;
422 break;
423 case 0x48:
424 arrow_u = true;
425 key = OTHER_KEY;
426 break;
427 case 0xc8:
428 arrow_u = false;
429 key = OTHER_KEY;
430 return 0xc8;
431 break;
432 case 0x4b:
433 arrow_l = true;
434 key = OTHER_KEY;
435 break;
436 case 0xcb:
437 arrow_l = false;
438 key = OTHER_KEY;
439 break;
440 case 0x50:
441 arrow_d = true;
442 key = OTHER_KEY;
443 return 0x50;
444 break;
445 case 0xd0:
446 arrow_d = false;
447 key = OTHER_KEY;
448 break;
449 case 0x4d:
450 arrow_r = true;
451 key = OTHER_KEY;
452 break;
453 case 0xcd:
454 arrow_r = false;
455 key = OTHER_KEY;
456 break;
457
458 case 0x35: // 数字小键盘的 / 符号
459 kp_forward_slash = true;
460 key = OTHER_KEY;
461 break;
462 case 0xb5:
463 kp_forward_slash = false;
464 key = OTHER_KEY;
465 break;
466 case 0x1c:
467 kp_en = true;
468 key = OTHER_KEY;
469 break;
470 case 0x9c:
471 kp_en = false;
472 key = OTHER_KEY;
473 break;
474
475 default:
476 key = OTHER_KEY;
477 break;
478 }
479 }
480
481 if (key == 0) // 属于第三类扫描码
482 {
483 // 判断按键是被按下还是抬起
484 flag_make = ((scancode & FLAG_BREAK) ? 0 : 1);
485
486 // 计算扫描码位于码表的第几行
487 uint32_t *key_row = &keycode_map_normal[(scancode & 0x7f) * MAP_COLS];
488 unsigned char col = 0;
489 // shift被按下
490 if (shift_l || shift_r)
491 col = 1;
492 key = key_row[col];
493
494 switch (scancode & 0x7f)
495 {
496 case 0x2a:
497 shift_l = flag_make;
498 key = 0;
499 break;
500 case 0x36:
501 shift_r = flag_make;
502 key = 0;
503 break;
504 case 0x1d:
505 ctrl_l = flag_make;
506 key = 0;
507 break;
508 case 0x38:
509 ctrl_r = flag_make;
510 key = 0;
511 break;
512 default:
513 if (!flag_make)
514 key = 0;
515 break;
516 }
517 if (key)
518 return key;
519 }
520 return 0;
521 }
522
523 /**
524 * @brief 从键盘设备文件中获取键盘扫描码
525 *
526 */
keyboard_get_scancode(int fd)527 int keyboard_get_scancode(int fd)
528 {
529 unsigned int ret = 0;
530 read(fd, &ret, 1);
531 return ret;
532 }