1 #include "epoc_sdl.h"
2 
3 #include <stdio.h>
4 #undef NULL
5 extern "C" {
6 //#define DEBUG_TRACE_ENABLED
7 #include "SDL_error.h"
8 #include "SDL_video.h"
9 #include "SDL_keysym.h"
10 #include "SDL_keyboard.h"
11 #include "SDL_events_c.h"
12 #include "SDL_timer.h"
13 } /* extern "C" */
14 
15 #include "SDL_epocvideo.h"
16 #include "SDL_epocevents_c.h"
17 
18 #include "sdlepocapi.h"
19 
20 #include <eikenv.h>
21 
22 #include<bautils.h>
23 
24 
25 extern "C"
26 	{
27 	static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
28 	}
29 
30 //extern "C" {
31 /* The translation tables from a console scancode to a SDL keysym */
32 static SDLKey keymap[MAX_SCANCODE];
33 static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
34 void DisableKeyBlocking(_THIS);
35 //} /* extern "C" */
36 
KeyMap()37 SDLKey* KeyMap()
38 	{
39 	return keymap;
40 	}
41 
42 TBool isCursorVisible = EFalse;
43 
ResetKeyMap()44 void ResetKeyMap()
45 	{
46 	int i;
47 
48 	/* Initialize the key translation table */
49 	for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
50 		keymap[i] = SDLK_UNKNOWN;
51 
52 
53 	/* Numbers */
54 	for ( i = 0; i<32; ++i ){
55 		keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
56 	}
57 	/* e.g. Alphabet keys */
58 	for ( i = 0; i<32; ++i ){
59 		keymap['A' + i] = (SDLKey)(SDLK_a+i);
60 	}
61 
62 	keymap[EStdKeyBackspace]    = SDLK_BACKSPACE;
63 	keymap[EStdKeyTab]          = SDLK_TAB;
64 	keymap[EStdKeyEnter]        = SDLK_RETURN;
65 	keymap[EStdKeyEscape]       = SDLK_ESCAPE;
66    	keymap[EStdKeySpace]        = SDLK_SPACE;
67    	keymap[EStdKeyPause]        = SDLK_PAUSE;
68    	keymap[EStdKeyHome]         = SDLK_HOME;
69    	keymap[EStdKeyEnd]          = SDLK_END;
70    	keymap[EStdKeyPageUp]       = SDLK_PAGEUP;
71    	keymap[EStdKeyPageDown]     = SDLK_PAGEDOWN;
72 	keymap[EStdKeyDelete]       = SDLK_DELETE;
73 	keymap[EStdKeyUpArrow]      = SDLK_UP;
74 	keymap[EStdKeyDownArrow]    = SDLK_DOWN;
75 	keymap[EStdKeyLeftArrow]    = SDLK_LEFT;
76 	keymap[EStdKeyRightArrow]   = SDLK_RIGHT;
77 	keymap[EStdKeyCapsLock]     = SDLK_CAPSLOCK;
78 	keymap[EStdKeyLeftShift]    = SDLK_LSHIFT;
79 	keymap[EStdKeyRightShift]   = SDLK_RSHIFT;
80 	keymap[EStdKeyLeftAlt]      = SDLK_LALT;
81 	keymap[EStdKeyRightAlt]     = SDLK_RALT;
82 	keymap[EStdKeyLeftCtrl]     = SDLK_LCTRL;
83 	keymap[EStdKeyRightCtrl]    = SDLK_RCTRL;
84 	keymap[EStdKeyLeftFunc]     = SDLK_LMETA;
85 	keymap[EStdKeyRightFunc]    = SDLK_RMETA;
86 	keymap[EStdKeyInsert]       = SDLK_INSERT;
87 	keymap[EStdKeyComma]        = SDLK_COMMA;
88 	keymap[EStdKeyFullStop]     = SDLK_PERIOD;
89 	keymap[EStdKeyForwardSlash] = SDLK_SLASH;
90 	keymap[EStdKeyBackSlash]    = SDLK_BACKSLASH;
91 	keymap[EStdKeySemiColon]    = SDLK_SEMICOLON;
92 	keymap[EStdKeySingleQuote]  = SDLK_QUOTE;
93 	keymap[EStdKeyHash]         = SDLK_HASH;
94 	keymap[EStdKeySquareBracketLeft]    = SDLK_LEFTBRACKET;
95 	keymap[EStdKeySquareBracketRight]   = SDLK_RIGHTBRACKET;
96 	keymap[EStdKeyMinus]        = SDLK_MINUS;
97 	keymap[EStdKeyEquals]       = SDLK_EQUALS;
98 
99    	keymap[EStdKeyF1]          = SDLK_F1;
100    	keymap[EStdKeyF2]          = SDLK_F2;
101    	keymap[EStdKeyF3]          = SDLK_F3;
102    	keymap[EStdKeyF4]          = SDLK_F4;
103    	keymap[EStdKeyF5]          = SDLK_F5;
104    	keymap[EStdKeyF6]          = SDLK_F6;
105    	keymap[EStdKeyF7]          = SDLK_F7;
106    	keymap[EStdKeyF8]          = SDLK_F8;
107 
108    	keymap[EStdKeyF9]          = SDLK_F9;
109    	keymap[EStdKeyF10]         = SDLK_F10;
110    	keymap[EStdKeyF11]         = SDLK_F11;
111    	keymap[EStdKeyF12]         = SDLK_F12;
112 
113 
114    	keymap[EStdKeyXXX]         = SDLK_RETURN;	/* "fire" key */
115 
116    	keymap[EStdKeyDevice3]     = SDLK_RETURN;	/* "fire" key */
117    	keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK;
118    	keymap[EStdKeyYes]         = SDLK_HOME;		/* "call" key */
119    	keymap[EStdKeyNo]		   = SDLK_END;		/* "end call" key */
120    	keymap[EStdKeyDevice0]     = SDLK_SPACE;	/* right menu key */
121    	keymap[EStdKeyDevice1]     = SDLK_ESCAPE;	/* left menu key */
122    	keymap[EStdKeyDevice2]     = SDLK_POWER;	/* power key */
123 
124     keymap[EStdKeyMenu]        = SDLK_MENU;   	// menu key
125     keymap[EStdKeyDevice6]     = SDLK_LEFT;     // Rocker (joystick) left
126     keymap[EStdKeyDevice7]     = SDLK_RIGHT;    // Rocker (joystick) right
127     keymap[EStdKeyDevice8]     = SDLK_UP;       // Rocker (joystick) up
128     keymap[EStdKeyDevice9]     = SDLK_DOWN;     // Rocker (joystick) down
129     keymap[EStdKeyLeftFunc]     = SDLK_LALT;    //chr?
130 	keymap[EStdKeyRightFunc]    = SDLK_RALT;
131     keymap[EStdKeyDeviceA]      = SDLK_RETURN;	/* "fire" key */
132 
133 
134 
135 
136 
137     ///////////////////////////////////////////////////////////
138     /*
139     RFs fs;
140     if(KErrNone == fs.Connect())
141         {
142         RArray<TInt> array;
143         TRAPD(err, ReadL(fs, array));
144         if(err == KErrNone && array.Count() > 0)
145             {
146 
147             SDLKey temp[MAX_SCANCODE];
148             Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
149 
150             for(TInt k = 0; k < array.Count(); k+= 2)
151                 {
152                 const TInt oldval = array[k];
153                 const TInt newval = array[k + 1];
154                 if(oldval >=  0 && oldval < MAX_SCANCODE && newval >=  0 && newval < MAX_SCANCODE)
155                     {
156                     keymap[oldval] = temp[newval];
157                     }
158                 }
159             }
160         array.Close();
161         }
162 
163     fs.Close();*/
164     ///////////////////////////////////////////////////////////
165 
166 
167 	keymap[EStdKeyNumLock] = SDLK_NUMLOCK;
168 	keymap[EStdKeyScrollLock] = SDLK_SCROLLOCK;
169 
170 	keymap[EStdKeyNkpForwardSlash] = SDLK_KP_DIVIDE;
171 	keymap[EStdKeyNkpAsterisk] = SDLK_KP_MULTIPLY;
172 	keymap[EStdKeyNkpMinus] = SDLK_KP_MINUS;
173 	keymap[EStdKeyNkpPlus] = SDLK_KP_PLUS;
174 	keymap[EStdKeyNkpEnter] = SDLK_KP_ENTER;
175 	keymap[EStdKeyNkp1] = SDLK_KP1;
176 	keymap[EStdKeyNkp2] = SDLK_KP2;
177 	keymap[EStdKeyNkp3] = SDLK_KP3;
178 	keymap[EStdKeyNkp4] = SDLK_KP4;
179 	keymap[EStdKeyNkp5] = SDLK_KP5;
180 	keymap[EStdKeyNkp6] = SDLK_KP6;
181 	keymap[EStdKeyNkp7] = SDLK_KP7;
182 	keymap[EStdKeyNkp8] = SDLK_KP8;
183 	keymap[EStdKeyNkp9] = SDLK_KP9;
184 	keymap[EStdKeyNkp0] = SDLK_KP0;
185 	keymap[EStdKeyNkpFullStop] = SDLK_KP_PERIOD;
186     /*
187     keymap[EStdKeyMenu] = SDLK_MENU; should be, but not yet
188     keymap[EStdKeyBacklightOn] =
189     keymap[EStdKeyBacklightOff] =
190     keymap[EStdKeyBacklightToggle] =
191     keymap[EStdKeyIncContrast] =
192     keymap[EStdKeyDecContrast] =
193     keymap[EStdKeySliderDown] =
194     keymap[EStdKeySliderUp] =
195     keymap[EStdKeyDictaphonePlay] =
196     keymap[EStdKeyDictaphoneStop] =
197     keymap[EStdKeyDictaphoneRecord] =
198     keymap[EStdKeyHelp] =
199     keymap[EStdKeyOff] =
200     keymap[EStdKeyDial] =
201     keymap[EStdKeyIncVolume] =
202     keymap[EStdKeyDecVolume] =
203     keymap[EStdKeyDevice0] =
204     keymap[EStdKeyDevice1] =
205     keymap[EStdKeyDevice2] =
206     keymap[EStdKeyDevice3] =
207     keymap[EStdKeyDevice4] =
208     keymap[EStdKeyDevice5] =
209     keymap[EStdKeyDevice6] =
210     keymap[EStdKeyDevice7] =
211     keymap[EStdKeyDevice8] =
212     keymap[EStdKeyDevice9] =
213     keymap[EStdKeyDeviceA] =
214     keymap[EStdKeyDeviceB] =
215     keymap[EStdKeyDeviceC] =
216     keymap[EStdKeyDeviceD] =
217     keymap[EStdKeyDeviceE] =
218     keymap[EStdKeyDeviceF] =
219     keymap[EStdKeyApplication0] =
220     keymap[EStdKeyApplication1] =
221     keymap[EStdKeyApplication2] =
222     keymap[EStdKeyApplication3] =
223     keymap[EStdKeyApplication4] =
224     keymap[EStdKeyApplication5] =
225     keymap[EStdKeyApplication6] =
226     keymap[EStdKeyApplication7] =
227     keymap[EStdKeyApplication8] =
228     keymap[EStdKeyApplication9] =
229     keymap[EStdKeyApplicationA] =
230     keymap[EStdKeyApplicationB] =
231     keymap[EStdKeyApplicationC] =
232     keymap[EStdKeyApplicationD] =
233     keymap[EStdKeyApplicationE] =
234     keymap[EStdKeyApplicationF] =
235     keymap[EStdKeyYes] =
236     keymap[EStdKeyNo] =
237     keymap[EStdKeyIncBrightness] =
238     keymap[EStdKeyDecBrightness] =
239     keymap[EStdKeyCaseOpen] =
240     keymap[EStdKeyCaseClose] =  */
241 
242 
243 
244 }
245 
246 
EPOC_HandleWsEvent(_THIS,const TWsEvent & aWsEvent)247 int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
248 {
249     int posted = 0;
250     SDL_keysym keysym;
251 
252 //    SDL_TRACE1("hws %d", aWsEvent.Type());
253 
254     switch (aWsEvent.Type())
255 		{
256     case EEventPointer: /* Mouse pointer events */
257 		{
258 /*        const TPointerCursorMode mode = EpocSdlEnv::PointerMode();
259 
260 
261         if(mode == EPointerCursorNone)
262             {
263             return 0; //TODO: Find out why events are get despite of cursor should be off
264             }
265 */
266         const TPointerEvent* pointerEvent = aWsEvent.Pointer();
267         const TPoint mousePos = EpocSdlEnv::WindowCoordinates(pointerEvent->iPosition);
268 
269         /*!! TODO Pointer do not yet work properly
270         //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
271 
272         if (Private->EPOC_ShrinkedHeight) {
273             mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
274         }
275         if (Private->EPOC_ShrinkedWidth) {
276             mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
277         }
278         */
279 
280 		posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
281 
282 		switch (pointerEvent->iType)
283 			{
284         case TPointerEvent::EButton1Down:
285             posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
286 			break;
287         case TPointerEvent::EButton1Up:
288 			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
289 			break;
290         case TPointerEvent::EButton2Down:
291             posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
292 			break;
293 		case TPointerEvent::EButton2Up:
294 			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
295 			break;
296         case TPointerEvent::EButton3Down:
297             posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
298 			break;
299         case TPointerEvent::EButton3Up:
300 			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
301 			break;
302 			} // switch
303         break;
304 	    }
305 
306     case EEventKeyDown: /* Key events */
307     {
308 #ifdef SYMBIAN_CRYSTAL
309 		// special case: 9300/9500 rocker down, simulate left mouse button
310 		if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
311 			{
312             const TPointerCursorMode mode =  Private->EPOC_WsSession.PointerCursorMode();
313             if(mode != EPointerCursorNone)
314                 posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
315 			}
316 #endif
317        (void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
318 
319 #ifndef DISABLE_JOYSTICK
320         /* Special handling */
321         switch((int)keysym.sym) {
322         case SDLK_CAPSLOCK:
323             if (!isCursorVisible) {
324                 /* Enable virtual cursor */
325 	            HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
326             }
327             else {
328                 /* Disable virtual cursor */
329                 HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
330             }
331             isCursorVisible = !isCursorVisible;
332             break;
333         }
334 #endif
335 	    posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
336         break;
337 	}
338 
339     case EEventKeyUp: /* Key events */
340 		{
341 #ifdef SYMBIAN_CRYSTAL
342 		// special case: 9300/9500 rocker up, simulate left mouse button
343 		if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
344 			{
345             posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
346 			}
347 #endif
348 	    posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
349         break;
350 		}
351 
352     case EEventFocusGained: /* SDL window got focus */
353 	    {
354         Private->iIsWindowFocused = ETrue;
355 		posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
356         /* Draw window background and screen buffer */
357         DisableKeyBlocking(_this);  //Markus: guess why:-)
358 
359         //RedrawWindowL(_this);
360         break;
361 	    }
362 
363     case EEventFocusLost: /* SDL window lost focus */
364 		{
365 
366 		Private->iIsWindowFocused = EFalse;
367 
368 		posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
369 
370 
371         break;
372 	    }
373 
374     case EEventModifiersChanged:
375     {
376 	    TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
377         TUint modstate = KMOD_NONE;
378         if (modEvent->iModifiers == EModifierLeftShift)
379             modstate |= KMOD_LSHIFT;
380         if (modEvent->iModifiers == EModifierRightShift)
381             modstate |= KMOD_RSHIFT;
382         if (modEvent->iModifiers == EModifierLeftCtrl)
383             modstate |= KMOD_LCTRL;
384         if (modEvent->iModifiers == EModifierRightCtrl)
385             modstate |= KMOD_RCTRL;
386         if (modEvent->iModifiers == EModifierLeftAlt)
387             modstate |= KMOD_LALT;
388         if (modEvent->iModifiers == EModifierRightAlt)
389             modstate |= KMOD_RALT;
390         if (modEvent->iModifiers == EModifierLeftFunc)
391             modstate |= KMOD_LMETA;
392         if (modEvent->iModifiers == EModifierRightFunc)
393             modstate |= KMOD_RMETA;
394         if (modEvent->iModifiers == EModifierCapsLock)
395             modstate |= KMOD_CAPS;
396         SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
397         break;
398     }
399 	case EEventScreenDeviceChanged:
400 	        {
401 	        EpocSdlEnv::WaitDeviceChange();
402 	        }
403 	    break;
404     default:
405         break;
406 	}
407 
408     return posted;
409 }
410 
411 extern "C" {
412 
EPOC_PumpEvents(_THIS)413 void EPOC_PumpEvents(_THIS)
414     {
415     MEventQueue& events = EpocSdlEnv::EventQueue();
416     while(events.HasData())
417         {
418         events.Lock();
419 
420        //there have to be a copy, so we can release
421        //lock immediately. HandleWsEvent may cause
422        //deadlock otherwise.
423 
424         const TWsEvent event = events.Shift();
425 		events.Unlock();
426 //        const TWsEvent& event = events.Top();
427 		EPOC_HandleWsEvent(_this, event);
428 //		events.Shift();
429 	    }
430     }
431 
432 
433 
EPOC_InitOSKeymap(_THIS)434 void EPOC_InitOSKeymap(_THIS)
435 	{
436 	ResetKeyMap();
437 	EpocSdlEnv::ObserverEvent(MSDLObserver::EEventKeyMapInit ,0);
438 	}
439 
TranslateKey(_THIS,int scancode,SDL_keysym * keysym)440 static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
441 {
442 //    char debug[256];
443     //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
444 
445 	/* Set the keysym information */
446 
447 	keysym->scancode = scancode;
448 
449     if ((scancode >= MAX_SCANCODE) &&
450         ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
451         SDL_SetError("Too big scancode");
452         keysym->scancode = SDLK_UNKNOWN;
453 	    keysym->mod = KMOD_NONE;
454         return keysym;
455     }
456 
457 	keysym->mod = SDL_GetModState();
458 
459     /* Handle function keys: F1, F2, F3 ... */
460     if (keysym->mod & KMOD_META) {
461         if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
462             switch(scancode) {
463                 case 'Q': scancode = EStdKeyF1; break;
464                 case 'W': scancode = EStdKeyF2; break;
465                 case 'E': scancode = EStdKeyF3; break;
466                 case 'R': scancode = EStdKeyF4; break;
467                 case 'T': scancode = EStdKeyF5; break;
468                 case 'Y': scancode = EStdKeyF6; break;
469                 case 'U': scancode = EStdKeyF7; break;
470                 case 'I': scancode = EStdKeyF8; break;
471                 case 'A': scancode = EStdKeyF9; break;
472                 case 'S': scancode = EStdKeyF10; break;
473                 case 'D': scancode = EStdKeyF11; break;
474                 case 'F': scancode = EStdKeyF12; break;
475             }
476             keysym->sym = keymap[scancode];
477         }
478     }
479 
480     if (scancode >= ENonCharacterKeyBase) {
481         // Non character keys
482 	    keysym->sym = keymap[scancode -
483             ENonCharacterKeyBase + 0x0081]; // !!hard coded
484     } else {
485 	    keysym->sym = keymap[scancode];
486     }
487 
488 	/* Remap the arrow keys if the device is rotated */
489 /*
490 	if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
491 		switch(keysym->sym) {
492 			case SDLK_UP:	keysym->sym = SDLK_LEFT;  break;
493 			case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
494 			case SDLK_LEFT: keysym->sym = SDLK_DOWN;  break;
495 			case SDLK_RIGHT:keysym->sym = SDLK_UP;    break;
496 		}
497 	}
498 */
499 	/* If UNICODE is on, get the UNICODE value for the key */
500 	keysym->unicode = 0;
501 
502 #if 0 // !!TODO:unicode
503 
504 	if ( SDL_TranslateUNICODE )
505     {
506 		/* Populate the unicode field with the ASCII value */
507 		keysym->unicode = scancode;
508 	}
509 #endif
510 
511     //!!
512     //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
513     //    keysym->scancode, keysym->sym, keysym->mod);
514     //SDL_TRACE(debug); //!!
515 
516 	return(keysym);
517 }
518 
519 } /* extern "C" */
520 
521 
522