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 }