SDL-1.2.14
[sdl_omap.git] / src / video / photon / SDL_ph_events.c
CommitLineData
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 */
45static SDLKey ODD_keymap[256];
46static SDLKey MISC_keymap[0xFF + 1];
47SDL_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! :) */
51static 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
78static 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, &region, NULL, NULL, 0) == 0 )
88 {
89 region.events_sense=(region.events_sense & ~fields)|(flags & fields);
90 PhRegionChange(Ph_REGION_EV_SENSE, 0, &region, NULL, NULL);
91 }
92 }
93}
94
95/* Convert the photon button state value to an SDL value */
96static 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
110static 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 */
414int 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
437void 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
449void 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
544static unsigned long cap;
545
546SDL_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
621void ph_InitOSKeymap(_THIS)
622{
623 ph_InitKeymap();
624}