123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533 |
- #include "keyboard.h"
- #include <unistd.h>
- // 功能键标志变量
- static bool shift_l = 0, shift_r = 0, ctrl_l = 0, ctrl_r = 0, alt_l = 0, alt_r = 0;
- 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;
- static bool kp_forward_slash = 0, kp_en = 0;
- // 键盘扫描码有三种:
- // 0xE1开头的PauseBreak键
- // 0xE0开头的功能键
- // 1byte的普通按键
- // pause break键的扫描码,没错,它就是这么长
- unsigned char pause_break_scan_code[] = {0xe1, 0x1d, 0x45, 0xe1, 0x9d, 0xc5};
- // 第一套键盘扫描码 及其对应的字符
- uint32_t keycode_map_normal[NUM_SCAN_CODES * MAP_COLS] =
- {
- /*scan-code unShift Shift */
- /*--------------------------------------------------------------*/
- /*0x00*/ 0,
- 0,
- /*0x01*/ 0,
- 0, // ESC
- /*0x02*/ '1',
- '!',
- /*0x03*/ '2',
- '@',
- /*0x04*/ '3',
- '#',
- /*0x05*/ '4',
- '$',
- /*0x06*/ '5',
- '%',
- /*0x07*/ '6',
- '^',
- /*0x08*/ '7',
- '&',
- /*0x09*/ '8',
- '*',
- /*0x0a*/ '9',
- '(',
- /*0x0b*/ '0',
- ')',
- /*0x0c*/ '-',
- '_',
- /*0x0d*/ '=',
- '+',
- /*0x0e*/ '\b',
- '\b', // BACKSPACE
- /*0x0f*/ '\t',
- '\t', // TAB
- /*0x10*/ 'q',
- 'Q',
- /*0x11*/ 'w',
- 'W',
- /*0x12*/ 'e',
- 'E',
- /*0x13*/ 'r',
- 'R',
- /*0x14*/ 't',
- 'T',
- /*0x15*/ 'y',
- 'Y',
- /*0x16*/ 'u',
- 'U',
- /*0x17*/ 'i',
- 'I',
- /*0x18*/ 'o',
- 'O',
- /*0x19*/ 'p',
- 'P',
- /*0x1a*/ '[',
- '{',
- /*0x1b*/ ']',
- '}',
- /*0x1c*/ '\n',
- '\n', // ENTER
- /*0x1d*/ 0x1d,
- 0x1d, // CTRL Left
- /*0x1e*/ 'a',
- 'A',
- /*0x1f*/ 's',
- 'S',
- /*0x20*/ 'd',
- 'D',
- /*0x21*/ 'f',
- 'F',
- /*0x22*/ 'g',
- 'G',
- /*0x23*/ 'h',
- 'H',
- /*0x24*/ 'j',
- 'J',
- /*0x25*/ 'k',
- 'K',
- /*0x26*/ 'l',
- 'L',
- /*0x27*/ ';',
- ':',
- /*0x28*/ '\'',
- '"',
- /*0x29*/ '`',
- '~',
- /*0x2a*/ 0x2a,
- 0x2a, // SHIFT Left
- /*0x2b*/ '\\',
- '|',
- /*0x2c*/ 'z',
- 'Z',
- /*0x2d*/ 'x',
- 'X',
- /*0x2e*/ 'c',
- 'C',
- /*0x2f*/ 'v',
- 'V',
- /*0x30*/ 'b',
- 'B',
- /*0x31*/ 'n',
- 'N',
- /*0x32*/ 'm',
- 'M',
- /*0x33*/ ',',
- '<',
- /*0x34*/ '.',
- '>',
- /*0x35*/ '/',
- '?',
- /*0x36*/ 0x36,
- 0x36, // SHIFT Right
- /*0x37*/ '*',
- '*',
- /*0x38*/ 0x38,
- 0x38, // ALT Left
- /*0x39*/ ' ',
- ' ',
- /*0x3a*/ 0,
- 0, // CAPS LOCK
- /*0x3b*/ 0,
- 0, // F1
- /*0x3c*/ 0,
- 0, // F2
- /*0x3d*/ 0,
- 0, // F3
- /*0x3e*/ 0,
- 0, // F4
- /*0x3f*/ 0,
- 0, // F5
- /*0x40*/ 0,
- 0, // F6
- /*0x41*/ 0,
- 0, // F7
- /*0x42*/ 0,
- 0, // F8
- /*0x43*/ 0,
- 0, // F9
- /*0x44*/ 0,
- 0, // F10
- /*0x45*/ 0,
- 0, // NUM LOCK
- /*0x46*/ 0,
- 0, // SCROLL LOCK
- /*0x47*/ '7',
- 0, /*PAD HONE*/
- /*0x48*/ '8',
- 0, /*PAD UP*/
- /*0x49*/ '9',
- 0, /*PAD PAGEUP*/
- /*0x4a*/ '-',
- 0, /*PAD MINUS*/
- /*0x4b*/ '4',
- 0, /*PAD LEFT*/
- /*0x4c*/ '5',
- 0, /*PAD MID*/
- /*0x4d*/ '6',
- 0, /*PAD RIGHT*/
- /*0x4e*/ '+',
- 0, /*PAD PLUS*/
- /*0x4f*/ '1',
- 0, /*PAD END*/
- /*0x50*/ '2',
- 0, /*PAD DOWN*/
- /*0x51*/ '3',
- 0, /*PAD PAGEDOWN*/
- /*0x52*/ '0',
- 0, /*PAD INS*/
- /*0x53*/ '.',
- 0, /*PAD DOT*/
- /*0x54*/ 0,
- 0,
- /*0x55*/ 0,
- 0,
- /*0x56*/ 0,
- 0,
- /*0x57*/ 0,
- 0, // F11
- /*0x58*/ 0,
- 0, // F12
- /*0x59*/ 0,
- 0,
- /*0x5a*/ 0,
- 0,
- /*0x5b*/ 0,
- 0,
- /*0x5c*/ 0,
- 0,
- /*0x5d*/ 0,
- 0,
- /*0x5e*/ 0,
- 0,
- /*0x5f*/ 0,
- 0,
- /*0x60*/ 0,
- 0,
- /*0x61*/ 0,
- 0,
- /*0x62*/ 0,
- 0,
- /*0x63*/ 0,
- 0,
- /*0x64*/ 0,
- 0,
- /*0x65*/ 0,
- 0,
- /*0x66*/ 0,
- 0,
- /*0x67*/ 0,
- 0,
- /*0x68*/ 0,
- 0,
- /*0x69*/ 0,
- 0,
- /*0x6a*/ 0,
- 0,
- /*0x6b*/ 0,
- 0,
- /*0x6c*/ 0,
- 0,
- /*0x6d*/ 0,
- 0,
- /*0x6e*/ 0,
- 0,
- /*0x6f*/ 0,
- 0,
- /*0x70*/ 0,
- 0,
- /*0x71*/ 0,
- 0,
- /*0x72*/ 0,
- 0,
- /*0x73*/ 0,
- 0,
- /*0x74*/ 0,
- 0,
- /*0x75*/ 0,
- 0,
- /*0x76*/ 0,
- 0,
- /*0x77*/ 0,
- 0,
- /*0x78*/ 0,
- 0,
- /*0x79*/ 0,
- 0,
- /*0x7a*/ 0,
- 0,
- /*0x7b*/ 0,
- 0,
- /*0x7c*/ 0,
- 0,
- /*0x7d*/ 0,
- 0,
- /*0x7e*/ 0,
- 0,
- /*0x7f*/ 0,
- 0,
- };
- /**
- * @brief 解析键盘扫描码
- *
- */
- int keyboard_analyze_keycode(int fd)
- {
- bool flag_make = false;
- int c = keyboard_get_scancode(fd);
- // 循环队列为空
- if (c == -1)
- return 0;
- unsigned char scancode = (unsigned char)c;
- int key = 0;
- if (scancode == 0xE1) // Pause Break
- {
- key = PAUSE_BREAK;
- // 清除缓冲区中剩下的扫描码
- for (int i = 1; i < 6; ++i)
- if (keyboard_get_scancode(fd) != pause_break_scan_code[i])
- {
- key = 0;
- break;
- }
- }
- else if (scancode == 0xE0) // 功能键, 有多个扫描码
- {
- // 获取下一个扫描码
- scancode = keyboard_get_scancode(fd);
- switch (scancode)
- {
- case 0x2a: // print screen 按键被按下
- if (keyboard_get_scancode(fd) == 0xe0)
- if (keyboard_get_scancode(fd) == 0x37)
- {
- key = PRINT_SCREEN;
- flag_make = true;
- }
- break;
- case 0xb7: // print screen 按键被松开
- if (keyboard_get_scancode(fd) == 0xe0)
- if (keyboard_get_scancode(fd) == 0xaa)
- {
- key = PRINT_SCREEN;
- flag_make = false;
- }
- break;
- case 0x1d: // 按下右边的ctrl
- ctrl_r = true;
- key = OTHER_KEY;
- break;
- case 0x9d: // 松开右边的ctrl
- ctrl_r = false;
- key = OTHER_KEY;
- break;
- case 0x38: // 按下右边的alt
- alt_r = true;
- key = OTHER_KEY;
- break;
- case 0xb8: // 松开右边的alt
- alt_r = false;
- key = OTHER_KEY;
- break;
- case 0x5b:
- gui_l = true;
- key = OTHER_KEY;
- break;
- case 0xdb:
- gui_l = false;
- key = OTHER_KEY;
- break;
- case 0x5c:
- gui_r = true;
- key = OTHER_KEY;
- break;
- case 0xdc:
- gui_r = false;
- key = OTHER_KEY;
- break;
- case 0x5d:
- apps = true;
- key = OTHER_KEY;
- break;
- case 0xdd:
- apps = false;
- key = OTHER_KEY;
- break;
- case 0x52:
- insert = true;
- key = OTHER_KEY;
- break;
- case 0xd2:
- insert = false;
- key = OTHER_KEY;
- break;
- case 0x47:
- home = true;
- key = OTHER_KEY;
- break;
- case 0xc7:
- home = false;
- key = OTHER_KEY;
- break;
- case 0x49:
- pgup = true;
- key = OTHER_KEY;
- break;
- case 0xc9:
- pgup = false;
- key = OTHER_KEY;
- break;
- case 0x53:
- del = true;
- key = OTHER_KEY;
- break;
- case 0xd3:
- del = false;
- key = OTHER_KEY;
- break;
- case 0x4f:
- end = true;
- key = OTHER_KEY;
- break;
- case 0xcf:
- end = false;
- key = OTHER_KEY;
- break;
- case 0x51:
- pgdn = true;
- key = OTHER_KEY;
- break;
- case 0xd1:
- pgdn = false;
- key = OTHER_KEY;
- break;
- case 0x48:
- arrow_u = true;
- key = OTHER_KEY;
- break;
- case 0xc8:
- arrow_u = false;
- key = OTHER_KEY;
- return 0xc8;
- break;
- case 0x4b:
- arrow_l = true;
- key = OTHER_KEY;
- break;
- case 0xcb:
- arrow_l = false;
- key = OTHER_KEY;
- break;
- case 0x50:
- arrow_d = true;
- key = OTHER_KEY;
- return 0x50;
- break;
- case 0xd0:
- arrow_d = false;
- key = OTHER_KEY;
- break;
- case 0x4d:
- arrow_r = true;
- key = OTHER_KEY;
- break;
- case 0xcd:
- arrow_r = false;
- key = OTHER_KEY;
- break;
- case 0x35: // 数字小键盘的 / 符号
- kp_forward_slash = true;
- key = OTHER_KEY;
- break;
- case 0xb5:
- kp_forward_slash = false;
- key = OTHER_KEY;
- break;
- case 0x1c:
- kp_en = true;
- key = OTHER_KEY;
- break;
- case 0x9c:
- kp_en = false;
- key = OTHER_KEY;
- break;
- default:
- key = OTHER_KEY;
- break;
- }
- }
- if (key == 0) // 属于第三类扫描码
- {
- // 判断按键是被按下还是抬起
- flag_make = ((scancode & FLAG_BREAK) ? 0 : 1);
- // 计算扫描码位于码表的第几行
- uint32_t *key_row = &keycode_map_normal[(scancode & 0x7f) * MAP_COLS];
- unsigned char col = 0;
- // shift被按下
- if (shift_l || shift_r)
- col = 1;
- key = key_row[col];
- switch (scancode & 0x7f)
- {
- case 0x2a:
- shift_l = flag_make;
- key = 0;
- break;
- case 0x36:
- shift_r = flag_make;
- key = 0;
- break;
- case 0x1d:
- ctrl_l = flag_make;
- key = 0;
- break;
- case 0x38:
- ctrl_r = flag_make;
- key = 0;
- break;
- default:
- if (!flag_make)
- key = 0;
- break;
- }
- if (key)
- return key;
- }
- return 0;
- }
- /**
- * @brief 从键盘设备文件中获取键盘扫描码
- *
- */
- int keyboard_get_scancode(int fd)
- {
- unsigned int ret = 0;
- read(fd, &ret, 1);
- return ret;
- }
|