1#include "epoc_sdl.h"
2
3#include <stdio.h>
4#undef NULL
5extern "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
25extern "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 */
32static SDLKey keymap[MAX_SCANCODE];
33static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
34void DisableKeyBlocking(_THIS);
35//} /* extern "C" */
36
37SDLKey* KeyMap()
38	{
39	return keymap;
40	}
41
42TBool isCursorVisible = EFalse;
43
44void 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
247int 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
411extern "C" {
412
413void 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
434void EPOC_InitOSKeymap(_THIS)
435	{
436	ResetKeyMap();
437	EpocSdlEnv::ObserverEvent(MSDLObserver::EEventKeyMapInit ,0);
438	}
439
440static 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