scancode.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. /*++
  2. Copyright (c) 2012 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. scancode.c
  9. Abstract:
  10. This module impelements support for converting between scancodes used
  11. in keyboards to OS key abstractions.
  12. Author:
  13. Evan Green 21-Dec-2012
  14. Environment:
  15. Kernel
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include <minoca/kernel/driver.h>
  21. #include "i8042.h"
  22. //
  23. // ---------------------------------------------------------------- Definitions
  24. //
  25. #define MAX_SCAN_CODE_1 0x7F
  26. #define SCAN_CODE_1_KEY_UP 0x80
  27. #define SCAN_CODE_1_EXTENDED_KEY_COUNT 41
  28. #define SCAN_CODE_1_EXTENDED_2_KEY_COUNT 1
  29. //
  30. // ------------------------------------------------------ Data Type Definitions
  31. //
  32. typedef struct _EXTENDED_KEY_DESCRIPTION {
  33. UCHAR ScanCode;
  34. KEYBOARD_KEY Key;
  35. } EXTENDED_KEY_DESCRIPTION, *PEXTENDED_KEY_DESCRIPTION;
  36. typedef struct _EXTENDED_2_KEY_DESCRIPTION {
  37. UCHAR ScanCode1;
  38. UCHAR ScanCode2;
  39. KEYBOARD_KEY Key;
  40. } EXTENDED_2_KEY_DESCRIPTION, *PEXTENDED_2_KEY_DESCRIPTION;
  41. //
  42. // ----------------------------------------------- Internal Function Prototypes
  43. //
  44. //
  45. // -------------------------------------------------------------------- Globals
  46. //
  47. KEYBOARD_KEY I8042ScanCodeSet1KeyTable[MAX_SCAN_CODE_1] = {
  48. KeyboardKeyInvalid, /* 00 */
  49. KeyboardKeyEscape,
  50. KeyboardKey1,
  51. KeyboardKey2,
  52. KeyboardKey3,
  53. KeyboardKey4,
  54. KeyboardKey5,
  55. KeyboardKey6,
  56. KeyboardKey7,
  57. KeyboardKey8,
  58. KeyboardKey9,
  59. KeyboardKey0,
  60. KeyboardKeyDash,
  61. KeyboardKeyEquals,
  62. KeyboardKeyBackspace,
  63. KeyboardKeyTab,
  64. KeyboardKeyQ, /* 10 */
  65. KeyboardKeyW,
  66. KeyboardKeyE,
  67. KeyboardKeyR,
  68. KeyboardKeyT,
  69. KeyboardKeyY,
  70. KeyboardKeyU,
  71. KeyboardKeyI,
  72. KeyboardKeyO,
  73. KeyboardKeyP,
  74. KeyboardKeyLeftBracket,
  75. KeyboardKeyRightBracket,
  76. KeyboardKeyEnter,
  77. KeyboardKeyLeftControl,
  78. KeyboardKeyA,
  79. KeyboardKeyS,
  80. KeyboardKeyD, /* 20 */
  81. KeyboardKeyF,
  82. KeyboardKeyG,
  83. KeyboardKeyH,
  84. KeyboardKeyJ,
  85. KeyboardKeyK,
  86. KeyboardKeyL,
  87. KeyboardKeySemicolon,
  88. KeyboardKeyApostrophe,
  89. KeyboardKeyTilde,
  90. KeyboardKeyLeftShift,
  91. KeyboardKeyBackslash,
  92. KeyboardKeyZ,
  93. KeyboardKeyX,
  94. KeyboardKeyC,
  95. KeyboardKeyV,
  96. KeyboardKeyB, /* 30 */
  97. KeyboardKeyN,
  98. KeyboardKeyM,
  99. KeyboardKeyComma,
  100. KeyboardKeyPeriod,
  101. KeyboardKeySlash,
  102. KeyboardKeyRightShift,
  103. KeyboardKeyKeypadAsterisk,
  104. KeyboardKeyLeftAlt,
  105. KeyboardKeySpace,
  106. KeyboardKeyCapsLock,
  107. KeyboardKeyF1,
  108. KeyboardKeyF2,
  109. KeyboardKeyF3,
  110. KeyboardKeyF4,
  111. KeyboardKeyF5,
  112. KeyboardKeyF6, /* 40 */
  113. KeyboardKeyF7,
  114. KeyboardKeyF8,
  115. KeyboardKeyF9,
  116. KeyboardKeyF10,
  117. KeyboardKeyNumLock,
  118. KeyboardKeyScrollLock,
  119. KeyboardKeyKeypad7,
  120. KeyboardKeyKeypad8,
  121. KeyboardKeyKeypad9,
  122. KeyboardKeyKeypadMinus,
  123. KeyboardKeyKeypad4,
  124. KeyboardKeyKeypad5,
  125. KeyboardKeyKeypad6,
  126. KeyboardKeyKeypadPlus,
  127. KeyboardKeyKeypad1,
  128. KeyboardKeyKeypad2, /* 50 */
  129. KeyboardKeyKeypad3,
  130. KeyboardKeyKeypad0,
  131. KeyboardKeyKeypadPeriod,
  132. KeyboardKeySysRq,
  133. KeyboardKeyInvalid,
  134. KeyboardKeyInternational1,
  135. KeyboardKeyF11,
  136. KeyboardKeyF12,
  137. KeyboardKeyInvalid,
  138. KeyboardKeyInvalid,
  139. KeyboardKeyF13,
  140. KeyboardKeyF14,
  141. KeyboardKeyF15,
  142. KeyboardKeyInvalid,
  143. KeyboardKeyInvalid,
  144. KeyboardKeyInvalid, /* 60 */
  145. KeyboardKeyInvalid,
  146. KeyboardKeyInvalid,
  147. KeyboardKeyF16,
  148. KeyboardKeyF17,
  149. KeyboardKeyF18,
  150. KeyboardKeyF19,
  151. KeyboardKeyF20,
  152. KeyboardKeyF21,
  153. KeyboardKeyF22,
  154. KeyboardKeyF23,
  155. KeyboardKeyF24,
  156. KeyboardKeyInvalid,
  157. KeyboardKeyInvalid,
  158. KeyboardKeyInvalid,
  159. KeyboardKeyInvalid,
  160. KeyboardKeyKatakana, /* 70 */
  161. KeyboardKeyInvalid,
  162. KeyboardKeyInvalid,
  163. KeyboardKeyInternational3,
  164. KeyboardKeyInvalid,
  165. KeyboardKeyInvalid,
  166. KeyboardKeyInvalid,
  167. KeyboardKeyFurigana,
  168. KeyboardKeyInvalid,
  169. KeyboardKeyKanji,
  170. KeyboardKeyInvalid,
  171. KeyboardKeyHirijana,
  172. KeyboardKeyInvalid,
  173. KeyboardKeyInternational4,
  174. KeyboardKeyInternational5,
  175. };
  176. EXTENDED_KEY_DESCRIPTION
  177. I8042ScanCodeSet1ExtendedKeyTable[SCAN_CODE_1_EXTENDED_KEY_COUNT] = {
  178. {0x07, KeyboardKeyRedo},
  179. {0x08, KeyboardKeyUndo},
  180. {0x0A, KeyboardKeyPaste},
  181. {0x10, KeyboardKeySkipBack},
  182. {0x17, KeyboardKeyCut},
  183. {0x18, KeyboardKeyCopy},
  184. {0x19, KeyboardKeySkipForward},
  185. {0x1C, KeyboardKeyKeypadEnter},
  186. {0x1D, KeyboardKeyRightControl},
  187. {0x1E, KeyboardKeyMail},
  188. {0x20, KeyboardKeyMute},
  189. {0x22, KeyboardKeyPlay},
  190. {0x24, KeyboardKeyStop},
  191. {0x2C, KeyboardKeyEject},
  192. {0x2E, KeyboardKeyVolumeDown},
  193. {0x30, KeyboardKeyVolumeUp},
  194. {0x32, KeyboardKeyWeb},
  195. {0x35, KeyboardKeyKeypadSlash},
  196. {0x37, KeyboardKeyPrintScreen},
  197. {0x38, KeyboardKeyRightAlt},
  198. {0x3B, KeyboardKeyHelp},
  199. {0x3C, KeyboardKeyMusic},
  200. {0x46, KeyboardKeyBreak},
  201. {0x47, KeyboardKeyHome},
  202. {0x48, KeyboardKeyUp},
  203. {0x49, KeyboardKeyPageUp},
  204. {0x4B, KeyboardKeyLeft},
  205. {0x4D, KeyboardKeyRight},
  206. {0x4F, KeyboardKeyEnd},
  207. {0x50, KeyboardKeyDown},
  208. {0x51, KeyboardKeyPageDown},
  209. {0x52, KeyboardKeyInsert},
  210. {0x53, KeyboardKeyDelete},
  211. {0x5B, KeyboardKeyLeftWindows},
  212. {0x5C, KeyboardKeyRightWindows},
  213. {0x5D, KeyboardKeyMenu},
  214. {0x5E, KeyboardKeyPower},
  215. {0x5F, KeyboardKeySleep},
  216. {0x63, KeyboardKeyWake},
  217. {0x64, KeyboardKeyPictures},
  218. {0x6D, KeyboardKeyVideo},
  219. };
  220. EXTENDED_2_KEY_DESCRIPTION
  221. I8042ScanCodeSet1Extended2KeyTable[SCAN_CODE_1_EXTENDED_2_KEY_COUNT] = {
  222. {0x1D, 0x45, KeyboardKeyBreak},
  223. };
  224. //
  225. // ------------------------------------------------------------------ Functions
  226. //
  227. KEYBOARD_KEY
  228. I8042ConvertScanCodeToKey (
  229. UCHAR ScanCode1,
  230. UCHAR ScanCode2,
  231. UCHAR ScanCode3,
  232. PBOOL KeyUp
  233. )
  234. /*++
  235. Routine Description:
  236. This routine converts a scan code sequence into a key.
  237. Arguments:
  238. ScanCode1 - Supplies the first scan code.
  239. ScanCode2 - Supplies an optional second scan code.
  240. ScanCode3 - Supplies an optional third scan code.
  241. KeyUp - Supplies a pointer where a boolean will be returned indicating
  242. whether the key is being released (TRUE) or pressed (FALSE).
  243. Return Value:
  244. Returns the keyboard key code associated with this scan code sequence.
  245. --*/
  246. {
  247. ULONG ExtendedIndex;
  248. KEYBOARD_KEY Key;
  249. *KeyUp = FALSE;
  250. if (ScanCode1 == SCAN_CODE_1_EXTENDED_2_CODE) {
  251. if ((ScanCode2 & SCAN_CODE_1_KEY_UP) != 0) {
  252. *KeyUp = TRUE;
  253. ScanCode2 &= ~SCAN_CODE_1_KEY_UP;
  254. ASSERT((ScanCode3 & SCAN_CODE_1_KEY_UP) != 0);
  255. ScanCode3 &= ~ SCAN_CODE_1_KEY_UP;
  256. }
  257. for (ExtendedIndex = 0;
  258. ExtendedIndex < SCAN_CODE_1_EXTENDED_2_KEY_COUNT;
  259. ExtendedIndex += 1) {
  260. if ((I8042ScanCodeSet1Extended2KeyTable[ExtendedIndex].ScanCode1 ==
  261. ScanCode2) &&
  262. (I8042ScanCodeSet1Extended2KeyTable[ExtendedIndex].ScanCode2 ==
  263. ScanCode3)) {
  264. break;
  265. }
  266. }
  267. if (ExtendedIndex == SCAN_CODE_1_EXTENDED_2_KEY_COUNT) {
  268. Key = KeyboardKeyInvalid;
  269. } else {
  270. Key = I8042ScanCodeSet1Extended2KeyTable[ExtendedIndex].Key;
  271. }
  272. } else if (ScanCode1 == SCAN_CODE_1_EXTENDED_CODE) {
  273. if ((ScanCode2 & SCAN_CODE_1_KEY_UP) != 0) {
  274. *KeyUp = TRUE;
  275. ScanCode2 &= ~SCAN_CODE_1_KEY_UP;
  276. }
  277. for (ExtendedIndex = 0;
  278. ExtendedIndex < SCAN_CODE_1_EXTENDED_KEY_COUNT;
  279. ExtendedIndex += 1) {
  280. if (I8042ScanCodeSet1ExtendedKeyTable[ExtendedIndex].ScanCode ==
  281. ScanCode2) {
  282. break;
  283. }
  284. }
  285. if (ExtendedIndex == SCAN_CODE_1_EXTENDED_KEY_COUNT) {
  286. Key = KeyboardKeyInvalid;
  287. } else {
  288. Key = I8042ScanCodeSet1ExtendedKeyTable[ExtendedIndex].Key;
  289. }
  290. } else {
  291. if ((ScanCode1 & SCAN_CODE_1_KEY_UP) != 0) {
  292. *KeyUp = TRUE;
  293. ScanCode1 &= ~SCAN_CODE_1_KEY_UP;
  294. }
  295. Key = I8042ScanCodeSet1KeyTable[ScanCode1];
  296. }
  297. return Key;
  298. }
  299. //
  300. // --------------------------------------------------------- Internal Functions
  301. //