Event.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /**
  2. * Copyright (c) 2006-2013 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "Event.h"
  21. #include "keyboard/Keyboard.h"
  22. #include "mouse/Mouse.h"
  23. #include "libraries/utf8/utf8.h"
  24. #include <cmath>
  25. #include <cstddef>
  26. namespace love
  27. {
  28. namespace event
  29. {
  30. namespace sdl
  31. {
  32. const char *Event::getName() const
  33. {
  34. return "love.event.sdl";
  35. }
  36. Event::Event()
  37. {
  38. SDL_EnableUNICODE(1);
  39. }
  40. void Event::pump()
  41. {
  42. SDL_PumpEvents();
  43. static SDL_Event e;
  44. SDL_EnableUNICODE(1);
  45. Message *msg;
  46. while (SDL_PollEvent(&e))
  47. {
  48. msg = convert(e);
  49. if (msg)
  50. {
  51. push(msg);
  52. msg->release();
  53. }
  54. }
  55. }
  56. Message *Event::wait()
  57. {
  58. static SDL_Event e;
  59. bool ok = (SDL_WaitEvent(&e) == 1);
  60. if (!ok)
  61. return NULL;
  62. return convert(e);
  63. }
  64. void Event::clear()
  65. {
  66. static SDL_Event e;
  67. while (SDL_PollEvent(&e))
  68. {
  69. // Do nothing with 'e' ...
  70. }
  71. love::event::Event::clear();
  72. }
  73. Message *Event::convert(SDL_Event &e)
  74. {
  75. Message *msg = 0;
  76. love::keyboard::Keyboard::Key key;
  77. love::mouse::Mouse::Button button;
  78. love::joystick::Joystick::Hat hat;
  79. Variant *arg1 = 0, *arg2 = 0, *arg3 = 0;
  80. const char *txt;
  81. switch (e.type)
  82. {
  83. case SDL_KEYDOWN:
  84. if (!keys.find(e.key.keysym.sym, key))
  85. key = love::keyboard::Keyboard::KEY_UNKNOWN;
  86. if (!love::keyboard::Keyboard::getConstant(key, txt))
  87. txt = "unknown";
  88. arg1 = new Variant(txt, strlen(txt));
  89. txt = convertUnicode(e.key.keysym.unicode);
  90. if (txt)
  91. {
  92. arg2 = new Variant(txt, strlen(txt));
  93. msg = new Message("keypressed", arg1, arg2);
  94. arg2->release();
  95. }
  96. else
  97. msg = new Message("keypressed", arg1);
  98. arg1->release();
  99. break;
  100. case SDL_KEYUP:
  101. if (!keys.find(e.key.keysym.sym, key))
  102. key = love::keyboard::Keyboard::KEY_UNKNOWN;
  103. if (!love::keyboard::Keyboard::getConstant(key, txt))
  104. txt = "unknown";
  105. arg1 = new Variant(txt, strlen(txt));
  106. msg = new Message("keyreleased", arg1);
  107. arg1->release();
  108. break;
  109. case SDL_MOUSEBUTTONDOWN:
  110. case SDL_MOUSEBUTTONUP:
  111. if (buttons.find(e.button.button, button) && love::mouse::Mouse::getConstant(button, txt))
  112. {
  113. arg1 = new Variant((double) e.button.x);
  114. arg2 = new Variant((double) e.button.y);
  115. arg3 = new Variant(txt, strlen(txt));
  116. msg = new Message((e.type == SDL_MOUSEBUTTONDOWN) ?
  117. "mousepressed" : "mousereleased",
  118. arg1, arg2, arg3);
  119. arg1->release();
  120. arg2->release();
  121. arg3->release();
  122. }
  123. break;
  124. case SDL_JOYBUTTONDOWN:
  125. case SDL_JOYBUTTONUP:
  126. arg1 = new Variant((double)(e.jbutton.which+1));
  127. arg2 = new Variant((double)(e.jbutton.button+1));
  128. msg = new Message((e.type == SDL_JOYBUTTONDOWN) ?
  129. "joystickpressed" : "joystickreleased",
  130. arg1, arg2);
  131. arg1->release();
  132. arg2->release();
  133. break;
  134. case SDL_JOYAXISMOTION:
  135. {
  136. arg1 = new Variant((double)(e.jaxis.which+1));
  137. arg2 = new Variant((double)(e.jaxis.axis+1));
  138. float value = e.jaxis.value / 32768.0f;
  139. if (fabsf(value) < 0.001f) value = 0.0f;
  140. if (value < -0.99f) value = -1.0f;
  141. if (value > 0.99f) value = 1.0f;
  142. arg3 = new Variant((double) value);
  143. msg = new Message("joystickaxis", arg1, arg2, arg3);
  144. arg1->release();
  145. arg2->release();
  146. arg3->release();
  147. }
  148. break;
  149. case SDL_JOYHATMOTION:
  150. if (hats.find(e.jhat.value, hat) && love::joystick::Joystick::getConstant(hat, txt))
  151. {
  152. arg1 = new Variant((double)(e.jhat.which+1));
  153. arg2 = new Variant((double)(e.jhat.hat+1));
  154. arg3 = new Variant(txt, strlen(txt));
  155. msg = new Message("joystickhat", arg1, arg2, arg3);
  156. arg1->release();
  157. arg2->release();
  158. arg3->release();
  159. }
  160. break;
  161. case SDL_ACTIVEEVENT:
  162. arg1 = new Variant(e.active.gain != 0);
  163. if (e.active.state & SDL_APPINPUTFOCUS)
  164. msg = new Message("focus", arg1);
  165. else if (e.active.state & SDL_APPMOUSEFOCUS)
  166. msg = new Message("mousefocus", arg1);
  167. else if (e.active.state & SDL_APPACTIVE)
  168. msg = new Message("visible", arg1);
  169. arg1->release();
  170. break;
  171. case SDL_QUIT:
  172. msg = new Message("quit");
  173. break;
  174. case SDL_VIDEORESIZE:
  175. arg1 = new Variant((double) e.resize.w);
  176. arg2 = new Variant((double) e.resize.h);
  177. msg = new Message("resize", arg1, arg2);
  178. arg1->release();
  179. arg2->release();
  180. break;
  181. }
  182. return msg;
  183. }
  184. const char *Event::convertUnicode(Uint16 codepoint) const
  185. {
  186. // A single unicode character can use up to 4 bytes.
  187. static char str[5] = {'\0'};
  188. ptrdiff_t length = 0;
  189. if (codepoint == 0)
  190. return 0;
  191. char *end = utf8::unchecked::append(codepoint, str);
  192. length = end - str;
  193. if (length <= 0 || !utf8::is_valid(str, str + length))
  194. return 0;
  195. // Zero out the rest of the string.
  196. for (ptrdiff_t i = length; i < 5; i++)
  197. str[i] = '\0';
  198. return str;
  199. }
  200. EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
  201. {
  202. { love::keyboard::Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE},
  203. { love::keyboard::Keyboard::KEY_TAB, SDLK_TAB},
  204. { love::keyboard::Keyboard::KEY_CLEAR, SDLK_CLEAR},
  205. { love::keyboard::Keyboard::KEY_RETURN, SDLK_RETURN},
  206. { love::keyboard::Keyboard::KEY_PAUSE, SDLK_PAUSE},
  207. { love::keyboard::Keyboard::KEY_ESCAPE, SDLK_ESCAPE },
  208. { love::keyboard::Keyboard::KEY_SPACE, SDLK_SPACE },
  209. { love::keyboard::Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM },
  210. { love::keyboard::Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL },
  211. { love::keyboard::Keyboard::KEY_HASH, SDLK_HASH },
  212. { love::keyboard::Keyboard::KEY_DOLLAR, SDLK_DOLLAR },
  213. { love::keyboard::Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND },
  214. { love::keyboard::Keyboard::KEY_QUOTE, SDLK_QUOTE },
  215. { love::keyboard::Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN },
  216. { love::keyboard::Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN },
  217. { love::keyboard::Keyboard::KEY_ASTERISK, SDLK_ASTERISK },
  218. { love::keyboard::Keyboard::KEY_PLUS, SDLK_PLUS },
  219. { love::keyboard::Keyboard::KEY_COMMA, SDLK_COMMA },
  220. { love::keyboard::Keyboard::KEY_MINUS, SDLK_MINUS },
  221. { love::keyboard::Keyboard::KEY_PERIOD, SDLK_PERIOD },
  222. { love::keyboard::Keyboard::KEY_SLASH, SDLK_SLASH },
  223. { love::keyboard::Keyboard::KEY_0, SDLK_0 },
  224. { love::keyboard::Keyboard::KEY_1, SDLK_1 },
  225. { love::keyboard::Keyboard::KEY_2, SDLK_2 },
  226. { love::keyboard::Keyboard::KEY_3, SDLK_3 },
  227. { love::keyboard::Keyboard::KEY_4, SDLK_4 },
  228. { love::keyboard::Keyboard::KEY_5, SDLK_5 },
  229. { love::keyboard::Keyboard::KEY_6, SDLK_6 },
  230. { love::keyboard::Keyboard::KEY_7, SDLK_7 },
  231. { love::keyboard::Keyboard::KEY_8, SDLK_8 },
  232. { love::keyboard::Keyboard::KEY_9, SDLK_9 },
  233. { love::keyboard::Keyboard::KEY_COLON, SDLK_COLON },
  234. { love::keyboard::Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON },
  235. { love::keyboard::Keyboard::KEY_LESS, SDLK_LESS },
  236. { love::keyboard::Keyboard::KEY_EQUALS, SDLK_EQUALS },
  237. { love::keyboard::Keyboard::KEY_GREATER, SDLK_GREATER },
  238. { love::keyboard::Keyboard::KEY_QUESTION, SDLK_QUESTION },
  239. { love::keyboard::Keyboard::KEY_AT, SDLK_AT },
  240. { love::keyboard::Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET },
  241. { love::keyboard::Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH },
  242. { love::keyboard::Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET },
  243. { love::keyboard::Keyboard::KEY_CARET, SDLK_CARET },
  244. { love::keyboard::Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE },
  245. { love::keyboard::Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE },
  246. { love::keyboard::Keyboard::KEY_A, SDLK_a },
  247. { love::keyboard::Keyboard::KEY_B, SDLK_b },
  248. { love::keyboard::Keyboard::KEY_C, SDLK_c },
  249. { love::keyboard::Keyboard::KEY_D, SDLK_d },
  250. { love::keyboard::Keyboard::KEY_E, SDLK_e },
  251. { love::keyboard::Keyboard::KEY_F, SDLK_f },
  252. { love::keyboard::Keyboard::KEY_G, SDLK_g },
  253. { love::keyboard::Keyboard::KEY_H, SDLK_h },
  254. { love::keyboard::Keyboard::KEY_I, SDLK_i },
  255. { love::keyboard::Keyboard::KEY_J, SDLK_j },
  256. { love::keyboard::Keyboard::KEY_K, SDLK_k },
  257. { love::keyboard::Keyboard::KEY_L, SDLK_l },
  258. { love::keyboard::Keyboard::KEY_M, SDLK_m },
  259. { love::keyboard::Keyboard::KEY_N, SDLK_n },
  260. { love::keyboard::Keyboard::KEY_O, SDLK_o },
  261. { love::keyboard::Keyboard::KEY_P, SDLK_p },
  262. { love::keyboard::Keyboard::KEY_Q, SDLK_q },
  263. { love::keyboard::Keyboard::KEY_R, SDLK_r },
  264. { love::keyboard::Keyboard::KEY_S, SDLK_s },
  265. { love::keyboard::Keyboard::KEY_T, SDLK_t },
  266. { love::keyboard::Keyboard::KEY_U, SDLK_u },
  267. { love::keyboard::Keyboard::KEY_V, SDLK_v },
  268. { love::keyboard::Keyboard::KEY_W, SDLK_w },
  269. { love::keyboard::Keyboard::KEY_X, SDLK_x },
  270. { love::keyboard::Keyboard::KEY_Y, SDLK_y },
  271. { love::keyboard::Keyboard::KEY_Z, SDLK_z },
  272. { love::keyboard::Keyboard::KEY_DELETE, SDLK_DELETE },
  273. { love::keyboard::Keyboard::KEY_KP0, SDLK_KP0 },
  274. { love::keyboard::Keyboard::KEY_KP1, SDLK_KP1 },
  275. { love::keyboard::Keyboard::KEY_KP2, SDLK_KP2 },
  276. { love::keyboard::Keyboard::KEY_KP3, SDLK_KP3 },
  277. { love::keyboard::Keyboard::KEY_KP4, SDLK_KP4 },
  278. { love::keyboard::Keyboard::KEY_KP5, SDLK_KP5 },
  279. { love::keyboard::Keyboard::KEY_KP6, SDLK_KP6 },
  280. { love::keyboard::Keyboard::KEY_KP7, SDLK_KP7 },
  281. { love::keyboard::Keyboard::KEY_KP8, SDLK_KP8 },
  282. { love::keyboard::Keyboard::KEY_KP9, SDLK_KP9 },
  283. { love::keyboard::Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD },
  284. { love::keyboard::Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE },
  285. { love::keyboard::Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY},
  286. { love::keyboard::Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS },
  287. { love::keyboard::Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS },
  288. { love::keyboard::Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER },
  289. { love::keyboard::Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS },
  290. { love::keyboard::Keyboard::KEY_UP, SDLK_UP },
  291. { love::keyboard::Keyboard::KEY_DOWN, SDLK_DOWN },
  292. { love::keyboard::Keyboard::KEY_RIGHT, SDLK_RIGHT },
  293. { love::keyboard::Keyboard::KEY_LEFT, SDLK_LEFT },
  294. { love::keyboard::Keyboard::KEY_INSERT, SDLK_INSERT },
  295. { love::keyboard::Keyboard::KEY_HOME, SDLK_HOME },
  296. { love::keyboard::Keyboard::KEY_END, SDLK_END },
  297. { love::keyboard::Keyboard::KEY_PAGEUP, SDLK_PAGEUP },
  298. { love::keyboard::Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN },
  299. { love::keyboard::Keyboard::KEY_F1, SDLK_F1 },
  300. { love::keyboard::Keyboard::KEY_F2, SDLK_F2 },
  301. { love::keyboard::Keyboard::KEY_F3, SDLK_F3 },
  302. { love::keyboard::Keyboard::KEY_F4, SDLK_F4 },
  303. { love::keyboard::Keyboard::KEY_F5, SDLK_F5 },
  304. { love::keyboard::Keyboard::KEY_F6, SDLK_F6 },
  305. { love::keyboard::Keyboard::KEY_F7, SDLK_F7 },
  306. { love::keyboard::Keyboard::KEY_F8, SDLK_F8 },
  307. { love::keyboard::Keyboard::KEY_F9, SDLK_F9 },
  308. { love::keyboard::Keyboard::KEY_F10, SDLK_F10 },
  309. { love::keyboard::Keyboard::KEY_F11, SDLK_F11 },
  310. { love::keyboard::Keyboard::KEY_F12, SDLK_F12 },
  311. { love::keyboard::Keyboard::KEY_F13, SDLK_F13 },
  312. { love::keyboard::Keyboard::KEY_F14, SDLK_F14 },
  313. { love::keyboard::Keyboard::KEY_F15, SDLK_F15 },
  314. { love::keyboard::Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK },
  315. { love::keyboard::Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK },
  316. { love::keyboard::Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK },
  317. { love::keyboard::Keyboard::KEY_RSHIFT, SDLK_RSHIFT },
  318. { love::keyboard::Keyboard::KEY_LSHIFT, SDLK_LSHIFT },
  319. { love::keyboard::Keyboard::KEY_RCTRL, SDLK_RCTRL },
  320. { love::keyboard::Keyboard::KEY_LCTRL, SDLK_LCTRL },
  321. { love::keyboard::Keyboard::KEY_RALT, SDLK_RALT },
  322. { love::keyboard::Keyboard::KEY_LALT, SDLK_LALT },
  323. { love::keyboard::Keyboard::KEY_RMETA, SDLK_RMETA },
  324. { love::keyboard::Keyboard::KEY_LMETA, SDLK_LMETA },
  325. { love::keyboard::Keyboard::KEY_LSUPER, SDLK_LSUPER },
  326. { love::keyboard::Keyboard::KEY_RSUPER, SDLK_RSUPER },
  327. { love::keyboard::Keyboard::KEY_MODE, SDLK_MODE },
  328. { love::keyboard::Keyboard::KEY_COMPOSE, SDLK_COMPOSE },
  329. { love::keyboard::Keyboard::KEY_HELP, SDLK_HELP },
  330. { love::keyboard::Keyboard::KEY_PRINT, SDLK_PRINT },
  331. { love::keyboard::Keyboard::KEY_SYSREQ, SDLK_SYSREQ },
  332. { love::keyboard::Keyboard::KEY_BREAK, SDLK_BREAK },
  333. { love::keyboard::Keyboard::KEY_MENU, SDLK_MENU },
  334. { love::keyboard::Keyboard::KEY_POWER, SDLK_POWER },
  335. { love::keyboard::Keyboard::KEY_EURO, SDLK_EURO },
  336. { love::keyboard::Keyboard::KEY_UNDO, SDLK_UNDO },
  337. { love::keyboard::Keyboard::KEY_UNKNOWN, SDLK_UNKNOWN },
  338. };
  339. EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> Event::keys(Event::keyEntries, sizeof(Event::keyEntries));
  340. EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry Event::buttonEntries[] =
  341. {
  342. { love::mouse::Mouse::BUTTON_LEFT, SDL_BUTTON_LEFT},
  343. { love::mouse::Mouse::BUTTON_MIDDLE, SDL_BUTTON_MIDDLE},
  344. { love::mouse::Mouse::BUTTON_RIGHT, SDL_BUTTON_RIGHT},
  345. { love::mouse::Mouse::BUTTON_WHEELUP, SDL_BUTTON_WHEELUP},
  346. { love::mouse::Mouse::BUTTON_WHEELDOWN, SDL_BUTTON_WHEELDOWN},
  347. { love::mouse::Mouse::BUTTON_X1, SDL_BUTTON_X1},
  348. { love::mouse::Mouse::BUTTON_X2, SDL_BUTTON_X2},
  349. };
  350. EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries));
  351. EnumMap<love::joystick::Joystick::Hat, Uint8, love::joystick::Joystick::HAT_MAX_ENUM>::Entry Event::hatEntries[] =
  352. {
  353. {love::joystick::Joystick::HAT_CENTERED, SDL_HAT_CENTERED},
  354. {love::joystick::Joystick::HAT_UP, SDL_HAT_UP},
  355. {love::joystick::Joystick::HAT_RIGHT, SDL_HAT_RIGHT},
  356. {love::joystick::Joystick::HAT_DOWN, SDL_HAT_DOWN},
  357. {love::joystick::Joystick::HAT_LEFT, SDL_HAT_LEFT},
  358. {love::joystick::Joystick::HAT_RIGHTUP, SDL_HAT_RIGHTUP},
  359. {love::joystick::Joystick::HAT_RIGHTDOWN, SDL_HAT_RIGHTDOWN},
  360. {love::joystick::Joystick::HAT_LEFTUP, SDL_HAT_LEFTUP},
  361. {love::joystick::Joystick::HAT_LEFTDOWN, SDL_HAT_LEFTDOWN},
  362. };
  363. EnumMap<love::joystick::Joystick::Hat, Uint8, love::joystick::Joystick::HAT_MAX_ENUM> Event::hats(Event::hatEntries, sizeof(Event::hatEntries));
  364. } // sdl
  365. } // event
  366. } // love