nacl.patch 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. diff --git a/configure.in b/configure.in
  2. index ab0e314..c7ae13b 100644
  3. --- a/configure.in
  4. +++ b/configure.in
  5. @@ -957,7 +957,7 @@ AC_HELP_STRING([--enable-naclvideo], [enable the nacl video driver [[default=yes
  6. AC_DEFINE(SDL_VIDEO_DRIVER_NACL)
  7. SOURCES="$SOURCES $srcdir/src/video/nacl/*.c"
  8. EXTRA_LDFLAGS="-lppapi_simple -l${NACL_CXX_LIB:-stdc++} $EXTRA_LDFLAGS"
  9. - SDL_LIBS="-Wl,-unacl_main -Wl,-undefined=PSUserMainGet -lSDLmain $SDL_LIBS -lppapi_gles2 -lcli_main -lnacl_spawn -ltar -lppapi_simple -lnacl_io -lppapi -lm -l${NACL_CXX_LIB:-stdc++}"
  10. + SDL_LIBS="-lSDLmain $SDL_LIBS -lppapi_gles2 -lcli_main -lnacl_spawn -ltar -lppapi_simple_cpp -lnacl_io -lppapi -lm -l${NACL_CXX_LIB:-stdc++} -lppapi_cpp"
  11. SDL_CFLAGS="$SDL_CFLAGS -Dmain=SDL_main"
  12. fi
  13. @@ -2449,7 +2449,7 @@ case "$host" in
  14. have_timers=yes
  15. fi
  16. CheckPTHREAD
  17. - SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.c"
  18. + SDLMAIN_SOURCES="$srcdir/src/main/nacl/*.cc"
  19. ;;
  20. *-*-linux*|*-*-uclinux*|*-*-gnu*|*-*-k*bsd*-gnu|*-*-bsdi*|*-*-freebsd*|*-*-dragonfly*|*-*-netbsd*|*-*-openbsd*|*-*-sysv5*|*-*-solaris*|*-*-hpux*|*-*-irix*|*-*-aix*|*-*-osf*)
  21. case "$host" in
  22. diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
  23. index 5753927..da37fe6 100644
  24. --- a/src/events/SDL_keyboard.c
  25. +++ b/src/events/SDL_keyboard.c
  26. @@ -371,6 +371,13 @@ Uint8 * SDL_GetKeyState (int *numkeys)
  27. *numkeys = SDLK_LAST;
  28. return(SDL_KeyState);
  29. }
  30. +
  31. +// private (used in naclevents.c)
  32. +void SDL_SetKeyState (SDLKey key, Uint8 state)
  33. +{
  34. + SDL_KeyState[key] = state;
  35. +}
  36. +
  37. SDLMod SDL_GetModState (void)
  38. {
  39. return(SDL_ModState);
  40. diff --git a/src/main/nacl/SDL_nacl_main.c b/src/main/nacl/SDL_nacl_main.c
  41. deleted file mode 100644
  42. index ef26120..0000000
  43. --- a/src/main/nacl/SDL_nacl_main.c
  44. +++ /dev/null
  45. @@ -1,125 +0,0 @@
  46. -/*
  47. - Simple DirectMedia Layer
  48. - Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
  49. -
  50. - This software is provided 'as-is', without any express or implied
  51. - warranty. In no event will the authors be held liable for any damages
  52. - arising from the use of this software.
  53. -
  54. - Permission is granted to anyone to use this software for any purpose,
  55. - including commercial applications, and to alter it and redistribute it
  56. - freely, subject to the following restrictions:
  57. -
  58. - 1. The origin of this software must not be misrepresented; you must not
  59. - claim that you wrote the original software. If you use this software
  60. - in a product, an acknowledgment in the product documentation would be
  61. - appreciated but is not required.
  62. - 2. Altered source versions must be plainly marked as such, and must not be
  63. - misrepresented as being the original software.
  64. - 3. This notice may not be removed or altered from any source distribution.
  65. -*/
  66. -#include "SDL_config.h"
  67. -
  68. -#if SDL_VIDEO_DRIVER_NACL
  69. -
  70. -/* Include the SDL main definition header */
  71. -#include "SDL_main.h"
  72. -#include "../../SDL_trace.h"
  73. -
  74. -#include <errno.h>
  75. -#include <ppapi_simple/ps_main.h>
  76. -#include <ppapi_simple/ps_event.h>
  77. -#include <ppapi_simple/ps_interface.h>
  78. -#include <nacl_io/nacl_io.h>
  79. -#include <sys/mount.h>
  80. -#include <nacl_main.h>
  81. -#include <unistd.h>
  82. -
  83. -extern void NACL_SetScreenResolution(int width, int height);
  84. -
  85. -static int
  86. -ProcessArgs(int argc, char** argv) {
  87. - const char* arg = getenv("SDL_TAR_EXTRACT");
  88. - if (arg != NULL) {
  89. - const char* source;
  90. - const char* target = "/";
  91. - char* sep;
  92. - char buf[64];
  93. - int n;
  94. -
  95. - const char* q, *p = arg;
  96. - while (*p) {
  97. - while (*p && isspace((unsigned char)*p)) ++p;
  98. - if (!*p) break;
  99. - q = p;
  100. - while (*p && !isspace((unsigned char)*p)) ++p;
  101. -
  102. - n = sizeof(buf) - 1;
  103. - if (p - q < n) n = p - q;
  104. - strncpy(buf, q, n);
  105. - buf[n] = '\0';
  106. -
  107. - sep = strchr(buf, ':');
  108. - source = buf;
  109. - if (sep) {
  110. - target = sep + 1;
  111. - *sep = '\0';
  112. - }
  113. -
  114. - SDL_log("extracting tar file '%s' -> '%s'\n", source, target);
  115. - if (nacl_startup_untar(argv[0], source, target) != 0)
  116. - return 1;
  117. - }
  118. - }
  119. -
  120. - return 0;
  121. -}
  122. -
  123. -/* This is started in a worker thread by ppapi_simple! */
  124. -int
  125. -nacl_main(int argc, char *argv[])
  126. -{
  127. - SDL_TRACE("nacl_main\n");
  128. - PSEvent* ps_event;
  129. - PP_Resource event;
  130. - struct PP_Rect rect;
  131. - int ready = 0;
  132. - const PPB_View *ppb_view = PSInterfaceView();
  133. -
  134. - if (ProcessArgs(argc, argv) != 0) {
  135. - return 1;
  136. - }
  137. -
  138. - /* Wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before starting the app */
  139. - PSEventSetFilter(PSE_INSTANCE_DIDCHANGEVIEW);
  140. - /* Process all waiting events without blocking */
  141. - while (!ready) {
  142. - ps_event = PSEventWaitAcquire();
  143. - event = ps_event->as_resource;
  144. - switch(ps_event->type) {
  145. - /* From DidChangeView, contains a view resource */
  146. - case PSE_INSTANCE_DIDCHANGEVIEW:
  147. - ppb_view->GetRect(event, &rect);
  148. - NACL_SetScreenResolution(rect.size.width, rect.size.height);
  149. - ready = 1;
  150. - break;
  151. - default:
  152. - break;
  153. - }
  154. - PSEventRelease(ps_event);
  155. - }
  156. -
  157. - /*
  158. - * Startup in /mnt/http by default so resources hosted on the webserver
  159. - * are accessible in the current working directory.
  160. - */
  161. - if (getenv("PWD") == NULL) {
  162. - if (chdir("/mnt/http") != 0) {
  163. - SDL_log("chdir to /mnt/http failed: %s\n", strerror(errno));
  164. - }
  165. - }
  166. -
  167. - return SDL_main(argc, argv);
  168. -}
  169. -
  170. -#endif /* SDL_VIDEO_DRIVER_NACL */
  171. diff --git a/src/main/nacl/SDL_nacl_main.cc b/src/main/nacl/SDL_nacl_main.cc
  172. new file mode 100644
  173. index 0000000..ee80b9a
  174. --- /dev/null
  175. +++ b/src/main/nacl/SDL_nacl_main.cc
  176. @@ -0,0 +1,129 @@
  177. +/*
  178. + Simple DirectMedia Layer
  179. + Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
  180. +
  181. + This software is provided 'as-is', without any express or implied
  182. + warranty. In no event will the authors be held liable for any damages
  183. + arising from the use of this software.
  184. +
  185. + Permission is granted to anyone to use this software for any purpose,
  186. + including commercial applications, and to alter it and redistribute it
  187. + freely, subject to the following restrictions:
  188. +
  189. + 1. The origin of this software must not be misrepresented; you must not
  190. + claim that you wrote the original software. If you use this software
  191. + in a product, an acknowledgment in the product documentation would be
  192. + appreciated but is not required.
  193. + 2. Altered source versions must be plainly marked as such, and must not be
  194. + misrepresented as being the original software.
  195. + 3. This notice may not be removed or altered from any source distribution.
  196. +*/
  197. +#include "SDL_config.h"
  198. +
  199. +#if SDL_VIDEO_DRIVER_NACL
  200. +
  201. +/* Include the SDL main definition header */
  202. +#include "SDL_main.h"
  203. +#include "../../SDL_trace.h"
  204. +
  205. +#include <errno.h>
  206. +#include <ppapi_simple/ps_main.h>
  207. +#include <ppapi_simple/ps_event.h>
  208. +#include <ppapi_simple/ps_interface.h>
  209. +#include <nacl_io/nacl_io.h>
  210. +#include <sys/mount.h>
  211. +#include <nacl_main.h>
  212. +#include <unistd.h>
  213. +
  214. +extern "C" void NACL_SetScreenResolution(int width, int height);
  215. +
  216. +static int
  217. +ProcessArgs(int argc, char** argv) {
  218. + const char* arg = getenv("SDL_TAR_EXTRACT");
  219. + if (arg != NULL) {
  220. + const char* source;
  221. + const char* target = "/";
  222. + char* sep;
  223. + char buf[64];
  224. + int n;
  225. +
  226. + const char* q, *p = arg;
  227. + while (*p) {
  228. + while (*p && isspace((unsigned char)*p)) ++p;
  229. + if (!*p) break;
  230. + q = p;
  231. + while (*p && !isspace((unsigned char)*p)) ++p;
  232. +
  233. + n = sizeof(buf) - 1;
  234. + if (p - q < n) n = p - q;
  235. + strncpy(buf, q, n);
  236. + buf[n] = '\0';
  237. +
  238. + sep = strchr(buf, ':');
  239. + source = buf;
  240. + if (sep) {
  241. + target = sep + 1;
  242. + *sep = '\0';
  243. + }
  244. +
  245. + SDL_log("extracting tar file '%s' -> '%s'\n", source, target);
  246. + if (nacl_startup_untar(argv[0], source, target) != 0)
  247. + return 1;
  248. + }
  249. + }
  250. +
  251. + return 0;
  252. +}
  253. +
  254. +#undef main
  255. +
  256. +/* This is started in a worker thread by ppapi_simple! */
  257. +int
  258. +main(int argc, char *argv[])
  259. +{
  260. + SDL_TRACE("main\n");
  261. + PSEvent* ps_event;
  262. + PP_Resource event;
  263. + struct PP_Rect rect;
  264. + int ready = 0;
  265. + const PPB_View *ppb_view = PSInterfaceView();
  266. +
  267. + if (ProcessArgs(argc, argv) != 0) {
  268. + return 1;
  269. + }
  270. +
  271. + /* Wait for the first PSE_INSTANCE_DIDCHANGEVIEW event before starting the app */
  272. + PSEventSetFilter(PSE_INSTANCE_DIDCHANGEVIEW);
  273. + /* Process all waiting events without blocking */
  274. + while (!ready) {
  275. + ps_event = PSEventWaitAcquire();
  276. + event = ps_event->as_resource;
  277. + switch(ps_event->type) {
  278. + /* From DidChangeView, contains a view resource */
  279. + case PSE_INSTANCE_DIDCHANGEVIEW:
  280. + ppb_view->GetRect(event, &rect);
  281. + NACL_SetScreenResolution(rect.size.width, rect.size.height);
  282. + ready = 1;
  283. + break;
  284. + default:
  285. + break;
  286. + }
  287. + PSEventRelease(ps_event);
  288. + }
  289. +
  290. + mount("", /* source */
  291. + "/persistent", /* target */
  292. + "html5fs", /* filesystemtype */
  293. + 0, /* mountflags */
  294. + "type=PERSISTENT,expected_size=1048576"); /* data */
  295. +
  296. + mount("", /* source. Use relative URL */
  297. + "/http", /* target */
  298. + "httpfs", /* filesystemtype */
  299. + 0, /* mountflags */
  300. + ""); /* data */
  301. +
  302. + return SDL_main(argc, argv);
  303. +}
  304. +
  305. +#endif /* SDL_VIDEO_DRIVER_NACL */
  306. diff --git a/src/video/nacl/SDL_naclevents.c b/src/video/nacl/SDL_naclevents.c
  307. index a2f7e19..a97134f 100644
  308. --- a/src/video/nacl/SDL_naclevents.c
  309. +++ b/src/video/nacl/SDL_naclevents.c
  310. @@ -29,6 +29,7 @@
  311. #include <math.h>
  312. #include <ppapi_simple/ps_event.h>
  313. +#include <ppapi/c/ppb_input_event.h>
  314. #define PPAPI_KEY_CTRL 17
  315. #define PPAPI_KEY_ALT 18
  316. @@ -176,12 +177,85 @@ static SDLKey translateKey(uint32_t code) {
  317. }
  318. }
  319. +static SDL_bool SDL_NeedModUpdate = SDL_TRUE;
  320. +
  321. +static int Utf8ToUtf16(const Uint8 *utf8, const int utf8_length, Uint16 *utf16, const int utf16_max_length) {
  322. +
  323. + /* p moves over the output buffer. max_ptr points to the next to the last slot of the buffer. */
  324. + Uint16 *p = utf16;
  325. + Uint16 const *const max_ptr = utf16 + utf16_max_length;
  326. +
  327. + /* end_of_input points to the last byte of input as opposed to the next to the last byte. */
  328. + Uint8 const *const end_of_input = utf8 + utf8_length - 1;
  329. +
  330. + while (utf8 <= end_of_input) {
  331. + Uint8 const c = *utf8;
  332. + if (p >= max_ptr) {
  333. + /* No more output space. */
  334. + return -1;
  335. + }
  336. + if (c < 0x80) {
  337. + /* One byte ASCII. */
  338. + *p++ = c;
  339. + utf8 += 1;
  340. + } else if (c < 0xC0) {
  341. + /* Follower byte without preceeding leader bytes. */
  342. + return -1;
  343. + } else if (c < 0xE0) {
  344. + /* Two byte sequence. We need one follower byte. */
  345. + if (end_of_input - utf8 < 1 || (((utf8[1] ^ 0x80)) & 0xC0)) {
  346. + return -1;
  347. + }
  348. + *p++ = (Uint16)(0xCF80 + (c << 6) + utf8[1]);
  349. + utf8 += 2;
  350. + } else if (c < 0xF0) {
  351. + /* Three byte sequence. We need two follower byte. */
  352. + if (end_of_input - utf8 < 2 || (((utf8[1] ^ 0x80) | (utf8[2] ^ 0x80)) & 0xC0)) {
  353. + return -1;
  354. + }
  355. + *p++ = (Uint16)(0xDF80 + (c << 12) + (utf8[1] << 6) + utf8[2]);
  356. + utf8 += 3;
  357. + } else if (c < 0xF8) {
  358. + int plane;
  359. + /* Four byte sequence. We need three follower bytes. */
  360. + if (end_of_input - utf8 < 3 || (((utf8[1] ^ 0x80) | (utf8[2] ^0x80) | (utf8[3] ^ 0x80)) & 0xC0)) {
  361. + return -1;
  362. + }
  363. + plane = (-0xC8 + (c << 2) + (utf8[1] >> 4));
  364. + if (plane == 0) {
  365. + /* This four byte sequence is an alias that
  366. + corresponds to a Unicode scalar value in BMP.
  367. + It fits in an UTF-16 encoding unit. */
  368. + *p++ = (Uint16)(0xDF80 + (utf8[1] << 12) + (utf8[2] << 6) + utf8[3]);
  369. + } else if (plane <= 16) {
  370. + /* This is a legal four byte sequence that corresponds to a surrogate pair. */
  371. + if (p + 1 >= max_ptr) {
  372. + /* No enough space on the output buffer for the pair. */
  373. + return -1;
  374. + }
  375. + *p++ = (Uint16)(0xE5B8 + (c << 8) + (utf8[1] << 2) + (utf8[2] >> 4));
  376. + *p++ = (Uint16)(0xDB80 + ((utf8[2] & 0x0F) << 6) + utf8[3]);
  377. + } else {
  378. + /* This four byte sequence is out of UTF-16 code space. */
  379. + return -1;
  380. + }
  381. + utf8 += 4;
  382. + } else {
  383. + /* Longer sequence or unused byte. */
  384. + return -1;
  385. + }
  386. + }
  387. + return p - utf16;
  388. +}
  389. +
  390. +
  391. void HandleInputEvent(_THIS, PP_Resource event) {
  392. static Uint8 last_scancode = 0;
  393. static int alt_down = 0;
  394. static int ctrl_down = 0;
  395. PP_InputEvent_Type type;
  396. PP_InputEvent_Modifier modifiers;
  397. + SDLMod sdl_mod;
  398. Uint8 button;
  399. Uint8 state;
  400. Uint8 gained;
  401. @@ -197,9 +271,49 @@ void HandleInputEvent(_THIS, PP_Resource event) {
  402. int sdl_wheel_clicks_y;
  403. int i;
  404. + // defining modifiers array for conversion
  405. + static const size_t modcnt = 6;
  406. + static const int ppapi_mods[modcnt] = {
  407. + PP_INPUTEVENT_MODIFIER_SHIFTKEY,
  408. + PP_INPUTEVENT_MODIFIER_CONTROLKEY,
  409. + PP_INPUTEVENT_MODIFIER_ALTKEY,
  410. + PP_INPUTEVENT_MODIFIER_METAKEY,
  411. + PP_INPUTEVENT_MODIFIER_CAPSLOCKKEY,
  412. + PP_INPUTEVENT_MODIFIER_NUMLOCKKEY
  413. + };
  414. + static const SDLMod sdl_mods[modcnt] = {
  415. + KMOD_LSHIFT,
  416. + KMOD_LCTRL,
  417. + KMOD_LALT,
  418. + KMOD_LMETA,
  419. + KMOD_CAPS,
  420. + KMOD_NUM
  421. + };
  422. + static const SDLKey sdl_keys[modcnt] = {
  423. + SDLK_LSHIFT,
  424. + SDLK_LCTRL,
  425. + SDLK_LALT,
  426. + SDLK_LMETA,
  427. + SDLK_CAPSLOCK,
  428. + SDLK_NUMLOCK
  429. + };
  430. + static const SDLKey sdl_rkeys[modcnt] = {
  431. + SDLK_RSHIFT,
  432. + SDLK_RCTRL,
  433. + SDLK_RALT,
  434. + SDLK_RMETA,
  435. + SDLK_CAPSLOCK,
  436. + SDLK_NUMLOCK
  437. + };
  438. +
  439. type = dd->ppb_input_event->GetType(event);
  440. modifiers = dd->ppb_input_event->GetModifiers(event);
  441. + // alt_down and ctrl_down correction
  442. + // needed when one of these keys were pressed outside of the module
  443. + alt_down = modifiers & PP_INPUTEVENT_MODIFIER_ALTKEY ? 1 : 0;
  444. + ctrl_down = modifiers & PP_INPUTEVENT_MODIFIER_CONTROLKEY ? 1 : 0;
  445. +
  446. switch (type) {
  447. case PP_INPUTEVENT_TYPE_MOUSEDOWN:
  448. case PP_INPUTEVENT_TYPE_MOUSEUP:
  449. @@ -216,13 +330,13 @@ void HandleInputEvent(_THIS, PP_Resource event) {
  450. sdl_wheel_clicks_y = trunc(wheel_clicks_y);
  451. button = (sdl_wheel_clicks_x > 0) ? SDL_BUTTON_X1 : SDL_BUTTON_X2;
  452. for (i = 0; i < abs(sdl_wheel_clicks_x); i++) {
  453. - SDL_PrivateMouseButton(SDL_MOUSEBUTTONDOWN, button, 0, 0);
  454. - SDL_PrivateMouseButton(SDL_MOUSEBUTTONUP, button, 0, 0);
  455. + SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0);
  456. + SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0);
  457. }
  458. button = (sdl_wheel_clicks_y > 0) ? SDL_BUTTON_WHEELUP : SDL_BUTTON_WHEELDOWN;
  459. for (i = 0; i < abs(sdl_wheel_clicks_y); i++) {
  460. - SDL_PrivateMouseButton(SDL_MOUSEBUTTONDOWN, button, 0, 0);
  461. - SDL_PrivateMouseButton(SDL_MOUSEBUTTONUP, button, 0, 0);
  462. + SDL_PrivateMouseButton(SDL_PRESSED, button, 0, 0);
  463. + SDL_PrivateMouseButton(SDL_RELEASED, button, 0, 0);
  464. }
  465. wheel_clicks_x -= sdl_wheel_clicks_x;
  466. wheel_clicks_y -= sdl_wheel_clicks_y;
  467. @@ -259,7 +373,12 @@ void HandleInputEvent(_THIS, PP_Resource event) {
  468. // It seems that SDL 1.3 is better in this regard.
  469. keysym.scancode = dd->ppb_keyboard_input_event->GetKeyCode(event);
  470. unicode_var = dd->ppb_keyboard_input_event->GetCharacterText(event);
  471. - keysym.unicode = dd->ppb_var->VarToUtf8(unicode_var, &unicode_var_len)[0];
  472. + const Uint8 *utf8_buf = dd->ppb_var->VarToUtf8(unicode_var, &unicode_var_len);
  473. +
  474. + Uint8 utf16_buf[10];
  475. + Utf8ToUtf16(utf8_buf, unicode_var_len, (Uint16*)&utf16_buf[0], 1);
  476. + keysym.unicode = *(Uint16*)&utf16_buf[0];
  477. +
  478. dd->ppb_var->Release(unicode_var);
  479. keysym.sym = translateKey(keysym.scancode);
  480. @@ -318,6 +437,34 @@ void HandleInputEvent(_THIS, PP_Resource event) {
  481. state = SDL_RELEASED;
  482. last_scancode = 0;
  483. }
  484. +
  485. + if (SDL_NeedModUpdate) {
  486. + // copying keyboard modifiers from PPAPI
  487. + sdl_mod = KMOD_NONE;
  488. + for (i = 0; i < modcnt; ++i) {
  489. + if (sdl_keys[i] == keysym.sym) // if key is a modifier
  490. + continue; // then do not copy it
  491. + if (modifiers & ppapi_mods[i]) {
  492. + sdl_mod |= sdl_mods[i];
  493. + SDL_SetKeyState(sdl_keys[i], SDL_PRESSED);
  494. + } else {
  495. + SDL_SetKeyState(sdl_keys[i], SDL_RELEASED);
  496. + }
  497. + }
  498. + SDL_SetModState(sdl_mod);
  499. + SDL_NeedModUpdate = SDL_FALSE;
  500. + }
  501. +
  502. + if (modifiers & PP_INPUTEVENT_MODIFIER_ISRIGHT) {
  503. + // convert left modifier keycode to the right one
  504. + for (i = 0; i < modcnt; ++i) {
  505. + if (keysym.sym == sdl_keys[i]) {
  506. + keysym.sym = sdl_rkeys[i];
  507. + break;
  508. + }
  509. + }
  510. + }
  511. +
  512. keysym.mod = KMOD_NONE;
  513. SDL_TRACE("Key event: %d: %s\n", state, SDL_GetKeyName(keysym.sym));
  514. SDL_PrivateKeyboard(state, &keysym);
  515. @@ -352,6 +499,7 @@ static void HandleEvent(_THIS, PSEvent* ps_event) {
  516. /* From DidChangeFocus, contains a PP_Bool with the current focus state. */
  517. case PSE_INSTANCE_DIDCHANGEFOCUS:
  518. + SDL_NeedModUpdate = SDL_TRUE;
  519. break;
  520. /* When the 3D context is lost, no resource. */