e14743d1 |
1 | /* |
2 | SDL - Simple DirectMedia Layer |
3 | Copyright (C) 1997-2009 Sam Lantinga |
4 | |
5 | This library is free software; you can redistribute it and/or |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either |
8 | version 2.1 of the License, or (at your option) any later version. |
9 | |
10 | This library is distributed in the hope that it will be useful, |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with this library; if not, write to the Free Software |
17 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
18 | |
19 | Sam Lantinga |
20 | slouken@libsdl.org |
21 | */ |
22 | #include "SDL_config.h" |
23 | |
24 | /* Handle the event stream, converting photon events into SDL events */ |
25 | |
26 | #include <stdio.h> |
27 | #include <setjmp.h> |
28 | #include <sys/time.h> |
29 | |
30 | #include <Ph.h> |
31 | #include <photon/PkKeyDef.h> |
32 | |
33 | #include "SDL.h" |
34 | #include "SDL_syswm.h" |
35 | #include "../SDL_sysvideo.h" |
36 | #include "../../events/SDL_sysevents.h" |
37 | #include "../../events/SDL_events_c.h" |
38 | #include "SDL_ph_video.h" |
39 | #include "SDL_ph_modes_c.h" |
40 | #include "SDL_ph_image_c.h" |
41 | #include "SDL_ph_events_c.h" |
42 | #include "SDL_phyuv_c.h" |
43 | |
44 | /* The translation tables from a photon keysym to a SDL keysym */ |
45 | static SDLKey ODD_keymap[256]; |
46 | static SDLKey MISC_keymap[0xFF + 1]; |
47 | SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym); |
48 | |
49 | /* Check to see if this is a repeated key. |
50 | (idea shamelessly lifted from GII -- thanks guys! :) */ |
51 | static int ph_WarpedMotion(_THIS, PhEvent_t *winEvent) |
52 | { |
53 | PhRect_t *rect = PhGetRects( winEvent ); |
54 | |
55 | int centre_x, centre_y; |
56 | int dx, dy; |
57 | short abs_x, abs_y; |
58 | int posted; |
59 | |
60 | centre_x = SDL_VideoSurface->w / 2; |
61 | centre_y = SDL_VideoSurface->h / 2; |
62 | |
63 | dx = rect->ul.x - centre_x; |
64 | dy = rect->ul.y - centre_y; |
65 | |
66 | posted = SDL_PrivateMouseMotion( 0, 1, dx, dy ); |
67 | |
68 | /* Move mouse cursor to middle of the window */ |
69 | PtGetAbsPosition( window, &abs_x, &abs_y ); |
70 | PhMoveCursorAbs(PhInputGroup(NULL), abs_x + centre_x, abs_y + centre_y); |
71 | |
72 | return (posted); |
73 | } |
74 | |
75 | /* Control which motion flags the window has set, a flags value of -1 sets |
76 | * MOTION_BUTTON and MOTION_NOBUTTON */ |
77 | |
78 | static void set_motion_sensitivity(_THIS, unsigned int flags) |
79 | { |
80 | int rid; |
81 | int fields = Ph_EV_PTR_MOTION_BUTTON | Ph_EV_PTR_MOTION_NOBUTTON; |
82 | PhRegion_t region; |
83 | |
84 | if( window ) |
85 | { |
86 | rid = PtWidgetRid(window); |
87 | if( rid != 0 && PhRegionQuery(rid, ®ion, NULL, NULL, 0) == 0 ) |
88 | { |
89 | region.events_sense=(region.events_sense & ~fields)|(flags & fields); |
90 | PhRegionChange(Ph_REGION_EV_SENSE, 0, ®ion, NULL, NULL); |
91 | } |
92 | } |
93 | } |
94 | |
95 | /* Convert the photon button state value to an SDL value */ |
96 | static Uint8 ph2sdl_mousebutton(unsigned short button_state) |
97 | { |
98 | Uint8 mouse_button = 0; |
99 | |
100 | if (button_state & Ph_BUTTON_SELECT) |
101 | mouse_button |= SDL_BUTTON_LEFT; |
102 | if (button_state & Ph_BUTTON_MENU) |
103 | mouse_button |= SDL_BUTTON_RIGHT; |
104 | if (button_state & Ph_BUTTON_ADJUST) |
105 | mouse_button |= SDL_BUTTON_MIDDLE; |
106 | |
107 | return (mouse_button); |
108 | } |
109 | |
110 | static int ph_DispatchEvent(_THIS) |
111 | { |
112 | int posted; |
113 | PhRect_t* rect; |
114 | PhPointerEvent_t* pointerEvent; |
115 | PhKeyEvent_t* keyEvent; |
116 | PhWindowEvent_t* winEvent; |
117 | int i, buttons; |
118 | SDL_Rect sdlrects[PH_SDL_MAX_RECTS]; |
119 | |
120 | posted = 0; |
121 | |
122 | switch (phevent->type) |
123 | { |
124 | case Ph_EV_BOUNDARY: |
125 | { |
126 | if (phevent->subtype == Ph_EV_PTR_ENTER) |
127 | { |
128 | posted = SDL_PrivateAppActive(1, SDL_APPMOUSEFOCUS); |
129 | } |
130 | else if (phevent->subtype ==Ph_EV_PTR_LEAVE) |
131 | { |
132 | posted = SDL_PrivateAppActive(0, SDL_APPMOUSEFOCUS); |
133 | } |
134 | } |
135 | break; |
136 | |
137 | case Ph_EV_PTR_MOTION_BUTTON: |
138 | case Ph_EV_PTR_MOTION_NOBUTTON: |
139 | { |
140 | if (SDL_VideoSurface) |
141 | { |
142 | pointerEvent = PhGetData(phevent); |
143 | rect = PhGetRects(phevent); |
144 | |
145 | if (mouse_relative) |
146 | { |
147 | posted = ph_WarpedMotion(this, phevent); |
148 | } |
149 | else |
150 | { |
151 | posted = SDL_PrivateMouseMotion(0, 0, rect->ul.x, rect->ul.y); |
152 | } |
153 | } |
154 | } |
155 | break; |
156 | |
157 | case Ph_EV_BUT_PRESS: |
158 | { |
159 | pointerEvent = PhGetData(phevent); |
160 | buttons = ph2sdl_mousebutton(pointerEvent->buttons); |
161 | if (buttons != 0) |
162 | { |
163 | posted = SDL_PrivateMouseButton(SDL_PRESSED, buttons, 0, 0); |
164 | } |
165 | } |
166 | break; |
167 | |
168 | case Ph_EV_BUT_RELEASE: |
169 | { |
170 | pointerEvent = PhGetData(phevent); |
171 | buttons = ph2sdl_mousebutton(pointerEvent->buttons); |
172 | if (phevent->subtype == Ph_EV_RELEASE_REAL && buttons != 0) |
173 | { |
174 | posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0); |
175 | } |
176 | else if(phevent->subtype == Ph_EV_RELEASE_PHANTOM) |
177 | { |
178 | /* If the mouse is outside the window, |
179 | * only a phantom release event is sent, so |
180 | * check if the window doesn't have mouse focus. |
181 | * Not perfect, maybe checking the mouse button |
182 | * state for Ph_EV_BOUNDARY events would be |
183 | * better. */ |
184 | if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) == 0) |
185 | { |
186 | posted = SDL_PrivateMouseButton(SDL_RELEASED, buttons, 0, 0); |
187 | } |
188 | } |
189 | } |
190 | break; |
191 | |
192 | case Ph_EV_WM: |
193 | { |
194 | winEvent = PhGetData(phevent); |
195 | |
196 | /* losing focus */ |
197 | if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUSLOST)) |
198 | { |
199 | set_motion_sensitivity(this, Ph_EV_PTR_MOTION_BUTTON); |
200 | posted = SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS); |
201 | } |
202 | /* gaining focus */ |
203 | else if ((winEvent->event_f==Ph_WM_FOCUS) && (winEvent->event_state==Ph_WM_EVSTATE_FOCUS)) |
204 | { |
205 | set_motion_sensitivity(this, -1); |
206 | posted = SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS); |
207 | } |
208 | /* request quit */ |
209 | else if (winEvent->event_f==Ph_WM_CLOSE) |
210 | { |
211 | posted = SDL_PrivateQuit(); |
212 | } |
213 | /* request hide/unhide */ |
214 | else if (winEvent->event_f==Ph_WM_HIDE) |
215 | { |
216 | if (currently_hided) |
217 | { |
218 | /* got unhide window event */ |
219 | /* TODO: restore application's palette if in palette mode */ |
220 | currently_hided=0; |
221 | } |
222 | else |
223 | { |
224 | /* got hide window event */ |
225 | /* TODO: restore original palette if in palette mode */ |
226 | currently_hided=1; |
227 | } |
228 | } |
229 | /* request to resize */ |
230 | else if (winEvent->event_f==Ph_WM_RESIZE) |
231 | { |
232 | currently_maximized=0; |
233 | #if (_NTO_VERSION < 630) |
234 | SDL_PrivateResize(winEvent->size.w+1, winEvent->size.h+1); |
235 | #else |
236 | /* QNX 6.3.0 have this bug fixed */ |
237 | SDL_PrivateResize(winEvent->size.w, winEvent->size.h); |
238 | #endif /* _NTO_VERSION */ |
239 | } |
240 | /* request to move */ |
241 | else if (winEvent->event_f==Ph_WM_MOVE) |
242 | { |
243 | if (current_overlay!=NULL) |
244 | { |
245 | int lockedstate=current_overlay->hwdata->locked; |
246 | int chromastate=current_overlay->hwdata->ischromakey; |
247 | int error; |
248 | SDL_Rect src, dst; |
249 | |
250 | current_overlay->hwdata->locked=1; |
251 | src.x = 0; |
252 | src.y = 0; |
253 | src.w = current_overlay->w; |
254 | src.y = current_overlay->h; |
255 | dst.x=current_overlay->hwdata->CurrentViewPort.pos.x; |
256 | dst.y=current_overlay->hwdata->CurrentViewPort.pos.y; |
257 | dst.w=current_overlay->hwdata->CurrentViewPort.size.w; |
258 | dst.h=current_overlay->hwdata->CurrentViewPort.size.h; |
259 | current_overlay->hwdata->ischromakey=0; |
260 | error=ph_DisplayYUVOverlay(this, current_overlay, &src, &dst); |
261 | if (!error) |
262 | { |
263 | current_overlay->hwdata->ischromakey=chromastate; |
264 | current_overlay->hwdata->locked=lockedstate; |
265 | } |
266 | } |
267 | } |
268 | /* maximize request */ |
269 | else if (winEvent->event_f==Ph_WM_MAX) |
270 | { |
271 | /* window already moved and resized here */ |
272 | currently_maximized=1; |
273 | } |
274 | /* restore request */ |
275 | else if (winEvent->event_f==Ph_WM_RESTORE) |
276 | { |
277 | /* window already moved and resized here */ |
278 | currently_maximized=0; |
279 | } |
280 | } |
281 | break; |
282 | |
283 | /* window has been resized, moved or removed */ |
284 | case Ph_EV_EXPOSE: |
285 | { |
286 | if (phevent->num_rects!=0) |
287 | { |
288 | int numrects; |
289 | |
290 | if (SDL_VideoSurface) |
291 | { |
292 | rect = PhGetRects(phevent); |
293 | if (phevent->num_rects>PH_SDL_MAX_RECTS) |
294 | { |
295 | /* sorry, buffers underrun, we'll update only first PH_SDL_MAX_RECTS rects */ |
296 | numrects=PH_SDL_MAX_RECTS; |
297 | } |
298 | |
299 | for(i=0; i<phevent->num_rects; i++) |
300 | { |
301 | sdlrects[i].x = rect[i].ul.x; |
302 | sdlrects[i].y = rect[i].ul.y; |
303 | sdlrects[i].w = rect[i].lr.x - rect[i].ul.x + 1; |
304 | sdlrects[i].h = rect[i].lr.y - rect[i].ul.y + 1; |
305 | } |
306 | |
307 | this->UpdateRects(this, phevent->num_rects, sdlrects); |
308 | |
309 | if (current_overlay!=NULL) |
310 | { |
311 | int lockedstate=current_overlay->hwdata->locked; |
312 | int error; |
313 | SDL_Rect src, dst; |
314 | |
315 | current_overlay->hwdata->locked=1; |
316 | src.x = 0; |
317 | src.y = 0; |
318 | src.w = current_overlay->w; |
319 | src.y = current_overlay->h; |
320 | dst.x=current_overlay->hwdata->CurrentViewPort.pos.x; |
321 | dst.y=current_overlay->hwdata->CurrentViewPort.pos.y; |
322 | dst.w=current_overlay->hwdata->CurrentViewPort.size.w; |
323 | dst.h=current_overlay->hwdata->CurrentViewPort.size.h; |
324 | current_overlay->hwdata->forcedredraw=1; |
325 | error=ph_DisplayYUVOverlay(this, current_overlay, &src, &dst); |
326 | if (!error) |
327 | { |
328 | current_overlay->hwdata->forcedredraw=0; |
329 | current_overlay->hwdata->locked=lockedstate; |
330 | } |
331 | } |
332 | } |
333 | } |
334 | } |
335 | break; |
336 | |
337 | case Ph_EV_KEY: |
338 | { |
339 | SDL_keysym keysym; |
340 | |
341 | posted = 0; |
342 | |
343 | keyEvent = PhGetData(phevent); |
344 | |
345 | if (Pk_KF_Key_Down & keyEvent->key_flags) |
346 | { |
347 | /* split the wheel events from real key events */ |
348 | if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) |
349 | { |
350 | posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELUP, 0, 0); |
351 | break; |
352 | } |
353 | if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) |
354 | { |
355 | posted = SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_WHEELDOWN, 0, 0); |
356 | break; |
357 | } |
358 | posted = SDL_PrivateKeyboard(SDL_PRESSED, ph_TranslateKey(keyEvent, &keysym)); |
359 | } |
360 | else /* must be key release */ |
361 | { |
362 | /* split the wheel events from real key events */ |
363 | if ((keyEvent->key_cap==Pk_Up) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) |
364 | { |
365 | posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELUP, 0, 0); |
366 | break; |
367 | } |
368 | if ((keyEvent->key_cap==Pk_Down) && (keyEvent->key_scan==0) && ((keyEvent->key_flags & Pk_KF_Scan_Valid)==Pk_KF_Scan_Valid)) |
369 | { |
370 | posted = SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_WHEELDOWN, 0, 0); |
371 | break; |
372 | } |
373 | posted = SDL_PrivateKeyboard(SDL_RELEASED, ph_TranslateKey( keyEvent, &keysym)); |
374 | } |
375 | } |
376 | break; |
377 | |
378 | case Ph_EV_INFO: |
379 | { |
380 | if (phevent->subtype==Ph_OFFSCREEN_INVALID) |
381 | { |
382 | unsigned long* EvInfoData; |
383 | |
384 | EvInfoData=(unsigned long*)PhGetData(phevent); |
385 | |
386 | switch (*EvInfoData) |
387 | { |
388 | case Pg_VIDEO_MODE_SWITCHED: |
389 | { |
390 | } |
391 | break; |
392 | case Pg_ENTERED_DIRECT: |
393 | { |
394 | } |
395 | break; |
396 | case Pg_EXITED_DIRECT: |
397 | { |
398 | } |
399 | break; |
400 | case Pg_DRIVER_STARTED: |
401 | { |
402 | } |
403 | break; |
404 | } |
405 | } |
406 | } |
407 | break; |
408 | } |
409 | |
410 | return(posted); |
411 | } |
412 | |
413 | /* perform a blocking read if no events available */ |
414 | int ph_Pending(_THIS) |
415 | { |
416 | /* Flush the display connection and look to see if events are queued */ |
417 | PgFlush(); |
418 | |
419 | while (1) |
420 | { |
421 | switch(PhEventPeek(phevent, EVENT_SIZE)) |
422 | { |
423 | case Ph_EVENT_MSG: |
424 | return 1; |
425 | case -1: |
426 | SDL_SetError("ph_Pending(): PhEventNext failed.\n"); |
427 | return 0; |
428 | default: |
429 | return 0; |
430 | } |
431 | } |
432 | |
433 | /* Oh well, nothing is ready .. */ |
434 | return(0); |
435 | } |
436 | |
437 | void ph_PumpEvents(_THIS) |
438 | { |
439 | /* Flush the display connection and look to see if events are queued */ |
440 | PgFlush(); |
441 | |
442 | while (ph_Pending(this)) |
443 | { |
444 | PtEventHandler(phevent); |
445 | ph_DispatchEvent(this); |
446 | } |
447 | } |
448 | |
449 | void ph_InitKeymap(void) |
450 | { |
451 | int i; |
452 | |
453 | /* Odd keys used in international keyboards */ |
454 | for (i=0; i<SDL_arraysize(ODD_keymap); ++i) |
455 | { |
456 | ODD_keymap[i] = SDLK_UNKNOWN; |
457 | } |
458 | |
459 | /* Map the miscellaneous keys */ |
460 | for (i=0; i<SDL_arraysize(MISC_keymap); ++i) |
461 | { |
462 | MISC_keymap[i] = SDLK_UNKNOWN; |
463 | } |
464 | |
465 | MISC_keymap[Pk_BackSpace&0xFF] = SDLK_BACKSPACE; |
466 | MISC_keymap[Pk_Tab&0xFF] = SDLK_TAB; |
467 | MISC_keymap[Pk_Clear&0xFF] = SDLK_CLEAR; |
468 | MISC_keymap[Pk_Return&0xFF] = SDLK_RETURN; |
469 | MISC_keymap[Pk_Pause&0xFF] = SDLK_PAUSE; |
470 | MISC_keymap[Pk_Escape&0xFF] = SDLK_ESCAPE; |
471 | MISC_keymap[Pk_Delete&0xFF] = SDLK_DELETE; |
472 | |
473 | MISC_keymap[Pk_KP_0&0xFF] = SDLK_KP0; |
474 | MISC_keymap[Pk_KP_1&0xFF] = SDLK_KP1; |
475 | MISC_keymap[Pk_KP_2&0xFF] = SDLK_KP2; |
476 | MISC_keymap[Pk_KP_3&0xFF] = SDLK_KP3; |
477 | MISC_keymap[Pk_KP_4&0xFF] = SDLK_KP4; |
478 | MISC_keymap[Pk_KP_5&0xFF] = SDLK_KP5; |
479 | MISC_keymap[Pk_KP_6&0xFF] = SDLK_KP6; |
480 | MISC_keymap[Pk_KP_7&0xFF] = SDLK_KP7; |
481 | MISC_keymap[Pk_KP_8&0xFF] = SDLK_KP8; |
482 | MISC_keymap[Pk_KP_9&0xFF] = SDLK_KP9; |
483 | |
484 | MISC_keymap[Pk_KP_Decimal&0xFF] = SDLK_KP_PERIOD; |
485 | MISC_keymap[Pk_KP_Divide&0xFF] = SDLK_KP_DIVIDE; |
486 | MISC_keymap[Pk_KP_Multiply&0xFF] = SDLK_KP_MULTIPLY; |
487 | MISC_keymap[Pk_KP_Subtract&0xFF] = SDLK_KP_MINUS; |
488 | MISC_keymap[Pk_KP_Add&0xFF] = SDLK_KP_PLUS; |
489 | MISC_keymap[Pk_KP_Enter&0xFF] = SDLK_KP_ENTER; |
490 | MISC_keymap[Pk_KP_Equal&0xFF] = SDLK_KP_EQUALS; |
491 | |
492 | MISC_keymap[Pk_Up&0xFF] = SDLK_UP; |
493 | MISC_keymap[Pk_Down&0xFF] = SDLK_DOWN; |
494 | MISC_keymap[Pk_Right&0xFF] = SDLK_RIGHT; |
495 | MISC_keymap[Pk_Left&0xFF] = SDLK_LEFT; |
496 | MISC_keymap[Pk_Insert&0xFF] = SDLK_INSERT; |
497 | MISC_keymap[Pk_Home&0xFF] = SDLK_HOME; |
498 | MISC_keymap[Pk_End&0xFF] = SDLK_END; |
499 | MISC_keymap[Pk_Pg_Up&0xFF] = SDLK_PAGEUP; |
500 | MISC_keymap[Pk_Pg_Down&0xFF] = SDLK_PAGEDOWN; |
501 | |
502 | MISC_keymap[Pk_F1&0xFF] = SDLK_F1; |
503 | MISC_keymap[Pk_F2&0xFF] = SDLK_F2; |
504 | MISC_keymap[Pk_F3&0xFF] = SDLK_F3; |
505 | MISC_keymap[Pk_F4&0xFF] = SDLK_F4; |
506 | MISC_keymap[Pk_F5&0xFF] = SDLK_F5; |
507 | MISC_keymap[Pk_F6&0xFF] = SDLK_F6; |
508 | MISC_keymap[Pk_F7&0xFF] = SDLK_F7; |
509 | MISC_keymap[Pk_F8&0xFF] = SDLK_F8; |
510 | MISC_keymap[Pk_F9&0xFF] = SDLK_F9; |
511 | MISC_keymap[Pk_F10&0xFF] = SDLK_F10; |
512 | MISC_keymap[Pk_F11&0xFF] = SDLK_F11; |
513 | MISC_keymap[Pk_F12&0xFF] = SDLK_F12; |
514 | MISC_keymap[Pk_F13&0xFF] = SDLK_F13; |
515 | MISC_keymap[Pk_F14&0xFF] = SDLK_F14; |
516 | MISC_keymap[Pk_F15&0xFF] = SDLK_F15; |
517 | |
518 | MISC_keymap[Pk_Num_Lock&0xFF] = SDLK_NUMLOCK; |
519 | MISC_keymap[Pk_Caps_Lock&0xFF] = SDLK_CAPSLOCK; |
520 | MISC_keymap[Pk_Scroll_Lock&0xFF] = SDLK_SCROLLOCK; |
521 | MISC_keymap[Pk_Shift_R&0xFF] = SDLK_RSHIFT; |
522 | MISC_keymap[Pk_Shift_L&0xFF] = SDLK_LSHIFT; |
523 | MISC_keymap[Pk_Control_R&0xFF] = SDLK_RCTRL; |
524 | MISC_keymap[Pk_Control_L&0xFF] = SDLK_LCTRL; |
525 | MISC_keymap[Pk_Alt_R&0xFF] = SDLK_RALT; |
526 | MISC_keymap[Pk_Alt_L&0xFF] = SDLK_LALT; |
527 | MISC_keymap[Pk_Meta_R&0xFF] = SDLK_RMETA; |
528 | MISC_keymap[Pk_Meta_L&0xFF] = SDLK_LMETA; |
529 | MISC_keymap[Pk_Super_L&0xFF] = SDLK_LSUPER; |
530 | MISC_keymap[Pk_Super_R&0xFF] = SDLK_RSUPER; |
531 | MISC_keymap[Pk_Mode_switch&0xFF] = SDLK_MODE; /* "Alt Gr" key */ |
532 | |
533 | MISC_keymap[Pk_Help&0xFF] = SDLK_HELP; |
534 | MISC_keymap[Pk_Print&0xFF] = SDLK_PRINT; |
535 | MISC_keymap[Pk_Break&0xFF] = SDLK_BREAK; |
536 | MISC_keymap[Pk_Menu&0xFF] = SDLK_MENU; /* Windows "Menu" key */ |
537 | |
538 | MISC_keymap[Pk_Hyper_R&0xFF] = SDLK_RSUPER; /* Right "Windows" */ |
539 | |
540 | /* Left "Windows" key, but it can't be catched by application */ |
541 | MISC_keymap[Pk_Hyper_L&0xFF] = SDLK_LSUPER; |
542 | } |
543 | |
544 | static unsigned long cap; |
545 | |
546 | SDL_keysym *ph_TranslateKey(PhKeyEvent_t *key, SDL_keysym *keysym) |
547 | { |
548 | /* 'sym' is set to the value of the key with modifiers applied to it. |
549 | This member is valid only if Pk_KF_Sym_Valid is set in the key_flags. |
550 | We will assume it is valid. */ |
551 | |
552 | /* FIXME: This needs to check whether the cap & scancode is valid */ |
553 | |
554 | cap = key->key_cap; |
555 | |
556 | switch (cap>>8) |
557 | { |
558 | case 0x00: /* Latin 1 */ |
559 | case 0x01: /* Latin 2 */ |
560 | case 0x02: /* Latin 3 */ |
561 | case 0x03: /* Latin 4 */ |
562 | case 0x04: /* Katakana */ |
563 | case 0x05: /* Arabic */ |
564 | case 0x06: /* Cyrillic */ |
565 | case 0x07: /* Greek */ |
566 | case 0x08: /* Technical */ |
567 | case 0x0A: /* Publishing */ |
568 | case 0x0C: /* Hebrew */ |
569 | case 0x0D: /* Thai */ |
570 | keysym->sym = (SDLKey)(cap&0xFF); |
571 | /* Map capital letter syms to lowercase */ |
572 | if ((keysym->sym >= 'A')&&(keysym->sym <= 'Z')) |
573 | keysym->sym += ('a'-'A'); |
574 | break; |
575 | case 0xF0: |
576 | keysym->sym = MISC_keymap[cap&0xFF]; |
577 | break; |
578 | default: |
579 | keysym->sym = SDLK_UNKNOWN; |
580 | break; |
581 | } |
582 | |
583 | keysym->scancode = key->key_scan; |
584 | keysym->unicode = 0; |
585 | |
586 | if (SDL_TranslateUNICODE) |
587 | { |
588 | char utf8[MB_CUR_MAX]; |
589 | int utf8len; |
590 | wchar_t unicode; |
591 | |
592 | switch (keysym->scancode) |
593 | { |
594 | /* Esc key */ |
595 | case 0x01: keysym->unicode = 27; |
596 | break; |
597 | /* BackSpace key */ |
598 | case 0x0E: keysym->unicode = 127; |
599 | break; |
600 | /* Enter key */ |
601 | case 0x1C: keysym->unicode = 10; |
602 | break; |
603 | default: |
604 | utf8len = PhKeyToMb(utf8, key); |
605 | if (utf8len > 0) |
606 | { |
607 | utf8len = mbtowc(&unicode, utf8, utf8len); |
608 | if (utf8len > 0) |
609 | { |
610 | keysym->unicode = unicode; |
611 | } |
612 | } |
613 | break; |
614 | } |
615 | |
616 | } |
617 | |
618 | return (keysym); |
619 | } |
620 | |
621 | void ph_InitOSKeymap(_THIS) |
622 | { |
623 | ph_InitKeymap(); |
624 | } |