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