WebKeyboardLinux.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. //
  2. // Copyright (c) 2014-2016, THUNDERBEAST GAMES LLC All rights reserved
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #ifdef ATOMIC_PLATFORM_LINUX
  23. #include <include/cef_client.h>
  24. #include <Atomic/Core/Variant.h>
  25. #include <Atomic/Input/InputEvents.h>
  26. #include <Atomic/Input/Input.h>
  27. #include <Atomic/IO/Log.h>
  28. #include "WebKeyboard.h"
  29. #include <ThirdParty/SDL/include/SDL.h>
  30. #include <ThirdParty/SDL/include/SDL_syswm.h>
  31. #include <ThirdParty/SDL/src/events/scancodes_windows.h>
  32. namespace Atomic
  33. {
  34. // From ui/events/keycodes/keyboard_codes_posix.h.
  35. enum KeyboardCode {
  36. VKEY_BACK = 0x08, VKEY_TAB = 0x09, VKEY_BACKTAB = 0x0A, VKEY_CLEAR = 0x0C,
  37. VKEY_RETURN = 0x0D, VKEY_SHIFT = 0x10, VKEY_CONTROL = 0x11, VKEY_MENU = 0x12,
  38. VKEY_PAUSE = 0x13, VKEY_CAPITAL = 0x14, VKEY_KANA = 0x15, VKEY_HANGUL = 0x15,
  39. VKEY_JUNJA = 0x17, VKEY_FINAL = 0x18, VKEY_HANJA = 0x19, VKEY_KANJI = 0x19,
  40. VKEY_ESCAPE = 0x1B, VKEY_CONVERT = 0x1C, VKEY_NONCONVERT = 0x1D, VKEY_ACCEPT = 0x1E,
  41. VKEY_MODECHANGE = 0x1F, VKEY_SPACE = 0x20, VKEY_PRIOR = 0x21, VKEY_NEXT = 0x22,
  42. VKEY_END = 0x23, VKEY_HOME = 0x24, VKEY_LEFT = 0x25, VKEY_UP = 0x26,
  43. VKEY_RIGHT = 0x27, VKEY_DOWN = 0x28, VKEY_SELECT = 0x29, VKEY_PRINT = 0x2A,
  44. VKEY_EXECUTE = 0x2B, VKEY_SNAPSHOT = 0x2C, VKEY_INSERT = 0x2D, VKEY_DELETE = 0x2E,
  45. VKEY_HELP = 0x2F, VKEY_0 = 0x30, VKEY_1 = 0x31, VKEY_2 = 0x32,
  46. VKEY_3 = 0x33, VKEY_4 = 0x34, VKEY_5 = 0x35, VKEY_6 = 0x36,
  47. VKEY_7 = 0x37, VKEY_8 = 0x38, VKEY_9 = 0x39, VKEY_A = 0x41,
  48. VKEY_B = 0x42, VKEY_C = 0x43, VKEY_D = 0x44, VKEY_E = 0x45,
  49. VKEY_F = 0x46, VKEY_G = 0x47, VKEY_H = 0x48, VKEY_I = 0x49,
  50. VKEY_J = 0x4A, VKEY_K = 0x4B, VKEY_L = 0x4C, VKEY_M = 0x4D,
  51. VKEY_N = 0x4E, VKEY_O = 0x4F, VKEY_P = 0x50, VKEY_Q = 0x51,
  52. VKEY_R = 0x52, VKEY_S = 0x53, VKEY_T = 0x54, VKEY_U = 0x55,
  53. VKEY_V = 0x56, VKEY_W = 0x57, VKEY_X = 0x58, VKEY_Y = 0x59,
  54. VKEY_Z = 0x5A, VKEY_LWIN = 0x5B, VKEY_COMMAND = VKEY_LWIN, // Provide the Mac name for convenience.
  55. VKEY_RWIN = 0x5C, VKEY_APPS = 0x5D, VKEY_SLEEP = 0x5F, VKEY_NUMPAD0 = 0x60,
  56. VKEY_NUMPAD1 = 0x61, VKEY_NUMPAD2 = 0x62, VKEY_NUMPAD3 = 0x63, VKEY_NUMPAD4 = 0x64,
  57. VKEY_NUMPAD5 = 0x65, VKEY_NUMPAD6 = 0x66, VKEY_NUMPAD7 = 0x67, VKEY_NUMPAD8 = 0x68,
  58. VKEY_NUMPAD9 = 0x69, VKEY_MULTIPLY = 0x6A, VKEY_ADD = 0x6B, VKEY_SEPARATOR = 0x6C,
  59. VKEY_SUBTRACT = 0x6D, VKEY_DECIMAL = 0x6E, VKEY_DIVIDE = 0x6F, VKEY_F1 = 0x70,
  60. VKEY_F2 = 0x71, VKEY_F3 = 0x72, VKEY_F4 = 0x73, VKEY_F5 = 0x74,
  61. VKEY_F6 = 0x75, VKEY_F7 = 0x76, VKEY_F8 = 0x77, VKEY_F9 = 0x78,
  62. VKEY_F10 = 0x79, VKEY_F11 = 0x7A, VKEY_F12 = 0x7B, VKEY_F13 = 0x7C,
  63. VKEY_F14 = 0x7D, VKEY_F15 = 0x7E, VKEY_F16 = 0x7F, VKEY_F17 = 0x80,
  64. VKEY_F18 = 0x81, VKEY_F19 = 0x82, VKEY_F20 = 0x83, VKEY_F21 = 0x84,
  65. VKEY_F22 = 0x85, VKEY_F23 = 0x86, VKEY_F24 = 0x87, VKEY_NUMLOCK = 0x90,
  66. VKEY_SCROLL = 0x91, VKEY_LSHIFT = 0xA0, VKEY_RSHIFT = 0xA1, VKEY_LCONTROL = 0xA2,
  67. VKEY_RCONTROL = 0xA3, VKEY_LMENU = 0xA4, VKEY_RMENU = 0xA5, VKEY_BROWSER_BACK = 0xA6,
  68. VKEY_BROWSER_FORWARD = 0xA7, VKEY_BROWSER_REFRESH = 0xA8,VKEY_BROWSER_STOP = 0xA9,
  69. VKEY_BROWSER_SEARCH = 0xAA, VKEY_BROWSER_FAVORITES = 0xAB, VKEY_BROWSER_HOME = 0xAC,
  70. VKEY_VOLUME_MUTE = 0xAD,VKEY_VOLUME_DOWN = 0xAE,VKEY_VOLUME_UP = 0xAF, VKEY_MEDIA_NEXT_TRACK = 0xB0,
  71. VKEY_MEDIA_PREV_TRACK = 0xB1, VKEY_MEDIA_STOP = 0xB2, VKEY_MEDIA_PLAY_PAUSE = 0xB3,
  72. VKEY_MEDIA_LAUNCH_MAIL = 0xB4, VKEY_MEDIA_LAUNCH_MEDIA_SELECT = 0xB5,
  73. VKEY_MEDIA_LAUNCH_APP1 = 0xB6, VKEY_MEDIA_LAUNCH_APP2 = 0xB7,
  74. VKEY_OEM_1 = 0xBA, VKEY_OEM_PLUS = 0xBB, VKEY_OEM_COMMA = 0xBC, VKEY_OEM_MINUS = 0xBD,
  75. VKEY_OEM_PERIOD = 0xBE, VKEY_OEM_2 = 0xBF, VKEY_OEM_3 = 0xC0, VKEY_OEM_4 = 0xDB,
  76. VKEY_OEM_5 = 0xDC, VKEY_OEM_6 = 0xDD, VKEY_OEM_7 = 0xDE, VKEY_OEM_8 = 0xDF,
  77. VKEY_OEM_102 = 0xE2, VKEY_OEM_103 = 0xE3, // GTV KEYCODE_MEDIA_REWIND
  78. VKEY_OEM_104 = 0xE4, // GTV KEYCODE_MEDIA_FAST_FORWARD
  79. VKEY_PROCESSKEY = 0xE5, VKEY_PACKET = 0xE7, VKEY_DBE_SBCSCHAR = 0xF3, VKEY_DBE_DBCSCHAR = 0xF4,
  80. VKEY_ATTN = 0xF6, VKEY_CRSEL = 0xF7, VKEY_EXSEL = 0xF8, VKEY_EREOF = 0xF9,
  81. VKEY_PLAY = 0xFA, VKEY_ZOOM = 0xFB, VKEY_NONAME = 0xFC, VKEY_PA1 = 0xFD,
  82. VKEY_OEM_CLEAR = 0xFE, VKEY_UNKNOWN = 0,
  83. // POSIX specific VKEYs. Note that as of Windows SDK 7.1, 0x97-9F, 0xD8-DA,
  84. // and 0xE8 are unassigned.
  85. VKEY_WLAN = 0x97, VKEY_POWER = 0x98, VKEY_BRIGHTNESS_DOWN = 0xD8,VKEY_BRIGHTNESS_UP = 0xD9,
  86. VKEY_KBD_BRIGHTNESS_DOWN = 0xDA, VKEY_KBD_BRIGHTNESS_UP = 0xE8,
  87. // Windows does not have a specific key code for AltGr. We use the unused 0xE1
  88. // (VK_OEM_AX) code to represent AltGr, matching the behaviour of Firefox on
  89. // Linux.
  90. VKEY_ALTGR = 0xE1,
  91. // Windows does not have a specific key code for Compose. We use the unused
  92. // 0xE6 (VK_ICO_CLEAR) code to represent Compose.
  93. VKEY_COMPOSE = 0xE6,
  94. };
  95. static bool SDLScanCodeToWindowsScanCode(SDL_Scancode code, long int& lParam, long int& wParam )
  96. {
  97. wParam = 0;
  98. lParam = 0;
  99. int numCodes = sizeof(windows_scancode_table)/sizeof(SDL_Scancode);
  100. int windowsScanCode = -1;
  101. for (int i = 0; i < numCodes; i++)
  102. {
  103. if (windows_scancode_table[i] == code)
  104. {
  105. windowsScanCode = i;
  106. break;
  107. }
  108. }
  109. if (windowsScanCode != -1)
  110. {
  111. wParam = windowsScanCode;
  112. lParam = windowsScanCode << 16;
  113. }
  114. if ( code >= SDL_SCANCODE_A && code < SDL_SCANCODE_1 )
  115. {
  116. wParam = code + 61;
  117. lParam = wParam << 16;
  118. return wParam != 0 || lParam != 0;
  119. }
  120. switch (code)
  121. {
  122. case SDL_SCANCODE_RIGHT: wParam = VKEY_RIGHT; break;
  123. case SDL_SCANCODE_LEFT: wParam = VKEY_LEFT; break;
  124. case SDL_SCANCODE_UP: wParam = VKEY_UP; break;
  125. case SDL_SCANCODE_DOWN: wParam = VKEY_DOWN; break;
  126. case SDL_SCANCODE_DELETE: wParam = VKEY_DELETE; break;
  127. case SDL_SCANCODE_BACKSPACE: wParam = VKEY_BACK; break;
  128. case SDL_SCANCODE_F1: wParam = VKEY_F1; break;
  129. case SDL_SCANCODE_F2: wParam = VKEY_F2; break;
  130. case SDL_SCANCODE_F3: wParam = VKEY_F3; break;
  131. case SDL_SCANCODE_F4: wParam = VKEY_F4; break;
  132. case SDL_SCANCODE_F5: wParam = VKEY_F5; break;
  133. case SDL_SCANCODE_F6: wParam = VKEY_F6; break;
  134. case SDL_SCANCODE_F7: wParam = VKEY_F7; break;
  135. case SDL_SCANCODE_F8: wParam = VKEY_F8; break;
  136. case SDL_SCANCODE_F9: wParam = VKEY_F9; break;
  137. case SDL_SCANCODE_F10: wParam = VKEY_F10; break;
  138. case SDL_SCANCODE_F11: wParam = VKEY_F11; break;
  139. case SDL_SCANCODE_F12: wParam = VKEY_F12; break;
  140. case SDL_SCANCODE_PRINTSCREEN: wParam = VKEY_SNAPSHOT; break;
  141. case SDL_SCANCODE_SCROLLLOCK: wParam = VKEY_SCROLL; break;
  142. case SDL_SCANCODE_PAUSE: wParam = VKEY_PAUSE; break;
  143. case SDL_SCANCODE_INSERT: wParam = VKEY_INSERT; break;
  144. case SDL_SCANCODE_HOME: wParam = VKEY_HOME; break;
  145. case SDL_SCANCODE_PAGEUP: wParam = VKEY_PRIOR; break;
  146. case SDL_SCANCODE_END: wParam = VKEY_END; break;
  147. case SDL_SCANCODE_PAGEDOWN: wParam = VKEY_NEXT; break;
  148. case SDL_SCANCODE_1: wParam = VKEY_1; break;
  149. case SDL_SCANCODE_2: wParam = VKEY_2; break;
  150. case SDL_SCANCODE_3: wParam = VKEY_3; break;
  151. case SDL_SCANCODE_4: wParam = VKEY_4; break;
  152. case SDL_SCANCODE_5: wParam = VKEY_5; break;
  153. case SDL_SCANCODE_6: wParam = VKEY_6; break;
  154. case SDL_SCANCODE_7: wParam = VKEY_7; break;
  155. case SDL_SCANCODE_8: wParam = VKEY_8; break;
  156. case SDL_SCANCODE_9: wParam = VKEY_9; break;
  157. case SDL_SCANCODE_0: wParam = VKEY_0; break;
  158. case SDL_SCANCODE_SEMICOLON: wParam = VKEY_OEM_1; break;
  159. case SDL_SCANCODE_APOSTROPHE: wParam = VKEY_OEM_7; break;
  160. case SDL_SCANCODE_GRAVE: wParam = VKEY_OEM_3; break;
  161. case SDL_SCANCODE_KP_DIVIDE: wParam = VKEY_DIVIDE; break;
  162. case SDL_SCANCODE_KP_MULTIPLY: wParam = VKEY_MULTIPLY; break;
  163. case SDL_SCANCODE_KP_MINUS: wParam = VKEY_SUBTRACT; break;
  164. case SDL_SCANCODE_KP_PLUS: wParam = VKEY_ADD; break;
  165. case SDL_SCANCODE_KP_ENTER: wParam = VKEY_SEPARATOR; break;
  166. case SDL_SCANCODE_KP_1: wParam = VKEY_NUMPAD1; break;
  167. case SDL_SCANCODE_KP_2: wParam = VKEY_NUMPAD2; break;
  168. case SDL_SCANCODE_KP_3: wParam = VKEY_NUMPAD3; break;
  169. case SDL_SCANCODE_KP_4: wParam = VKEY_NUMPAD4; break;
  170. case SDL_SCANCODE_KP_5: wParam = VKEY_NUMPAD5; break;
  171. case SDL_SCANCODE_KP_6: wParam = VKEY_NUMPAD6; break;
  172. case SDL_SCANCODE_KP_7: wParam = VKEY_NUMPAD7; break;
  173. case SDL_SCANCODE_KP_8: wParam = VKEY_NUMPAD8; break;
  174. case SDL_SCANCODE_KP_9: wParam = VKEY_NUMPAD9; break;
  175. case SDL_SCANCODE_KP_0: wParam = VKEY_NUMPAD0; break;
  176. case SDL_SCANCODE_KP_PERIOD: wParam = VKEY_DECIMAL; break;
  177. case SDL_SCANCODE_NUMLOCKCLEAR: wParam = VKEY_NUMLOCK; break;
  178. case SDL_SCANCODE_CAPSLOCK: wParam = VKEY_CAPITAL; break;
  179. }
  180. return wParam != 0 || lParam != 0;
  181. }
  182. bool ConvertKeyEvent(Input* input, const StringHash eventType, VariantMap& eventData, CefKeyEvent& keyEvent)
  183. {
  184. memset((void*)&keyEvent, 0, sizeof(keyEvent));
  185. WebKeyEvent wk(eventType, eventData);
  186. if (wk.scanCode == SDL_SCANCODE_RETURN)
  187. {
  188. if (!wk.keyDown)
  189. return false;
  190. keyEvent.character = VKEY_RETURN;
  191. keyEvent.windows_key_code = VKEY_RETURN;
  192. keyEvent.type = KEYEVENT_RAWKEYDOWN;
  193. return true;
  194. }
  195. long int lParam = 0, wParam = 0;
  196. keyEvent.modifiers = EVENTFLAG_NONE;
  197. if (wk.qual & QUAL_SHIFT)
  198. keyEvent.modifiers |= EVENTFLAG_SHIFT_DOWN;
  199. if (wk.qual & QUAL_ALT)
  200. keyEvent.modifiers |= EVENTFLAG_ALT_DOWN;
  201. if (wk.qual & QUAL_CTRL)
  202. keyEvent.modifiers |= EVENTFLAG_CONTROL_DOWN;
  203. if (SDLScanCodeToWindowsScanCode((SDL_Scancode) wk.scanCode, lParam, wParam))
  204. {
  205. keyEvent.windows_key_code = (int) wParam;
  206. keyEvent.native_key_code = (int) lParam;
  207. keyEvent.type = wk.keyDown ? KEYEVENT_RAWKEYDOWN : KEYEVENT_KEYUP;
  208. }
  209. return true;
  210. }
  211. bool ConvertTextInputEvent(StringHash eventType, VariantMap& eventData, CefKeyEvent& keyEvent)
  212. {
  213. if (eventType != "TextInput")
  214. {
  215. LOGERROR("ConvertTextInputEvent - Unknown event type");
  216. return false;
  217. }
  218. memset((void*)&keyEvent, 0, sizeof(keyEvent));
  219. String text = eventData[TextInput::P_TEXT].GetString();
  220. if ( text.Length() > 0 )
  221. {
  222. keyEvent.character = (char16)text[0];
  223. keyEvent.type = KEYEVENT_CHAR;
  224. return true;
  225. }
  226. return false;
  227. }
  228. }
  229. #endif