InputSdl.cpp 10 KB

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