keyboard.c 11 KB

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