glue.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /*
  2. Copyright (c) 2014-2018 Bruce A Henderson
  3. This software is provided 'as-is', without any express or implied
  4. warranty. In no event will the authors be held liable for any damages
  5. arising from the use of this software.
  6. Permission is granted to anyone to use this software for any purpose,
  7. including commercial applications, and to alter it and redistribute it
  8. freely, subject to the following restrictions:
  9. 1. The origin of this software must not be misrepresented; you must not
  10. claim that you wrote the original software. If you use this software
  11. in a product, an acknowledgment in the product documentation would be
  12. appreciated but is not required.
  13. 2. Altered source versions must be plainly marked as such, and must not be
  14. misrepresented as being the original software.
  15. 3. This notice may not be removed or altered from any source
  16. distribution.
  17. */
  18. #include "SDL.h"
  19. #include "SDL_events.h"
  20. #include "SDL_keyboard.h"
  21. #include <brl.mod/blitz.mod/blitz.h>
  22. #include <brl.mod/event.mod/event.h> //event enums
  23. #include <brl.mod/keycodes.mod/keycodes.h> //keycode enums
  24. /* System stuff */
  25. int brl_event_EmitEvent( BBObject *event );
  26. BBObject *brl_event_CreateEvent( int id,BBObject *source,int data,int mods,int x,int y,BBObject *extra );
  27. int sdl_sdlsystem_TSDLSystemDriver__eventFilter(BBObject * userdata, int eventType);
  28. BBObject * sdl_sdlsystem_TSDLMultiGesture__getGesture(BBLONG touchId, int x, int y, float dTheta, float dDist, int numFingers);
  29. void sdl_sdlsystem_TSDLMultiGesture__freeGesture(BBObject * gesture);
  30. void bbSDLSystemEmitEvent( int id,BBObject *source,int data,int mods,int x,int y,BBObject *extra ){
  31. BBObject *event=brl_event_CreateEvent( id,source,data,mods,x,y,extra );
  32. brl_event_EmitEvent( event );
  33. }
  34. int mapkey(SDL_Scancode scancode);
  35. int mapmods(int keymods);
  36. int bmx_SDL_GetDisplayWidth(int display) {
  37. SDL_DisplayMode mode;
  38. SDL_GetCurrentDisplayMode(display, &mode);
  39. return mode.w;
  40. }
  41. int bmx_SDL_GetDisplayHeight(int display) {
  42. SDL_DisplayMode mode;
  43. SDL_GetCurrentDisplayMode(display, &mode);
  44. return mode.h;
  45. }
  46. int bmx_SDL_GetDisplayDepth(int display) {
  47. SDL_DisplayMode mode;
  48. SDL_GetCurrentDisplayMode(display, &mode);
  49. return mode.format; // TODO - make this a proper bit depth number
  50. }
  51. int bmx_SDL_GetDisplayhertz(int display) {
  52. SDL_DisplayMode mode;
  53. SDL_GetCurrentDisplayMode(display, &mode);
  54. return mode.refresh_rate;
  55. }
  56. void bmx_SDL_EmitSDLEvent( SDL_Event *event, BBObject *source ) {
  57. int data = 0;
  58. int mods = 0;
  59. int i = 0;
  60. switch (event->type) {
  61. case SDL_QUIT:
  62. bbSDLSystemEmitEvent(BBEVENT_APPTERMINATE, source, 0, 0, 0, 0, &bbNullObject);
  63. return;
  64. case SDL_KEYDOWN:
  65. i = 0;
  66. // some keys are not raised as text input events..
  67. // so we will push them ourselves.
  68. switch (event->key.keysym.sym) {
  69. case SDLK_BACKSPACE:
  70. i = 0x08;
  71. break;
  72. case SDLK_DELETE:
  73. i = 0x7f;
  74. break;
  75. case SDLK_RETURN:
  76. case SDLK_RETURN2:
  77. case SDLK_KP_ENTER:
  78. i = 0x0d;
  79. break;
  80. case SDLK_ESCAPE:
  81. i = 0x1b;
  82. break;
  83. }
  84. // intentional fall-through...
  85. case SDL_KEYUP:
  86. data = mapkey(event->key.keysym.scancode);
  87. mods = mapmods(event->key.keysym.mod);
  88. if (event->key.repeat) {
  89. bbSDLSystemEmitEvent( BBEVENT_KEYREPEAT,source,data,mods,0,0,&bbNullObject );
  90. if (i) {
  91. bbSDLSystemEmitEvent( BBEVENT_KEYCHAR,source,i,0,0,0,&bbNullObject );
  92. }
  93. return;
  94. }
  95. bbSDLSystemEmitEvent( (event->type == SDL_KEYDOWN) ? BBEVENT_KEYDOWN : BBEVENT_KEYUP,source,data,mods,0,0,&bbNullObject );
  96. if (i) {
  97. bbSDLSystemEmitEvent( BBEVENT_KEYCHAR,source,i,0,0,0,&bbNullObject );
  98. }
  99. return;
  100. break;
  101. case SDL_TEXTINPUT:
  102. {
  103. BBString * s = bbStringFromUTF8String(event->text.text);
  104. while (i < s->length) {
  105. bbSDLSystemEmitEvent( BBEVENT_KEYCHAR,source,s->buf[i],0,0,0,&bbNullObject );
  106. i++;
  107. }
  108. return;
  109. }
  110. case SDL_MOUSEMOTION:
  111. bbSDLSystemEmitEvent( BBEVENT_MOUSEMOVE,source,0,0,event->motion.x,event->motion.y,&bbNullObject );
  112. return;
  113. case SDL_MOUSEBUTTONDOWN:
  114. case SDL_MOUSEBUTTONUP:
  115. bbSDLSystemEmitEvent( (event->type == SDL_MOUSEBUTTONDOWN) ? BBEVENT_MOUSEDOWN : BBEVENT_MOUSEUP,source,(event->button.button == 1) ? 1 : 5 - event->button.button,0,event->button.x,event->button.y,&bbNullObject );
  116. return;
  117. case SDL_MOUSEWHEEL:
  118. bbSDLSystemEmitEvent( BBEVENT_MOUSEWHEEL,source,(event->wheel.y < 0) ? -1 : 1,0,0,0,&bbNullObject );
  119. return;
  120. case SDL_USEREVENT:
  121. switch (event->user.code) {
  122. case BBEVENT_TIMERTICK:
  123. bbSDLSystemEmitEvent( BBEVENT_TIMERTICK,event->user.data1,(int)event->user.data2,0,0,0,&bbNullObject );
  124. return;
  125. case 0x802:
  126. brl_event_EmitEvent( event->user.data1 );
  127. return;
  128. }
  129. case SDL_FINGERMOTION:
  130. {
  131. SDL_DisplayMode mode;
  132. SDL_GetWindowDisplayMode(SDL_GL_GetCurrentWindow(), &mode);
  133. bbSDLSystemEmitEvent( BBEVENT_TOUCHMOVE, source, event->tfinger.fingerId, 0, event->tfinger.x * mode.w, event->tfinger.y * mode.h, &bbNullObject);
  134. return;
  135. }
  136. case SDL_FINGERDOWN:
  137. case SDL_FINGERUP:
  138. {
  139. SDL_DisplayMode mode;
  140. SDL_GetWindowDisplayMode(SDL_GL_GetCurrentWindow(), &mode);
  141. bbSDLSystemEmitEvent( (event->type == SDL_FINGERDOWN) ? BBEVENT_TOUCHDOWN : BBEVENT_TOUCHUP, source, event->tfinger.fingerId, 0, event->tfinger.x * mode.w, event->tfinger.y * mode.h, &bbNullObject );
  142. return;
  143. }
  144. case SDL_MULTIGESTURE:
  145. {
  146. SDL_DisplayMode mode;
  147. SDL_GetWindowDisplayMode(SDL_GL_GetCurrentWindow(), &mode);
  148. int x = event->mgesture.x * mode.w;
  149. int y = event->mgesture.y * mode.h;
  150. BBObject * gesture = sdl_sdlsystem_TSDLMultiGesture__getGesture(event->mgesture.touchId, x, y, event->mgesture.dTheta, event->mgesture.dDist, event->mgesture.numFingers);
  151. bbSDLSystemEmitEvent(BBEVENT_MULTIGESTURE, source, event->mgesture.touchId, 0, x, y, gesture);
  152. sdl_sdlsystem_TSDLMultiGesture__freeGesture(gesture);
  153. return;
  154. }
  155. case SDL_WINDOWEVENT:
  156. switch (event->window.event) {
  157. case SDL_WINDOWEVENT_FOCUS_GAINED:
  158. bbSDLSystemEmitEvent(BBEVENT_APPRESUME, source, 0, 0, 0, 0, &bbNullObject);
  159. return;
  160. case SDL_WINDOWEVENT_FOCUS_LOST:
  161. bbSDLSystemEmitEvent(BBEVENT_APPSUSPEND, source, 0, 0, 0, 0, &bbNullObject);
  162. return;
  163. case SDL_WINDOWEVENT_RESIZED:
  164. bbSDLSystemEmitEvent(BBEVENT_WINDOWSIZE, source, event->window.windowID, 0, event->window.data1, event->window.data2, &bbNullObject);
  165. return;
  166. }
  167. }
  168. }
  169. void bmx_SDL_Poll() {
  170. SDL_Event event;
  171. while (SDL_PollEvent(&event)) {
  172. bmx_SDL_EmitSDLEvent(&event, &bbNullObject);
  173. }
  174. }
  175. void bmx_SDL_WaitEvent() {
  176. SDL_Event event;
  177. if (SDL_WaitEvent(&event)) {
  178. bmx_SDL_EmitSDLEvent(&event, &bbNullObject);
  179. }
  180. }
  181. int mapkey(SDL_Scancode scancode) {
  182. switch(scancode) {
  183. case SDL_SCANCODE_BACKSPACE:
  184. return KEY_BACKSPACE;
  185. case SDL_SCANCODE_TAB:
  186. return KEY_TAB;
  187. case SDL_SCANCODE_RETURN:
  188. return KEY_ENTER;
  189. case SDL_SCANCODE_ESCAPE:
  190. return KEY_ESC;
  191. case SDL_SCANCODE_SPACE:
  192. return KEY_SPACE;
  193. case SDL_SCANCODE_PAGEUP:
  194. return KEY_PAGEUP;
  195. case SDL_SCANCODE_PAGEDOWN:
  196. return KEY_PAGEDOWN;
  197. case SDL_SCANCODE_END:
  198. return KEY_END;
  199. case SDL_SCANCODE_HOME:
  200. return KEY_HOME;
  201. case SDL_SCANCODE_LEFT:
  202. return KEY_LEFT;
  203. case SDL_SCANCODE_UP:
  204. return KEY_UP;
  205. case SDL_SCANCODE_RIGHT:
  206. return KEY_RIGHT;
  207. case SDL_SCANCODE_DOWN:
  208. return KEY_DOWN;
  209. case SDL_SCANCODE_INSERT:
  210. return KEY_INSERT;
  211. case SDL_SCANCODE_DELETE:
  212. return KEY_DELETE;
  213. case SDL_SCANCODE_0:
  214. return KEY_0;
  215. case SDL_SCANCODE_1:
  216. return KEY_1;
  217. case SDL_SCANCODE_2:
  218. return KEY_2;
  219. case SDL_SCANCODE_3:
  220. return KEY_3;
  221. case SDL_SCANCODE_4:
  222. return KEY_4;
  223. case SDL_SCANCODE_5:
  224. return KEY_5;
  225. case SDL_SCANCODE_6:
  226. return KEY_6;
  227. case SDL_SCANCODE_7:
  228. return KEY_7;
  229. case SDL_SCANCODE_8:
  230. return KEY_8;
  231. case SDL_SCANCODE_9:
  232. return KEY_9;
  233. case SDL_SCANCODE_A:
  234. return KEY_A;
  235. case SDL_SCANCODE_B:
  236. return KEY_B;
  237. case SDL_SCANCODE_C:
  238. return KEY_C;
  239. case SDL_SCANCODE_D:
  240. return KEY_D;
  241. case SDL_SCANCODE_E:
  242. return KEY_E;
  243. case SDL_SCANCODE_F:
  244. return KEY_F;
  245. case SDL_SCANCODE_G:
  246. return KEY_G;
  247. case SDL_SCANCODE_H:
  248. return KEY_H;
  249. case SDL_SCANCODE_I:
  250. return KEY_I;
  251. case SDL_SCANCODE_J:
  252. return KEY_J;
  253. case SDL_SCANCODE_K:
  254. return KEY_K;
  255. case SDL_SCANCODE_L:
  256. return KEY_L;
  257. case SDL_SCANCODE_M:
  258. return KEY_M;
  259. case SDL_SCANCODE_N:
  260. return KEY_N;
  261. case SDL_SCANCODE_O:
  262. return KEY_O;
  263. case SDL_SCANCODE_P:
  264. return KEY_P;
  265. case SDL_SCANCODE_Q:
  266. return KEY_Q;
  267. case SDL_SCANCODE_R:
  268. return KEY_R;
  269. case SDL_SCANCODE_S:
  270. return KEY_S;
  271. case SDL_SCANCODE_T:
  272. return KEY_T;
  273. case SDL_SCANCODE_U:
  274. return KEY_U;
  275. case SDL_SCANCODE_V:
  276. return KEY_V;
  277. case SDL_SCANCODE_W:
  278. return KEY_W;
  279. case SDL_SCANCODE_X:
  280. return KEY_X;
  281. case SDL_SCANCODE_Y:
  282. return KEY_Y;
  283. case SDL_SCANCODE_Z:
  284. return KEY_Z;
  285. case SDL_SCANCODE_LGUI:
  286. return KEY_LSYS;
  287. case SDL_SCANCODE_RGUI:
  288. return KEY_RSYS;
  289. case SDL_SCANCODE_KP_0:
  290. return KEY_NUM0;
  291. case SDL_SCANCODE_KP_1:
  292. return KEY_NUM1;
  293. case SDL_SCANCODE_KP_2:
  294. return KEY_NUM2;
  295. case SDL_SCANCODE_KP_3:
  296. return KEY_NUM3;
  297. case SDL_SCANCODE_KP_4:
  298. return KEY_NUM4;
  299. case SDL_SCANCODE_KP_5:
  300. return KEY_NUM5;
  301. case SDL_SCANCODE_KP_6:
  302. return KEY_NUM6;
  303. case SDL_SCANCODE_KP_7:
  304. return KEY_NUM7;
  305. case SDL_SCANCODE_KP_8:
  306. return KEY_NUM8;
  307. case SDL_SCANCODE_KP_9:
  308. return KEY_NUM9;
  309. case SDL_SCANCODE_KP_MULTIPLY:
  310. return KEY_NUMMULTIPLY;
  311. case SDL_SCANCODE_KP_PLUS:
  312. return KEY_NUMADD;
  313. case SDL_SCANCODE_KP_EQUALS:
  314. return KEY_NUMSLASH;
  315. case SDL_SCANCODE_KP_MINUS:
  316. return KEY_NUMSUBTRACT;
  317. case SDL_SCANCODE_KP_PERIOD:
  318. return KEY_NUMDECIMAL;
  319. case SDL_SCANCODE_KP_DIVIDE:
  320. return KEY_NUMDIVIDE;
  321. case SDL_SCANCODE_F1:
  322. return KEY_F1;
  323. case SDL_SCANCODE_F2:
  324. return KEY_F2;
  325. case SDL_SCANCODE_F3:
  326. return KEY_F3;
  327. case SDL_SCANCODE_F4:
  328. return KEY_F4;
  329. case SDL_SCANCODE_F5:
  330. return KEY_F5;
  331. case SDL_SCANCODE_F6:
  332. return KEY_F6;
  333. case SDL_SCANCODE_F7:
  334. return KEY_F7;
  335. case SDL_SCANCODE_F8:
  336. return KEY_F8;
  337. case SDL_SCANCODE_F9:
  338. return KEY_F9;
  339. case SDL_SCANCODE_F10:
  340. return KEY_F10;
  341. case SDL_SCANCODE_F11:
  342. return KEY_F11;
  343. case SDL_SCANCODE_F12:
  344. return KEY_F12;
  345. case SDL_SCANCODE_LSHIFT:
  346. return KEY_LSHIFT;
  347. case SDL_SCANCODE_RSHIFT:
  348. return KEY_RSHIFT;
  349. case SDL_SCANCODE_LCTRL:
  350. return KEY_LCONTROL;
  351. case SDL_SCANCODE_RCTRL:
  352. return KEY_RCONTROL;
  353. case SDL_SCANCODE_LALT:
  354. return KEY_LALT;
  355. case SDL_SCANCODE_RALT:
  356. return KEY_RALT;
  357. case SDL_SCANCODE_AC_BACK:
  358. return KEY_BROWSER_BACK;
  359. case SDL_SCANCODE_AC_FORWARD:
  360. return KEY_BROWSER_FORWARD;
  361. case SDL_SCANCODE_AC_HOME:
  362. return KEY_BROWSER_HOME;
  363. case SDL_SCANCODE_AC_REFRESH:
  364. return KEY_BROWSER_REFRESH;
  365. case SDL_SCANCODE_AC_SEARCH:
  366. return KEY_BROWSER_SEARCH;
  367. case SDL_SCANCODE_AC_STOP:
  368. return KEY_BROWSER_STOP;
  369. case SDL_SCANCODE_GRAVE:
  370. return KEY_TILDE;
  371. case SDL_SCANCODE_MINUS:
  372. return KEY_MINUS;
  373. case SDL_SCANCODE_EQUALS:
  374. return KEY_EQUALS;
  375. case SDL_SCANCODE_LEFTBRACKET:
  376. return KEY_OPENBRACKET;
  377. case SDL_SCANCODE_RIGHTBRACKET:
  378. return KEY_CLOSEBRACKET;
  379. case SDL_SCANCODE_BACKSLASH:
  380. return KEY_BACKSLASH;
  381. case SDL_SCANCODE_SEMICOLON:
  382. return KEY_SEMICOLON;
  383. case SDL_SCANCODE_APOSTROPHE:
  384. return KEY_QUOTES;
  385. case SDL_SCANCODE_COMMA:
  386. return KEY_COMMA;
  387. case SDL_SCANCODE_PERIOD:
  388. return KEY_PERIOD;
  389. case SDL_SCANCODE_SLASH:
  390. return KEY_SLASH;
  391. }
  392. return scancode;
  393. }
  394. int mapmods(int keymods) {
  395. int mod = 0;
  396. if (keymods & KMOD_SHIFT) {
  397. mod |= MODIFIER_SHIFT;
  398. }
  399. if (keymods & KMOD_CTRL) {
  400. mod |= MODIFIER_CONTROL;
  401. }
  402. if (keymods & KMOD_ALT) {
  403. mod |= MODIFIER_OPTION;
  404. }
  405. if (keymods & KMOD_GUI) {
  406. mod |= MODIFIER_SYSTEM;
  407. }
  408. return mod;
  409. }
  410. int bmx_SDL_ShowSimpleMessageBox(BBString * text, BBString * appTitle, int serious) {
  411. int flags = (serious) ? SDL_MESSAGEBOX_WARNING : SDL_MESSAGEBOX_INFORMATION;
  412. char * t = bbStringToUTF8String(appTitle);
  413. char * s = bbStringToUTF8String(text);
  414. int ret = SDL_ShowSimpleMessageBox(flags, t, s, NULL);
  415. bbMemFree(s);
  416. bbMemFree(t);
  417. return ret;
  418. }
  419. int bmx_SDL_ShowMessageBox_confirm(BBString * text, BBString * appTitle, int serious) {
  420. char * t = bbStringToUTF8String(appTitle);
  421. char * s = bbStringToUTF8String(text);
  422. SDL_MessageBoxButtonData buttons[] = {
  423. { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 0, "no" },
  424. { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "yes" }
  425. };
  426. SDL_MessageBoxData messageboxdata = {
  427. (serious) ? SDL_MESSAGEBOX_WARNING : SDL_MESSAGEBOX_INFORMATION,
  428. NULL, t, s, SDL_arraysize(buttons), buttons, NULL
  429. };
  430. bbMemFree(s);
  431. bbMemFree(t);
  432. int buttonid;
  433. SDL_ShowMessageBox(&messageboxdata, &buttonid);
  434. if (buttonid == 1) {
  435. return 1;
  436. } else {
  437. return 0;
  438. }
  439. }
  440. int bmx_SDL_ShowMessageBox_proceed(BBString * text, BBString * appTitle, int serious) {
  441. char * t = bbStringToUTF8String(appTitle);
  442. char * s = bbStringToUTF8String(text);
  443. SDL_MessageBoxButtonData buttons[] = {
  444. { 0, 0, "no" },
  445. { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "yes" },
  446. { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "cancel" }
  447. };
  448. SDL_MessageBoxData messageboxdata = {
  449. (serious) ? SDL_MESSAGEBOX_WARNING : SDL_MESSAGEBOX_INFORMATION,
  450. NULL, t, s, SDL_arraysize(buttons), buttons, NULL
  451. };
  452. bbMemFree(s);
  453. bbMemFree(t);
  454. int buttonid;
  455. SDL_ShowMessageBox(&messageboxdata, &buttonid);
  456. switch (buttonid) {
  457. case 0: return 0;
  458. case 1: return 1;
  459. }
  460. return -1;
  461. }
  462. int bmx_SDL_EventFilter(void * userdata, SDL_Event * event) {
  463. switch (event->type) {
  464. case SDL_APP_TERMINATING:
  465. case SDL_APP_LOWMEMORY:
  466. case SDL_APP_WILLENTERBACKGROUND:
  467. case SDL_APP_DIDENTERBACKGROUND:
  468. case SDL_APP_WILLENTERFOREGROUND:
  469. case SDL_APP_DIDENTERFOREGROUND:
  470. return sdl_sdlsystem_TSDLSystemDriver__eventFilter(userdata, event->type);
  471. }
  472. return 1;
  473. }
  474. void bmx_SDL_SetEventFilter(BBObject * obj) {
  475. SDL_SetEventFilter(bmx_SDL_EventFilter, obj);
  476. }