KeyboardDevice.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright notice, this
  9. * list of conditions and the following disclaimer.
  10. *
  11. * 2. Redistributions in binary form must reproduce the above copyright notice,
  12. * this list of conditions and the following disclaimer in the documentation
  13. * and/or other materials provided with the distribution.
  14. *
  15. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  18. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  19. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  20. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  21. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  22. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  23. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  24. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25. */
  26. #include <AK/Assertions.h>
  27. #include <AK/ByteBuffer.h>
  28. #include <AK/Types.h>
  29. #include <Kernel/Arch/i386/CPU.h>
  30. #include <Kernel/Devices/KeyboardDevice.h>
  31. #include <Kernel/TTY/VirtualConsole.h>
  32. #include <LibBareMetal/IO.h>
  33. //#define KEYBOARD_DEBUG
  34. namespace Kernel {
  35. #define IRQ_KEYBOARD 1
  36. #define I8042_BUFFER 0x60
  37. #define I8042_STATUS 0x64
  38. #define I8042_ACK 0xFA
  39. #define I8042_BUFFER_FULL 0x01
  40. #define I8042_WHICH_BUFFER 0x20
  41. #define I8042_MOUSE_BUFFER 0x20
  42. #define I8042_KEYBOARD_BUFFER 0x00
  43. char* map;
  44. char* shift_map;
  45. char* alt_map;
  46. char* altgr_map;
  47. static const char en_map[0x80] = {
  48. 0,
  49. '\033',
  50. '1',
  51. '2',
  52. '3',
  53. '4',
  54. '5',
  55. '6',
  56. '7',
  57. '8',
  58. '9',
  59. '0',
  60. '-',
  61. '=',
  62. 0x08,
  63. '\t',
  64. 'q',
  65. 'w',
  66. 'e',
  67. 'r',
  68. 't',
  69. 'y',
  70. 'u',
  71. 'i',
  72. 'o',
  73. 'p',
  74. '[',
  75. ']',
  76. '\n',
  77. 0,
  78. 'a',
  79. 's',
  80. 'd',
  81. 'f',
  82. 'g',
  83. 'h',
  84. 'j',
  85. 'k',
  86. 'l',
  87. ';',
  88. '\'',
  89. '`',
  90. 0,
  91. '\\',
  92. 'z',
  93. 'x',
  94. 'c',
  95. 'v',
  96. 'b',
  97. 'n',
  98. 'm',
  99. ',',
  100. '.',
  101. '/',
  102. 0,
  103. '*',
  104. 0,
  105. ' ',
  106. 0,
  107. 0,
  108. //60
  109. 0,
  110. 0,
  111. 0,
  112. 0,
  113. 0,
  114. 0,
  115. 0,
  116. 0,
  117. 0,
  118. 0,
  119. //70
  120. 0,
  121. 0,
  122. 0,
  123. 0,
  124. '-',
  125. 0,
  126. 0,
  127. 0,
  128. '+',
  129. 0,
  130. //80
  131. 0,
  132. 0,
  133. 0,
  134. 0,
  135. 0,
  136. 0,
  137. '\\',
  138. 0,
  139. 0,
  140. 0,
  141. };
  142. static const char en_shift_map[0x80] = {
  143. 0,
  144. '\033',
  145. '!',
  146. '@',
  147. '#',
  148. '$',
  149. '%',
  150. '^',
  151. '&',
  152. '*',
  153. '(',
  154. ')',
  155. '_',
  156. '+',
  157. 0x08,
  158. '\t',
  159. 'Q',
  160. 'W',
  161. 'E',
  162. 'R',
  163. 'T',
  164. 'Y',
  165. 'U',
  166. 'I',
  167. 'O',
  168. 'P',
  169. '{',
  170. '}',
  171. '\n',
  172. 0,
  173. 'A',
  174. 'S',
  175. 'D',
  176. 'F',
  177. 'G',
  178. 'H',
  179. 'J',
  180. 'K',
  181. 'L',
  182. ':',
  183. '"',
  184. '~',
  185. 0,
  186. '|',
  187. 'Z',
  188. 'X',
  189. 'C',
  190. 'V',
  191. 'B',
  192. 'N',
  193. 'M',
  194. '<',
  195. '>',
  196. '?',
  197. 0,
  198. '*',
  199. 0,
  200. ' ',
  201. 0,
  202. 0,
  203. //60
  204. 0,
  205. 0,
  206. 0,
  207. 0,
  208. 0,
  209. 0,
  210. 0,
  211. 0,
  212. 0,
  213. 0,
  214. //70
  215. 0,
  216. 0,
  217. 0,
  218. 0,
  219. '-',
  220. 0,
  221. 0,
  222. 0,
  223. '+',
  224. 0,
  225. //80
  226. 0,
  227. 0,
  228. 0,
  229. 0,
  230. 0,
  231. 0,
  232. '|',
  233. 0,
  234. 0,
  235. 0,
  236. };
  237. static const char numpad_map[13] = { '7', '8', '9', 0, '4', '5', '6', 0, '1', '2', '3', '0', ',' };
  238. static const KeyCode unshifted_key_map[0x80] = {
  239. Key_Invalid,
  240. Key_Escape,
  241. Key_1,
  242. Key_2,
  243. Key_3,
  244. Key_4,
  245. Key_5,
  246. Key_6,
  247. Key_7,
  248. Key_8,
  249. Key_9,
  250. Key_0,
  251. Key_Minus,
  252. Key_Equal,
  253. Key_Backspace,
  254. Key_Tab, //15
  255. Key_Q,
  256. Key_W,
  257. Key_E,
  258. Key_R,
  259. Key_T,
  260. Key_Y,
  261. Key_U,
  262. Key_I,
  263. Key_O,
  264. Key_P,
  265. Key_LeftBracket,
  266. Key_RightBracket,
  267. Key_Return, // 28
  268. Key_Control, // 29
  269. Key_A,
  270. Key_S,
  271. Key_D,
  272. Key_F,
  273. Key_G,
  274. Key_H,
  275. Key_J,
  276. Key_K,
  277. Key_L,
  278. Key_Semicolon,
  279. Key_Apostrophe,
  280. Key_Backtick,
  281. Key_LeftShift, // 42
  282. Key_Backslash,
  283. Key_Z,
  284. Key_X,
  285. Key_C,
  286. Key_V,
  287. Key_B,
  288. Key_N,
  289. Key_M,
  290. Key_Comma,
  291. Key_Period,
  292. Key_Slash,
  293. Key_RightShift, // 54
  294. Key_Asterisk,
  295. Key_Alt, // 56
  296. Key_Space, // 57
  297. Key_CapsLock, // 58
  298. Key_F1,
  299. Key_F2,
  300. Key_F3,
  301. Key_F4,
  302. Key_F5,
  303. Key_F6,
  304. Key_F7,
  305. Key_F8,
  306. Key_F9,
  307. Key_F10,
  308. Key_NumLock,
  309. Key_Invalid, // 70
  310. Key_Home,
  311. Key_Up,
  312. Key_PageUp,
  313. Key_Minus,
  314. Key_Left,
  315. Key_Invalid,
  316. Key_Right, // 77
  317. Key_Plus,
  318. Key_End,
  319. Key_Down, // 80
  320. Key_PageDown,
  321. Key_Invalid,
  322. Key_Delete, // 83
  323. Key_Invalid,
  324. Key_Invalid,
  325. Key_Backslash,
  326. Key_F11,
  327. Key_F12,
  328. Key_Invalid,
  329. Key_Invalid,
  330. Key_Logo,
  331. };
  332. static const KeyCode shifted_key_map[0x100] = {
  333. Key_Invalid,
  334. Key_Escape,
  335. Key_ExclamationPoint,
  336. Key_AtSign,
  337. Key_Hashtag,
  338. Key_Dollar,
  339. Key_Percent,
  340. Key_Circumflex,
  341. Key_Ampersand,
  342. Key_Asterisk,
  343. Key_LeftParen,
  344. Key_RightParen,
  345. Key_Underscore,
  346. Key_Plus,
  347. Key_Backspace,
  348. Key_Tab,
  349. Key_Q,
  350. Key_W,
  351. Key_E,
  352. Key_R,
  353. Key_T,
  354. Key_Y,
  355. Key_U,
  356. Key_I,
  357. Key_O,
  358. Key_P,
  359. Key_LeftBrace,
  360. Key_RightBrace,
  361. Key_Return,
  362. Key_Control,
  363. Key_A,
  364. Key_S,
  365. Key_D,
  366. Key_F,
  367. Key_G,
  368. Key_H,
  369. Key_J,
  370. Key_K,
  371. Key_L,
  372. Key_Colon,
  373. Key_DoubleQuote,
  374. Key_Tilde,
  375. Key_LeftShift, // 42
  376. Key_Pipe,
  377. Key_Z,
  378. Key_X,
  379. Key_C,
  380. Key_V,
  381. Key_B,
  382. Key_N,
  383. Key_M,
  384. Key_LessThan,
  385. Key_GreaterThan,
  386. Key_QuestionMark,
  387. Key_RightShift, // 54
  388. Key_Asterisk,
  389. Key_Alt,
  390. Key_Space, // 57
  391. Key_CapsLock, // 58
  392. Key_F1,
  393. Key_F2,
  394. Key_F3,
  395. Key_F4,
  396. Key_F5,
  397. Key_F6,
  398. Key_F7,
  399. Key_F8,
  400. Key_F9,
  401. Key_F10,
  402. Key_NumLock,
  403. Key_Invalid, // 70
  404. Key_Home,
  405. Key_Up,
  406. Key_PageUp,
  407. Key_Minus,
  408. Key_Left,
  409. Key_Invalid,
  410. Key_Right, // 77
  411. Key_Plus,
  412. Key_End,
  413. Key_Down, // 80
  414. Key_PageDown,
  415. Key_Invalid,
  416. Key_Delete, // 83
  417. Key_Invalid,
  418. Key_Invalid,
  419. Key_Pipe,
  420. Key_F11,
  421. Key_F12,
  422. Key_Invalid,
  423. Key_Invalid,
  424. Key_Logo,
  425. };
  426. static const KeyCode numpad_key_map[13] = { Key_7, Key_8, Key_9, Key_Invalid, Key_4, Key_5, Key_6, Key_Invalid, Key_1, Key_2, Key_3, Key_0, Key_Comma };
  427. void KeyboardDevice::key_state_changed(u8 raw, bool pressed)
  428. {
  429. KeyCode key = (m_modifiers & Mod_Shift) ? shifted_key_map[raw] : unshifted_key_map[raw];
  430. char character = (m_modifiers & Mod_Shift) ? shift_map[raw] : (m_modifiers & Mod_Alt) ? alt_map[raw] : (m_modifiers & Mod_AltGr) ? altgr_map[raw] : map[raw];
  431. if (key == Key_NumLock && pressed)
  432. m_num_lock_on = !m_num_lock_on;
  433. if (m_num_lock_on && !m_has_e0_prefix) {
  434. if (raw >= 0x47 && raw <= 0x53) {
  435. u8 index = raw - 0x47;
  436. KeyCode newKey = numpad_key_map[index];
  437. if (newKey != Key_Invalid) {
  438. key = newKey;
  439. character = numpad_map[index];
  440. }
  441. }
  442. } else {
  443. if (m_has_e0_prefix) {
  444. if (key == Key_Slash) {
  445. character = '/'; // On Turkish-QWERTY Keyboard Key_Slash mapped to '.' char, if e0 prefix is true remap to '/' char
  446. }
  447. }
  448. }
  449. if (key == Key_CapsLock && pressed)
  450. m_caps_lock_on = !m_caps_lock_on;
  451. if (m_caps_lock_on && (m_modifiers == 0 || m_modifiers == Mod_Shift)) {
  452. if (character >= 'a' && character <= 'z')
  453. character &= ~0x20;
  454. else if (character >= 'A' && character <= 'Z')
  455. character |= 0x20;
  456. }
  457. Event event;
  458. event.key = key;
  459. event.character = static_cast<u8>(character);
  460. event.flags = m_modifiers;
  461. if (pressed)
  462. event.flags |= Is_Press;
  463. if (m_client)
  464. m_client->on_key_pressed(event);
  465. m_queue.enqueue(event);
  466. m_has_e0_prefix = false;
  467. }
  468. void KeyboardDevice::handle_irq(const RegisterState&)
  469. {
  470. for (;;) {
  471. u8 status = IO::in8(I8042_STATUS);
  472. if (!(((status & I8042_WHICH_BUFFER) == I8042_KEYBOARD_BUFFER) && (status & I8042_BUFFER_FULL)))
  473. return;
  474. u8 raw = IO::in8(I8042_BUFFER);
  475. u8 ch = raw & 0x7f;
  476. bool pressed = !(raw & 0x80);
  477. if (raw == 0xe0) {
  478. m_has_e0_prefix = true;
  479. return;
  480. }
  481. #ifdef KEYBOARD_DEBUG
  482. dbg() << "Keyboard::handle_irq: " << String::format("%b", ch) << " " << (pressed ? "down" : "up");
  483. #endif
  484. switch (ch) {
  485. case 0x38:
  486. if (m_has_e0_prefix)
  487. update_modifier(Mod_AltGr, pressed);
  488. else
  489. update_modifier(Mod_Alt, pressed);
  490. break;
  491. case 0x1d:
  492. update_modifier(Mod_Ctrl, pressed);
  493. break;
  494. case 0x5b:
  495. update_modifier(Mod_Logo, pressed);
  496. break;
  497. case 0x2a:
  498. case 0x36:
  499. update_modifier(Mod_Shift, pressed);
  500. break;
  501. }
  502. switch (ch) {
  503. case I8042_ACK:
  504. break;
  505. default:
  506. if (m_modifiers & Mod_Alt) {
  507. switch (map[ch]) {
  508. case '1':
  509. case '2':
  510. case '3':
  511. case '4':
  512. VirtualConsole::switch_to(map[ch] - '0' - 1);
  513. break;
  514. default:
  515. key_state_changed(ch, pressed);
  516. break;
  517. }
  518. } else {
  519. key_state_changed(ch, pressed);
  520. }
  521. }
  522. }
  523. }
  524. static KeyboardDevice* s_the;
  525. KeyboardDevice& KeyboardDevice::the()
  526. {
  527. ASSERT(s_the);
  528. return *s_the;
  529. }
  530. KeyboardDevice::KeyboardDevice()
  531. : IRQHandler(IRQ_KEYBOARD)
  532. , CharacterDevice(85, 1)
  533. {
  534. s_the = this;
  535. KeyboardDevice::set_maps(en_map, en_shift_map, en_map, en_map);
  536. // Empty the buffer of any pending data.
  537. // I don't care what you've been pressing until now!
  538. while (IO::in8(I8042_STATUS) & I8042_BUFFER_FULL)
  539. IO::in8(I8042_BUFFER);
  540. enable_irq();
  541. }
  542. KeyboardDevice::~KeyboardDevice()
  543. {
  544. }
  545. bool KeyboardDevice::can_read(const FileDescription&) const
  546. {
  547. return !m_queue.is_empty();
  548. }
  549. ssize_t KeyboardDevice::read(FileDescription&, u8* buffer, ssize_t size)
  550. {
  551. ssize_t nread = 0;
  552. while (nread < size) {
  553. if (m_queue.is_empty())
  554. break;
  555. // Don't return partial data frames.
  556. if ((size - nread) < (ssize_t)sizeof(Event))
  557. break;
  558. auto event = m_queue.dequeue();
  559. memcpy(buffer, &event, sizeof(Event));
  560. nread += sizeof(Event);
  561. }
  562. return nread;
  563. }
  564. ssize_t KeyboardDevice::write(FileDescription&, const u8*, ssize_t)
  565. {
  566. return 0;
  567. }
  568. KeyboardClient::~KeyboardClient()
  569. {
  570. }
  571. void KeyboardDevice::set_maps(const char* n_map, const char* n_shift_map, const char* n_alt_map, const char* n_altgr_map)
  572. {
  573. kfree(map);
  574. kfree(shift_map);
  575. kfree(alt_map);
  576. kfree(altgr_map);
  577. map = (char*)kmalloc(0x80);
  578. shift_map = (char*)kmalloc(0x80);
  579. alt_map = (char*)kmalloc(0x80);
  580. altgr_map = (char*)kmalloc(0x80);
  581. for (int i = 0; i < 0x80; i++) {
  582. map[i] = n_map[i];
  583. shift_map[i] = n_shift_map[i];
  584. alt_map[i] = n_alt_map[i];
  585. altgr_map[i] = n_altgr_map[i];
  586. }
  587. }
  588. }