SDL-1.2.14
[sdl_omap.git] / src / video / symbian / EKA1 / SDL_epocevents.cpp
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 Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 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     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19     Sam Lantinga
20     slouken@devolution.com
21 */
22
23 /*
24     SDL_epocevents.cpp
25     Handle the event stream, converting Epoc events into SDL events
26
27     Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
28 */
29
30
31 #include <stdio.h>
32 #undef NULL
33 extern "C" {
34 //#define DEBUG_TRACE_ENABLED
35 #include "SDL_error.h"
36 #include "SDL_video.h"
37 #include "SDL_keysym.h"
38 #include "SDL_keyboard.h"
39 #include "SDL_events_c.h"
40 #include "SDL_timer.h"
41 }; /* extern "C" */
42
43 #include "SDL_epocvideo.h"
44 #include "SDL_epocevents_c.h"
45
46 #include<linereader.h>
47 #include<bautils.h>
48
49
50 #include <hal.h>
51
52 extern "C" {
53 /* The translation tables from a console scancode to a SDL keysym */
54 static SDLKey keymap[MAX_SCANCODE];
55 static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
56 void DisableKeyBlocking(_THIS);
57 }; /* extern "C" */
58
59 TBool isCursorVisible = EFalse;
60
61 int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
62 {
63     int posted = 0;
64     SDL_keysym keysym;
65     
66 //    SDL_TRACE1("hws %d", aWsEvent.Type());
67
68     switch (aWsEvent.Type())
69                 {    
70     case EEventPointer: /* Mouse pointer events */
71                 {
72
73         const TPointerCursorMode mode =  Private->EPOC_WsSession.PointerCursorMode();
74
75         if(mode == EPointerCursorNone) 
76             {
77             return 0; //TODO: Find out why events are get despite of cursor should be off
78             }
79
80         const TPointerEvent* pointerEvent = aWsEvent.Pointer();
81         TPoint mousePos = pointerEvent->iPosition;
82
83         /*!! TODO Pointer do not yet work properly
84         //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
85
86         if (Private->EPOC_ShrinkedHeight) {
87             mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
88         }
89         if (Private->EPOC_ShrinkedWidth) {
90             mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
91         }
92         */
93
94                 posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
95
96                 switch (pointerEvent->iType)
97                         {
98         case TPointerEvent::EButton1Down:
99             posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
100                         break;
101         case TPointerEvent::EButton1Up:
102                         posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
103                         break;
104         case TPointerEvent::EButton2Down:
105             posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
106                         break;
107                 case TPointerEvent::EButton2Up:
108                         posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
109                         break;
110         case TPointerEvent::EButton3Down:
111             posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
112                         break;
113         case TPointerEvent::EButton3Up:
114                         posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
115                         break;
116                         } // switch
117         break;
118             }
119     
120     case EEventKeyDown: /* Key events */
121     {
122 #ifdef SYMBIAN_CRYSTAL
123                 // special case: 9300/9500 rocker down, simulate left mouse button
124                 if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
125                         {
126             const TPointerCursorMode mode =  Private->EPOC_WsSession.PointerCursorMode();
127             if(mode != EPointerCursorNone) 
128                 posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
129                         }
130 #endif
131        (void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
132             
133 #ifndef DISABLE_JOYSTICK
134         /* Special handling */
135         switch((int)keysym.sym) {
136         case SDLK_CAPSLOCK:
137             if (!isCursorVisible) {
138                 /* Enable virtual cursor */
139                     HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
140             }
141             else {
142                 /* Disable virtual cursor */
143                 HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
144             }
145             isCursorVisible = !isCursorVisible;
146             break;
147         }
148 #endif        
149             posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
150         break;
151         } 
152
153     case EEventKeyUp: /* Key events */
154                 {
155 #ifdef SYMBIAN_CRYSTAL
156                 // special case: 9300/9500 rocker up, simulate left mouse button
157                 if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
158                         {
159             posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
160                         }
161 #endif
162             posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
163         break;
164                 }
165     
166     case EEventFocusGained: /* SDL window got focus */
167             {
168         Private->EPOC_IsWindowFocused = ETrue;
169                 posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
170         /* Draw window background and screen buffer */
171         DisableKeyBlocking(_this);  //Markus: guess why:-)
172  
173         RedrawWindowL(_this);  
174         break;
175             }
176
177     case EEventFocusLost: /* SDL window lost focus */
178                 {
179 /*        
180         CFbsBitmap* bmp = new (ELeave) CFbsBitmap();
181         bmp->Create(Private->EPOC_ScreenSize, Private->EPOC_DisplayMode);
182         Private->EPOC_WsScreen->CopyScreenToBitmap(bmp);
183         Private->EPOC_WindowGc->Activate(Private->EPOC_WsWindow);
184         Private->EPOC_WsWindow.BeginRedraw(TRect(Private->EPOC_WsWindow.Size()));
185             Private->EPOC_WindowGc->BitBlt(TPoint(0, 0), bmp);
186             Private->EPOC_WsWindow.EndRedraw();
187             Private->EPOC_WindowGc->Deactivate();
188         bmp->Save(_L("C:\\scr.mbm"));
189         delete bmp;
190 */       
191
192                 Private->EPOC_IsWindowFocused = EFalse;
193
194                 posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
195
196         RWsSession s;
197         s.Connect();
198         RWindowGroup g(s);
199         g.Construct(TUint32(&g), EFalse);
200         g.EnableReceiptOfFocus(EFalse);
201         RWindow w(s);
202         w.Construct(g, TUint32(&w));
203         w.SetExtent(TPoint(0, 0), Private->EPOC_WsWindow.Size());
204         w.SetOrdinalPosition(0);
205         w.Activate();
206         w.Close();
207         g.Close();
208         s.Close();
209
210 /*
211         Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(Private->EPOC_WsWindowGroupID, -1);
212
213             
214         SDL_Delay(500);
215         TInt focus = -1;
216         while(focus < 0)
217             {
218             const TInt curr = Private->EPOC_WsSession.GetFocusWindowGroup();
219             if(curr != Private->EPOC_WsWindowGroupID)
220                 focus = curr;
221             else
222                 SDL_Delay(500);
223             }
224
225         if(1 < Private->EPOC_WsSession.GetWindowGroupOrdinalPriority(Private->EPOC_WsWindowGroupID))
226             {
227             Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, -1);
228             SDL_Delay(500);
229             Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, 0);
230             }
231 */
232         /*//and the request redraw
233         TRawEvent redrawEvent;
234         redrawEvent.Set(TRawEvent::ERedraw);
235         Private->EPOC_WsSession.SimulateRawEvent(redrawEvent);
236         Private->EPOC_WsSession.Flush();*/
237 #if 0
238         //!! Not used
239         // Wait and eat events until focus is gained again
240             while (ETrue) {
241             Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
242             User::WaitForRequest(Private->EPOC_WsEventStatus);
243                     Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
244             TInt eventType = Private->EPOC_WsEvent.Type();
245                     Private->EPOC_WsEventStatus = KRequestPending;
246                     //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
247             if (eventType == EEventFocusGained) {
248                 RedrawWindowL(_this);
249                 break;
250             }
251             }
252 #endif
253         break;
254             }
255
256     case EEventModifiersChanged: 
257     {
258             TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
259         TUint modstate = KMOD_NONE;
260         if (modEvent->iModifiers == EModifierLeftShift)
261             modstate |= KMOD_LSHIFT;
262         if (modEvent->iModifiers == EModifierRightShift)
263             modstate |= KMOD_RSHIFT;
264         if (modEvent->iModifiers == EModifierLeftCtrl)
265             modstate |= KMOD_LCTRL;
266         if (modEvent->iModifiers == EModifierRightCtrl)
267             modstate |= KMOD_RCTRL;
268         if (modEvent->iModifiers == EModifierLeftAlt)
269             modstate |= KMOD_LALT;
270         if (modEvent->iModifiers == EModifierRightAlt)
271             modstate |= KMOD_RALT;
272         if (modEvent->iModifiers == EModifierLeftFunc)
273             modstate |= KMOD_LMETA;
274         if (modEvent->iModifiers == EModifierRightFunc)
275             modstate |= KMOD_RMETA;
276         if (modEvent->iModifiers == EModifierCapsLock)
277             modstate |= KMOD_CAPS;
278         SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
279         break;
280     }
281     default:            
282         break;
283         } 
284         
285     return posted;
286 }
287
288 extern "C" {
289
290 void EPOC_PumpEvents(_THIS)
291 {
292     int posted = 0; // !! Do we need this?
293     //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
294         while (Private->EPOC_WsEventStatus != KRequestPending) {
295
296                 Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
297                 posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent);
298                 Private->EPOC_WsEventStatus = KRequestPending;
299                 Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
300         }
301 }
302
303
304 _LIT(KMapFileName, "C:\\sdl_info\\sdlkeymap.cfg");
305 LOCAL_C void ReadL(RFs& aFs, RArray<TInt>& aArray)
306     {
307     TInt drive = -1;
308     TFileName name(KMapFileName);
309     for(TInt i = 'z'; drive < 0 && i >= 'a'; i--)
310         {
311         name[0] = (TUint16)i;
312         if(BaflUtils::FileExists(aFs, name))
313             drive = i;
314         }
315     if(drive < 0)
316         return;
317     CLineReader* reader = CLineReader::NewLC(aFs, name);
318     while(reader->NextL())
319         {
320         TPtrC ln = reader->Current();
321         TLex line(ln);
322         TInt n = 0;
323         for(;;)
324             {
325             const TPtrC token = line.NextToken();
326             if(token.Length() == 0)
327                 break;
328             if((n & 1) != 0)
329                 {
330                 TInt value;
331                 TLex lex(token);
332                 User::LeaveIfError(lex.Val(value));
333                 User::LeaveIfError(aArray.Append(value));
334                 }
335             n++;
336             }
337         }
338     CleanupStack::PopAndDestroy();
339     }
340
341
342 void EPOC_InitOSKeymap(_THIS)
343 {
344         int i;
345
346         /* Initialize the key translation table */
347         for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
348                 keymap[i] = SDLK_UNKNOWN;
349
350
351         /* Numbers */
352         for ( i = 0; i<32; ++i ){
353                 keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
354         }
355         /* e.g. Alphabet keys */
356         for ( i = 0; i<32; ++i ){
357                 keymap['A' + i] = (SDLKey)(SDLK_a+i);
358         }
359
360         keymap[EStdKeyBackspace]    = SDLK_BACKSPACE;
361         keymap[EStdKeyTab]          = SDLK_TAB;
362         keymap[EStdKeyEnter]        = SDLK_RETURN;
363         keymap[EStdKeyEscape]       = SDLK_ESCAPE;
364         keymap[EStdKeySpace]        = SDLK_SPACE;
365         keymap[EStdKeyPause]        = SDLK_PAUSE;
366         keymap[EStdKeyHome]         = SDLK_HOME;
367         keymap[EStdKeyEnd]          = SDLK_END;
368         keymap[EStdKeyPageUp]       = SDLK_PAGEUP;
369         keymap[EStdKeyPageDown]     = SDLK_PAGEDOWN;
370         keymap[EStdKeyDelete]       = SDLK_DELETE;
371         keymap[EStdKeyUpArrow]      = SDLK_UP;
372         keymap[EStdKeyDownArrow]    = SDLK_DOWN;
373         keymap[EStdKeyLeftArrow]    = SDLK_LEFT;
374         keymap[EStdKeyRightArrow]   = SDLK_RIGHT;
375         keymap[EStdKeyCapsLock]     = SDLK_CAPSLOCK;
376         keymap[EStdKeyLeftShift]    = SDLK_LSHIFT;
377         keymap[EStdKeyRightShift]   = SDLK_RSHIFT;
378         keymap[EStdKeyLeftAlt]      = SDLK_LALT;
379         keymap[EStdKeyRightAlt]     = SDLK_RALT;
380         keymap[EStdKeyLeftCtrl]     = SDLK_LCTRL;
381         keymap[EStdKeyRightCtrl]    = SDLK_RCTRL;
382         keymap[EStdKeyLeftFunc]     = SDLK_LMETA;
383         keymap[EStdKeyRightFunc]    = SDLK_RMETA;
384         keymap[EStdKeyInsert]       = SDLK_INSERT;
385         keymap[EStdKeyComma]        = SDLK_COMMA;
386         keymap[EStdKeyFullStop]     = SDLK_PERIOD;
387         keymap[EStdKeyForwardSlash] = SDLK_SLASH;
388         keymap[EStdKeyBackSlash]    = SDLK_BACKSLASH;
389         keymap[EStdKeySemiColon]    = SDLK_SEMICOLON;
390         keymap[EStdKeySingleQuote]  = SDLK_QUOTE;
391         keymap[EStdKeyHash]         = SDLK_HASH;
392         keymap[EStdKeySquareBracketLeft]    = SDLK_LEFTBRACKET;
393         keymap[EStdKeySquareBracketRight]   = SDLK_RIGHTBRACKET;
394         keymap[EStdKeyMinus]        = SDLK_MINUS;
395         keymap[EStdKeyEquals]       = SDLK_EQUALS;
396
397         keymap[EStdKeyF1]          = SDLK_F1;  /* chr + q */
398         keymap[EStdKeyF2]          = SDLK_F2;  /* chr + w */
399         keymap[EStdKeyF3]          = SDLK_F3;  /* chr + e */
400         keymap[EStdKeyF4]          = SDLK_F4;  /* chr + r */
401         keymap[EStdKeyF5]          = SDLK_F5;  /* chr + t */
402         keymap[EStdKeyF6]          = SDLK_F6;  /* chr + y */
403         keymap[EStdKeyF7]          = SDLK_F7;  /* chr + i */
404         keymap[EStdKeyF8]          = SDLK_F8;  /* chr + o */
405
406         keymap[EStdKeyF9]          = SDLK_F9;  /* chr + a */
407         keymap[EStdKeyF10]         = SDLK_F10; /* chr + s */
408         keymap[EStdKeyF11]         = SDLK_F11; /* chr + d */
409         keymap[EStdKeyF12]         = SDLK_F12; /* chr + f */
410
411         #ifndef SYMBIAN_CRYSTAL 
412         //!!7650 additions
413     #ifdef __WINS__
414         keymap[EStdKeyXXX]         = SDLK_RETURN;       /* "fire" key */
415         #else
416         keymap[EStdKeyDevice3]     = SDLK_RETURN;       /* "fire" key */
417         #endif
418         keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK; 
419         keymap[EStdKeyYes]         = SDLK_HOME;         /* "call" key */
420         keymap[EStdKeyNo]                  = SDLK_END;          /* "end call" key */
421         keymap[EStdKeyDevice0]     = SDLK_SPACE;        /* right menu key */
422         keymap[EStdKeyDevice1]     = SDLK_ESCAPE;       /* left menu key */
423         keymap[EStdKeyDevice2]     = SDLK_POWER;        /* power key */
424         #endif
425
426  #ifdef SYMBIAN_CRYSTAL 
427     keymap[EStdKeyMenu]        = SDLK_ESCAPE;   // menu key
428     keymap[EStdKeyDevice6]     = SDLK_LEFT;     // Rocker (joystick) left
429     keymap[EStdKeyDevice7]     = SDLK_RIGHT;    // Rocker (joystick) right
430     keymap[EStdKeyDevice8]     = SDLK_UP;       // Rocker (joystick) up
431     keymap[EStdKeyDevice9]     = SDLK_DOWN;     // Rocker (joystick) down
432     keymap[EStdKeyLeftFunc]     = SDLK_LALT;    //chr?
433         keymap[EStdKeyRightFunc]    = SDLK_RALT;
434     keymap[EStdKeyDeviceA]      = SDLK_RETURN;  /* "fire" key */
435 #endif
436
437     ///////////////////////////////////////////////////////////
438
439     RFs fs;
440     if(KErrNone == fs.Connect())
441         {
442         RArray<TInt> array;
443         TRAPD(err, ReadL(fs, array));
444         if(err == KErrNone && array.Count() > 0)
445             {
446             
447             SDLKey temp[MAX_SCANCODE];
448             Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
449
450             for(TInt k = 0; k < array.Count(); k+= 2)
451                 {
452                 const TInt oldval = array[k]; 
453                 const TInt newval = array[k + 1]; 
454                 if(oldval >=  0 && oldval < MAX_SCANCODE && newval >=  0 && newval < MAX_SCANCODE)
455                     {
456                     keymap[oldval] = temp[newval];
457                     }
458                 }
459             }
460         array.Close();
461         }
462
463     fs.Close();
464     ///////////////////////////////////////////////////////////
465
466     /* !!TODO
467         EStdKeyNumLock=0x1b,
468         EStdKeyScrollLock=0x1c,
469
470         EStdKeyNkpForwardSlash=0x84,
471         EStdKeyNkpAsterisk=0x85,
472         EStdKeyNkpMinus=0x86,
473         EStdKeyNkpPlus=0x87,
474         EStdKeyNkpEnter=0x88,
475         EStdKeyNkp1=0x89,
476         EStdKeyNkp2=0x8a,
477         EStdKeyNkp3=0x8b,
478         EStdKeyNkp4=0x8c,
479         EStdKeyNkp5=0x8d,
480         EStdKeyNkp6=0x8e,
481         EStdKeyNkp7=0x8f,
482         EStdKeyNkp8=0x90,
483         EStdKeyNkp9=0x91,
484         EStdKeyNkp0=0x92,
485         EStdKeyNkpFullStop=0x93,
486     EStdKeyMenu=0x94,
487     EStdKeyBacklightOn=0x95,
488     EStdKeyBacklightOff=0x96,
489     EStdKeyBacklightToggle=0x97,
490     EStdKeyIncContrast=0x98,
491     EStdKeyDecContrast=0x99,
492     EStdKeySliderDown=0x9a,
493     EStdKeySliderUp=0x9b,
494     EStdKeyDictaphonePlay=0x9c,
495     EStdKeyDictaphoneStop=0x9d,
496     EStdKeyDictaphoneRecord=0x9e,
497     EStdKeyHelp=0x9f,
498     EStdKeyOff=0xa0,
499     EStdKeyDial=0xa1,
500     EStdKeyIncVolume=0xa2,
501     EStdKeyDecVolume=0xa3,
502     EStdKeyDevice0=0xa4,
503     EStdKeyDevice1=0xa5,
504     EStdKeyDevice2=0xa6,
505     EStdKeyDevice3=0xa7,
506     EStdKeyDevice4=0xa8,
507     EStdKeyDevice5=0xa9,
508     EStdKeyDevice6=0xaa,
509     EStdKeyDevice7=0xab,
510     EStdKeyDevice8=0xac,
511     EStdKeyDevice9=0xad,
512     EStdKeyDeviceA=0xae,
513     EStdKeyDeviceB=0xaf,
514     EStdKeyDeviceC=0xb0,
515     EStdKeyDeviceD=0xb1,
516     EStdKeyDeviceE=0xb2,
517     EStdKeyDeviceF=0xb3,
518     EStdKeyApplication0=0xb4,
519     EStdKeyApplication1=0xb5,
520     EStdKeyApplication2=0xb6,
521     EStdKeyApplication3=0xb7,
522     EStdKeyApplication4=0xb8,
523     EStdKeyApplication5=0xb9,
524     EStdKeyApplication6=0xba,
525     EStdKeyApplication7=0xbb,
526     EStdKeyApplication8=0xbc,
527     EStdKeyApplication9=0xbd,
528     EStdKeyApplicationA=0xbe,
529     EStdKeyApplicationB=0xbf,
530     EStdKeyApplicationC=0xc0,
531     EStdKeyApplicationD=0xc1,
532     EStdKeyApplicationE=0xc2,
533     EStdKeyApplicationF=0xc3,
534     EStdKeyYes=0xc4,
535     EStdKeyNo=0xc5,
536     EStdKeyIncBrightness=0xc6,
537     EStdKeyDecBrightness=0xc7, 
538     EStdKeyCaseOpen=0xc8,
539     EStdKeyCaseClose=0xc9
540     */
541
542 }
543
544
545
546 static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
547 {
548 //    char debug[256];
549     //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
550
551         /* Set the keysym information */ 
552
553         keysym->scancode = scancode;
554
555     if ((scancode >= MAX_SCANCODE) && 
556         ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
557         SDL_SetError("Too big scancode");
558         keysym->scancode = SDLK_UNKNOWN;
559             keysym->mod = KMOD_NONE; 
560         return keysym;
561     }
562
563         keysym->mod = SDL_GetModState();
564
565     /* Handle function keys: F1, F2, F3 ... */
566     if (keysym->mod & KMOD_META) {
567         if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
568             switch(scancode) {
569                 case 'Q': scancode = EStdKeyF1; break;
570                 case 'W': scancode = EStdKeyF2; break;
571                 case 'E': scancode = EStdKeyF3; break;
572                 case 'R': scancode = EStdKeyF4; break;
573                 case 'T': scancode = EStdKeyF5; break;
574                 case 'Y': scancode = EStdKeyF6; break;
575                 case 'U': scancode = EStdKeyF7; break;
576                 case 'I': scancode = EStdKeyF8; break;
577                 case 'A': scancode = EStdKeyF9; break;
578                 case 'S': scancode = EStdKeyF10; break;
579                 case 'D': scancode = EStdKeyF11; break;
580                 case 'F': scancode = EStdKeyF12; break;
581             }
582             keysym->sym = keymap[scancode];
583         }
584     }
585
586     if (scancode >= ENonCharacterKeyBase) {
587         // Non character keys
588             keysym->sym = keymap[scancode - 
589             ENonCharacterKeyBase + 0x0081]; // !!hard coded
590     } else {
591             keysym->sym = keymap[scancode];
592     }
593
594         /* Remap the arrow keys if the device is rotated */
595         if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
596                 switch(keysym->sym) {
597                         case SDLK_UP:   keysym->sym = SDLK_LEFT;  break;
598                         case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
599                         case SDLK_LEFT: keysym->sym = SDLK_DOWN;  break;
600                         case SDLK_RIGHT:keysym->sym = SDLK_UP;    break;
601                 }
602         }
603
604         /* If UNICODE is on, get the UNICODE value for the key */
605         keysym->unicode = 0;
606
607 #if 0 // !!TODO:unicode
608
609         if ( SDL_TranslateUNICODE ) 
610     {
611                 /* Populate the unicode field with the ASCII value */
612                 keysym->unicode = scancode;
613         }
614 #endif
615
616     //!!
617     //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
618     //    keysym->scancode, keysym->sym, keysym->mod);
619     //SDL_TRACE(debug); //!!
620
621         return(keysym);
622 }
623
624 }; /* extern "C" */
625
626