InputSdl.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. // Copyright (C) 2009-2020, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <anki/input/Input.h>
  6. #include <anki/input/InputSdl.h>
  7. #include <anki/core/NativeWindowSdl.h>
  8. #include <anki/util/Logger.h>
  9. #include <SDL.h>
  10. namespace anki
  11. {
  12. static MouseButton sdlMouseButtonToAnKi(const U32 sdl)
  13. {
  14. MouseButton out = MouseButton::COUNT;
  15. switch(sdl)
  16. {
  17. case SDL_BUTTON_LEFT:
  18. out = MouseButton::LEFT;
  19. break;
  20. case SDL_BUTTON_RIGHT:
  21. out = MouseButton::RIGHT;
  22. break;
  23. case SDL_BUTTON_MIDDLE:
  24. out = MouseButton::MIDDLE;
  25. break;
  26. }
  27. return out;
  28. }
  29. Error Input::initInternal(NativeWindow* nativeWindow)
  30. {
  31. ANKI_ASSERT(nativeWindow);
  32. m_nativeWindow = nativeWindow;
  33. // Init native
  34. HeapAllocator<std::pair<const SDL_Keycode, KeyCode>> alloc = m_nativeWindow->_getAllocator();
  35. m_impl = m_nativeWindow->_getAllocator().newInstance<InputImpl>(alloc);
  36. // impl
  37. #define MAP(sdl, ak) m_impl->m_sdlToAnki[sdl] = KeyCode::ak
  38. MAP(SDLK_RETURN, RETURN);
  39. MAP(SDLK_ESCAPE, ESCAPE);
  40. MAP(SDLK_BACKSPACE, BACKSPACE);
  41. MAP(SDLK_TAB, TAB);
  42. MAP(SDLK_SPACE, SPACE);
  43. MAP(SDLK_EXCLAIM, EXCLAIM);
  44. MAP(SDLK_QUOTEDBL, QUOTEDBL);
  45. MAP(SDLK_HASH, HASH);
  46. MAP(SDLK_PERCENT, PERCENT);
  47. MAP(SDLK_DOLLAR, DOLLAR);
  48. MAP(SDLK_AMPERSAND, AMPERSAND);
  49. MAP(SDLK_QUOTE, QUOTE);
  50. MAP(SDLK_LEFTPAREN, LEFTPAREN);
  51. MAP(SDLK_RIGHTPAREN, RIGHTPAREN);
  52. MAP(SDLK_ASTERISK, ASTERISK);
  53. MAP(SDLK_PLUS, PLUS);
  54. MAP(SDLK_COMMA, COMMA);
  55. MAP(SDLK_MINUS, MINUS);
  56. MAP(SDLK_PERIOD, PERIOD);
  57. MAP(SDLK_SLASH, SLASH);
  58. MAP(SDLK_0, _0);
  59. MAP(SDLK_1, _1);
  60. MAP(SDLK_2, _2);
  61. MAP(SDLK_3, _3);
  62. MAP(SDLK_4, _4);
  63. MAP(SDLK_5, _5);
  64. MAP(SDLK_6, _6);
  65. MAP(SDLK_7, _7);
  66. MAP(SDLK_8, _8);
  67. MAP(SDLK_9, _9);
  68. MAP(SDLK_COLON, COLON);
  69. MAP(SDLK_SEMICOLON, SEMICOLON);
  70. MAP(SDLK_LESS, LESS);
  71. MAP(SDLK_EQUALS, EQUALS);
  72. MAP(SDLK_GREATER, GREATER);
  73. MAP(SDLK_QUESTION, QUESTION);
  74. MAP(SDLK_AT, AT);
  75. MAP(SDLK_LEFTBRACKET, LEFTBRACKET);
  76. MAP(SDLK_BACKSLASH, BACKSLASH);
  77. MAP(SDLK_RIGHTBRACKET, RIGHTBRACKET);
  78. MAP(SDLK_CARET, CARET);
  79. MAP(SDLK_UNDERSCORE, UNDERSCORE);
  80. MAP(SDLK_BACKQUOTE, BACKQUOTE);
  81. MAP(SDLK_a, A);
  82. MAP(SDLK_b, B);
  83. MAP(SDLK_c, C);
  84. MAP(SDLK_d, D);
  85. MAP(SDLK_e, E);
  86. MAP(SDLK_f, F);
  87. MAP(SDLK_g, G);
  88. MAP(SDLK_h, H);
  89. MAP(SDLK_i, I);
  90. MAP(SDLK_j, J);
  91. MAP(SDLK_k, K);
  92. MAP(SDLK_l, L);
  93. MAP(SDLK_m, M);
  94. MAP(SDLK_n, N);
  95. MAP(SDLK_o, O);
  96. MAP(SDLK_p, P);
  97. MAP(SDLK_q, Q);
  98. MAP(SDLK_r, R);
  99. MAP(SDLK_s, S);
  100. MAP(SDLK_t, T);
  101. MAP(SDLK_u, U);
  102. MAP(SDLK_v, V);
  103. MAP(SDLK_w, W);
  104. MAP(SDLK_x, X);
  105. MAP(SDLK_y, Y);
  106. MAP(SDLK_z, Z);
  107. MAP(SDLK_CAPSLOCK, CAPSLOCK);
  108. MAP(SDLK_F1, F1);
  109. MAP(SDLK_F2, F2);
  110. MAP(SDLK_F3, F3);
  111. MAP(SDLK_F4, F4);
  112. MAP(SDLK_F5, F5);
  113. MAP(SDLK_F6, F6);
  114. MAP(SDLK_F7, F7);
  115. MAP(SDLK_F8, F8);
  116. MAP(SDLK_F9, F9);
  117. MAP(SDLK_F10, F10);
  118. MAP(SDLK_F11, F11);
  119. MAP(SDLK_F12, F12);
  120. MAP(SDLK_PRINTSCREEN, PRINTSCREEN);
  121. MAP(SDLK_SCROLLLOCK, SCROLLLOCK);
  122. MAP(SDLK_PAUSE, PAUSE);
  123. MAP(SDLK_INSERT, INSERT);
  124. MAP(SDLK_HOME, HOME);
  125. MAP(SDLK_PAGEUP, PAGEUP);
  126. MAP(SDLK_DELETE, DELETE);
  127. MAP(SDLK_END, END);
  128. MAP(SDLK_PAGEDOWN, PAGEDOWN);
  129. MAP(SDLK_RIGHT, RIGHT);
  130. MAP(SDLK_LEFT, LEFT);
  131. MAP(SDLK_DOWN, DOWN);
  132. MAP(SDLK_UP, UP);
  133. MAP(SDLK_NUMLOCKCLEAR, NUMLOCKCLEAR);
  134. MAP(SDLK_KP_DIVIDE, KP_DIVIDE);
  135. MAP(SDLK_KP_MULTIPLY, KP_MULTIPLY);
  136. MAP(SDLK_KP_MINUS, KP_MINUS);
  137. MAP(SDLK_KP_PLUS, KP_PLUS);
  138. MAP(SDLK_KP_ENTER, KP_ENTER);
  139. MAP(SDLK_KP_1, KP_1);
  140. MAP(SDLK_KP_2, KP_2);
  141. MAP(SDLK_KP_3, KP_3);
  142. MAP(SDLK_KP_4, KP_4);
  143. MAP(SDLK_KP_5, KP_5);
  144. MAP(SDLK_KP_6, KP_6);
  145. MAP(SDLK_KP_7, KP_7);
  146. MAP(SDLK_KP_8, KP_8);
  147. MAP(SDLK_KP_9, KP_9);
  148. MAP(SDLK_KP_0, KP_0);
  149. MAP(SDLK_KP_PERIOD, KP_PERIOD);
  150. MAP(SDLK_APPLICATION, APPLICATION);
  151. MAP(SDLK_POWER, POWER);
  152. MAP(SDLK_KP_EQUALS, KP_EQUALS);
  153. MAP(SDLK_F13, F13);
  154. MAP(SDLK_F14, F14);
  155. MAP(SDLK_F15, F15);
  156. MAP(SDLK_F16, F16);
  157. MAP(SDLK_F17, F17);
  158. MAP(SDLK_F18, F18);
  159. MAP(SDLK_F19, F19);
  160. MAP(SDLK_F20, F20);
  161. MAP(SDLK_F21, F21);
  162. MAP(SDLK_F22, F22);
  163. MAP(SDLK_F23, F23);
  164. MAP(SDLK_F24, F24);
  165. MAP(SDLK_EXECUTE, EXECUTE);
  166. MAP(SDLK_HELP, HELP);
  167. MAP(SDLK_MENU, MENU);
  168. MAP(SDLK_SELECT, SELECT);
  169. MAP(SDLK_STOP, STOP);
  170. MAP(SDLK_AGAIN, AGAIN);
  171. MAP(SDLK_UNDO, UNDO);
  172. MAP(SDLK_CUT, CUT);
  173. MAP(SDLK_COPY, COPY);
  174. MAP(SDLK_PASTE, PASTE);
  175. MAP(SDLK_FIND, FIND);
  176. MAP(SDLK_MUTE, MUTE);
  177. MAP(SDLK_VOLUMEUP, VOLUMEUP);
  178. MAP(SDLK_VOLUMEDOWN, VOLUMEDOWN);
  179. MAP(SDLK_KP_COMMA, KP_COMMA);
  180. MAP(SDLK_KP_EQUALSAS400, KP_EQUALSAS400);
  181. MAP(SDLK_ALTERASE, ALTERASE);
  182. MAP(SDLK_SYSREQ, SYSREQ);
  183. MAP(SDLK_CANCEL, CANCEL);
  184. MAP(SDLK_CLEAR, CLEAR);
  185. MAP(SDLK_PRIOR, PRIOR);
  186. MAP(SDLK_RETURN2, RETURN2);
  187. MAP(SDLK_SEPARATOR, SEPARATOR);
  188. MAP(SDLK_OUT, OUT);
  189. MAP(SDLK_OPER, OPER);
  190. MAP(SDLK_CLEARAGAIN, CLEARAGAIN);
  191. MAP(SDLK_CRSEL, CRSEL);
  192. MAP(SDLK_EXSEL, EXSEL);
  193. MAP(SDLK_KP_00, KP_00);
  194. MAP(SDLK_KP_000, KP_000);
  195. MAP(SDLK_THOUSANDSSEPARATOR, THOUSANDSSEPARATOR);
  196. MAP(SDLK_DECIMALSEPARATOR, DECIMALSEPARATOR);
  197. MAP(SDLK_CURRENCYUNIT, CURRENCYUNIT);
  198. MAP(SDLK_CURRENCYSUBUNIT, CURRENCYSUBUNIT);
  199. MAP(SDLK_KP_LEFTPAREN, KP_LEFTPAREN);
  200. MAP(SDLK_KP_RIGHTPAREN, KP_RIGHTPAREN);
  201. MAP(SDLK_KP_LEFTBRACE, KP_LEFTBRACE);
  202. MAP(SDLK_KP_RIGHTBRACE, KP_RIGHTBRACE);
  203. MAP(SDLK_KP_TAB, KP_TAB);
  204. MAP(SDLK_KP_BACKSPACE, KP_BACKSPACE);
  205. MAP(SDLK_KP_A, KP_A);
  206. MAP(SDLK_KP_B, KP_B);
  207. MAP(SDLK_KP_C, KP_C);
  208. MAP(SDLK_KP_D, KP_D);
  209. MAP(SDLK_KP_E, KP_E);
  210. MAP(SDLK_KP_F, KP_F);
  211. MAP(SDLK_KP_XOR, KP_XOR);
  212. MAP(SDLK_KP_POWER, KP_POWER);
  213. MAP(SDLK_KP_PERCENT, KP_PERCENT);
  214. MAP(SDLK_KP_LESS, KP_LESS);
  215. MAP(SDLK_KP_GREATER, KP_GREATER);
  216. MAP(SDLK_KP_AMPERSAND, KP_AMPERSAND);
  217. MAP(SDLK_KP_DBLAMPERSAND, KP_DBLAMPERSAND);
  218. MAP(SDLK_KP_VERTICALBAR, KP_VERTICALBAR);
  219. MAP(SDLK_KP_DBLVERTICALBAR, KP_DBLVERTICALBAR);
  220. MAP(SDLK_KP_COLON, KP_COLON);
  221. MAP(SDLK_KP_HASH, KP_HASH);
  222. MAP(SDLK_KP_SPACE, KP_SPACE);
  223. MAP(SDLK_KP_AT, KP_AT);
  224. MAP(SDLK_KP_EXCLAM, KP_EXCLAM);
  225. MAP(SDLK_KP_MEMSTORE, KP_MEMSTORE);
  226. MAP(SDLK_KP_MEMRECALL, KP_MEMRECALL);
  227. MAP(SDLK_KP_MEMCLEAR, KP_MEMCLEAR);
  228. MAP(SDLK_KP_MEMADD, KP_MEMADD);
  229. MAP(SDLK_KP_MEMSUBTRACT, KP_MEMSUBTRACT);
  230. MAP(SDLK_KP_MEMMULTIPLY, KP_MEMMULTIPLY);
  231. MAP(SDLK_KP_MEMDIVIDE, KP_MEMDIVIDE);
  232. MAP(SDLK_KP_PLUSMINUS, KP_PLUSMINUS);
  233. MAP(SDLK_KP_CLEAR, KP_CLEAR);
  234. MAP(SDLK_KP_CLEARENTRY, KP_CLEARENTRY);
  235. MAP(SDLK_KP_BINARY, KP_BINARY);
  236. MAP(SDLK_KP_OCTAL, KP_OCTAL);
  237. MAP(SDLK_KP_DECIMAL, KP_DECIMAL);
  238. MAP(SDLK_KP_HEXADECIMAL, KP_HEXADECIMAL);
  239. MAP(SDLK_LCTRL, LCTRL);
  240. MAP(SDLK_LSHIFT, LSHIFT);
  241. MAP(SDLK_LALT, LALT);
  242. MAP(SDLK_LGUI, LGUI);
  243. MAP(SDLK_RCTRL, RCTRL);
  244. MAP(SDLK_RSHIFT, RSHIFT);
  245. MAP(SDLK_RALT, RALT);
  246. MAP(SDLK_RGUI, RGUI);
  247. MAP(SDLK_MODE, MODE);
  248. MAP(SDLK_AUDIONEXT, AUDIONEXT);
  249. MAP(SDLK_AUDIOPREV, AUDIOPREV);
  250. MAP(SDLK_AUDIOSTOP, AUDIOSTOP);
  251. MAP(SDLK_AUDIOPLAY, AUDIOPLAY);
  252. MAP(SDLK_AUDIOMUTE, AUDIOMUTE);
  253. MAP(SDLK_MEDIASELECT, MEDIASELECT);
  254. MAP(SDLK_WWW, WWW);
  255. MAP(SDLK_MAIL, MAIL);
  256. MAP(SDLK_CALCULATOR, CALCULATOR);
  257. MAP(SDLK_COMPUTER, COMPUTER);
  258. MAP(SDLK_AC_SEARCH, AC_SEARCH);
  259. MAP(SDLK_AC_HOME, AC_HOME);
  260. MAP(SDLK_AC_BACK, AC_BACK);
  261. MAP(SDLK_AC_FORWARD, AC_FORWARD);
  262. MAP(SDLK_AC_STOP, AC_STOP);
  263. MAP(SDLK_AC_REFRESH, AC_REFRESH);
  264. MAP(SDLK_AC_BOOKMARKS, AC_BOOKMARKS);
  265. MAP(SDLK_BRIGHTNESSDOWN, BRIGHTNESSDOWN);
  266. MAP(SDLK_BRIGHTNESSUP, BRIGHTNESSUP);
  267. MAP(SDLK_DISPLAYSWITCH, DISPLAYSWITCH);
  268. MAP(SDLK_KBDILLUMTOGGLE, KBDILLUMTOGGLE);
  269. MAP(SDLK_KBDILLUMDOWN, KBDILLUMDOWN);
  270. MAP(SDLK_KBDILLUMUP, KBDILLUMUP);
  271. MAP(SDLK_EJECT, EJECT);
  272. MAP(SDLK_SLEEP, SLEEP);
  273. #undef MAP
  274. // Call once to clear first events
  275. return handleEvents();
  276. }
  277. void Input::destroy()
  278. {
  279. if(m_impl != nullptr)
  280. {
  281. m_nativeWindow->_getAllocator().deleteInstance(m_impl);
  282. m_impl = nullptr;
  283. }
  284. m_nativeWindow = nullptr;
  285. }
  286. Error Input::handleEvents()
  287. {
  288. ANKI_ASSERT(m_nativeWindow != nullptr);
  289. m_textInput[0] = '\0';
  290. // add the times a key is being pressed
  291. for(auto& k : m_keys)
  292. {
  293. if(k)
  294. {
  295. ++k;
  296. }
  297. }
  298. for(auto& k : m_mouseBtns)
  299. {
  300. if(k)
  301. {
  302. ++k;
  303. }
  304. }
  305. SDL_Event event;
  306. KeyCode akkey;
  307. SDL_StartTextInput();
  308. while(SDL_PollEvent(&event))
  309. {
  310. switch(event.type)
  311. {
  312. case SDL_KEYDOWN:
  313. akkey = m_impl->m_sdlToAnki[event.key.keysym.sym];
  314. m_keys[akkey] = 1;
  315. break;
  316. case SDL_KEYUP:
  317. akkey = m_impl->m_sdlToAnki[event.key.keysym.sym];
  318. m_keys[akkey] = 0;
  319. break;
  320. case SDL_MOUSEBUTTONDOWN:
  321. {
  322. MouseButton mb = sdlMouseButtonToAnKi(event.button.button);
  323. if(mb != MouseButton::COUNT)
  324. {
  325. m_mouseBtns[mb] = 1;
  326. }
  327. break;
  328. }
  329. case SDL_MOUSEBUTTONUP:
  330. {
  331. MouseButton mb = sdlMouseButtonToAnKi(event.button.button);
  332. if(mb != MouseButton::COUNT)
  333. {
  334. m_mouseBtns[mb] = 0;
  335. }
  336. break;
  337. }
  338. case SDL_MOUSEWHEEL:
  339. m_mouseBtns[MouseButton::SCROLL_UP] = event.wheel.y > 0;
  340. m_mouseBtns[MouseButton::SCROLL_DOWN] = event.wheel.y < 0;
  341. break;
  342. case SDL_MOUSEMOTION:
  343. m_mousePosWin.x() = event.button.x;
  344. m_mousePosWin.y() = event.button.y;
  345. m_mousePosNdc.x() = F32(event.button.x) / F32(m_nativeWindow->getWidth()) * 2.0f - 1.0f;
  346. m_mousePosNdc.y() = -(F32(event.button.y) / F32(m_nativeWindow->getHeight()) * 2.0f - 1.0f);
  347. break;
  348. case SDL_QUIT:
  349. addEvent(InputEvent::WINDOW_CLOSED);
  350. break;
  351. case SDL_TEXTINPUT:
  352. std::strncpy(&m_textInput[0], event.text.text, m_textInput.getSize() - 1);
  353. break;
  354. }
  355. } // end while events
  356. // Lock mouse
  357. if(m_lockCurs)
  358. {
  359. moveCursor(Vec2(0.0));
  360. }
  361. return Error::NONE;
  362. }
  363. void Input::moveCursor(const Vec2& pos)
  364. {
  365. if(pos != m_mousePosNdc)
  366. {
  367. const I32 x = I32(F32(m_nativeWindow->getWidth()) * (pos.x() * 0.5f + 0.5f));
  368. const I32 y = I32(F32(m_nativeWindow->getHeight()) * (-pos.y() * 0.5f + 0.5f));
  369. SDL_WarpMouseInWindow(m_nativeWindow->getNative().m_window, x, y);
  370. // SDL doesn't generate a SDL_MOUSEMOTION event if the cursor is outside the window. Push that event
  371. SDL_Event event;
  372. event.type = SDL_MOUSEMOTION;
  373. event.button.x = x;
  374. event.button.y = y;
  375. SDL_PushEvent(&event);
  376. }
  377. }
  378. void Input::hideCursor(Bool hide)
  379. {
  380. SDL_ShowCursor(!hide);
  381. }
  382. } // end namespace anki