KeyboardDevice.cpp 12 KB

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