1/*
2    SDL - Simple DirectMedia Layer
3    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  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@libsdl.org
21*/
22#include "SDL_config.h"
23
24/*
25    SDL_epocevents.cpp
26    Handle the event stream, converting Epoc events into SDL events
27
28    Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
29*/
30
31
32#include <stdio.h>
33#undef NULL
34
35extern "C" {
36#include "SDL_error.h"
37#include "SDL_video.h"
38#include "SDL_keysym.h"
39#include "SDL_keyboard.h"
40#include "SDL_timer.h"
41#include "../../events/SDL_events_c.h"
42}; /* extern "C" */
43
44#include "SDL_epocvideo.h"
45#include "SDL_epocevents_c.h"
46
47#include <hal.h>
48
49extern "C" {
50/* The translation tables from a console scancode to a SDL keysym */
51static SDLKey keymap[MAX_SCANCODE];
52static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym);
53}; /* extern "C" */
54
55TBool isCursorVisible = ETrue;
56
57int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
58{
59    int posted = 0;
60    SDL_keysym keysym;
61
62
63    switch (aWsEvent.Type()) {
64
65    case EEventPointer: /* Mouse pointer events */
66    {
67        const TPointerEvent* pointerEvent = aWsEvent.Pointer();
68        TPoint mousePos = pointerEvent->iPosition;
69
70        //SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
71
72        if (Private->EPOC_ShrinkedHeight) {
73            mousePos.iY <<= 1; /* Scale y coordinate to shrinked screen height */
74        }
75		posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
76        if (pointerEvent->iType==TPointerEvent::EButton1Down) {
77            posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
78        }
79        else if (pointerEvent->iType==TPointerEvent::EButton1Up) {
80			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
81        }
82        else if (pointerEvent->iType==TPointerEvent::EButton2Down) {
83            posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
84        }
85        else if (pointerEvent->iType==TPointerEvent::EButton2Up) {
86			posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
87        }
88	    //!!posted += SDL_PrivateKeyboard(SDL_PRESSED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym));
89        break;
90    }
91
92    case EEventKeyDown: /* Key events */
93    {
94       (void*)TranslateKey(aWsEvent.Key()->iScanCode, &keysym);
95
96        /* Special handling */
97        switch((int)keysym.sym) {
98        case SDLK_CAPSLOCK:
99            if (!isCursorVisible) {
100                /* Enable virtual cursor */
101	            HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
102            }
103            else {
104                /* Disable virtual cursor */
105                HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
106            }
107            isCursorVisible = !isCursorVisible;
108            break;
109        }
110
111	    posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
112        break;
113	}
114
115    case EEventKeyUp: /* Key events */
116    {
117	    posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(aWsEvent.Key()->iScanCode, &keysym));
118        break;
119	}
120
121    case EEventFocusGained: /* SDL window got focus */
122    {
123        //Private->EPOC_IsWindowFocused = ETrue;
124        /* Draw window background and screen buffer */
125        RedrawWindowL(_this);
126        break;
127    }
128
129    case EEventFocusLost: /* SDL window lost focus */
130    {
131        //Private->EPOC_IsWindowFocused = EFalse;
132
133        // Wait and eat events until focus is gained again
134        /*
135	    while (ETrue) {
136            Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
137            User::WaitForRequest(Private->EPOC_WsEventStatus);
138		    Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
139            TInt eventType = Private->EPOC_WsEvent.Type();
140		    Private->EPOC_WsEventStatus = KRequestPending;
141		    //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
142            if (eventType == EEventFocusGained) {
143                RedrawWindowL(_this);
144                break;
145            }
146	    }
147        */
148        break;
149    }
150
151    case EEventModifiersChanged:
152    {
153	    TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
154        TUint modstate = KMOD_NONE;
155        if (modEvent->iModifiers == EModifierLeftShift)
156            modstate |= KMOD_LSHIFT;
157        if (modEvent->iModifiers == EModifierRightShift)
158            modstate |= KMOD_RSHIFT;
159        if (modEvent->iModifiers == EModifierLeftCtrl)
160            modstate |= KMOD_LCTRL;
161        if (modEvent->iModifiers == EModifierRightCtrl)
162            modstate |= KMOD_RCTRL;
163        if (modEvent->iModifiers == EModifierLeftAlt)
164            modstate |= KMOD_LALT;
165        if (modEvent->iModifiers == EModifierRightAlt)
166            modstate |= KMOD_RALT;
167        if (modEvent->iModifiers == EModifierLeftFunc)
168            modstate |= KMOD_LMETA;
169        if (modEvent->iModifiers == EModifierRightFunc)
170            modstate |= KMOD_RMETA;
171        if (modEvent->iModifiers == EModifierCapsLock)
172            modstate |= KMOD_CAPS;
173        SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
174        break;
175    }
176    default:
177        break;
178	}
179
180    return posted;
181}
182
183extern "C" {
184
185void EPOC_PumpEvents(_THIS)
186{
187    int posted = 0; // !! Do we need this?
188    //Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
189	while (Private->EPOC_WsEventStatus != KRequestPending) {
190
191		Private->EPOC_WsSession.GetEvent(Private->EPOC_WsEvent);
192		posted = EPOC_HandleWsEvent(_this, Private->EPOC_WsEvent);
193		Private->EPOC_WsEventStatus = KRequestPending;
194		Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
195	}
196}
197
198
199void EPOC_InitOSKeymap(_THIS)
200{
201	int i;
202
203	/* Initialize the key translation table */
204	for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
205		keymap[i] = SDLK_UNKNOWN;
206
207
208	/* Numbers */
209	for ( i = 0; i<32; ++i ){
210		keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
211	}
212	/* e.g. Alphabet keys */
213	for ( i = 0; i<32; ++i ){
214		keymap['A' + i] = (SDLKey)(SDLK_a+i);
215	}
216
217	keymap[EStdKeyBackspace]    = SDLK_BACKSPACE;
218	keymap[EStdKeyTab]          = SDLK_TAB;
219	keymap[EStdKeyEnter]        = SDLK_RETURN;
220	keymap[EStdKeyEscape]       = SDLK_ESCAPE;
221   	keymap[EStdKeySpace]        = SDLK_SPACE;
222   	keymap[EStdKeyPause]        = SDLK_PAUSE;
223   	keymap[EStdKeyHome]         = SDLK_HOME;
224   	keymap[EStdKeyEnd]          = SDLK_END;
225   	keymap[EStdKeyPageUp]       = SDLK_PAGEUP;
226   	keymap[EStdKeyPageDown]     = SDLK_PAGEDOWN;
227	keymap[EStdKeyDelete]       = SDLK_DELETE;
228	keymap[EStdKeyUpArrow]      = SDLK_UP;
229	keymap[EStdKeyDownArrow]    = SDLK_DOWN;
230	keymap[EStdKeyLeftArrow]    = SDLK_LEFT;
231	keymap[EStdKeyRightArrow]   = SDLK_RIGHT;
232	keymap[EStdKeyCapsLock]     = SDLK_CAPSLOCK;
233	keymap[EStdKeyLeftShift]    = SDLK_LSHIFT;
234	keymap[EStdKeyRightShift]   = SDLK_RSHIFT;
235	keymap[EStdKeyLeftAlt]      = SDLK_LALT;
236	keymap[EStdKeyRightAlt]     = SDLK_RALT;
237	keymap[EStdKeyLeftCtrl]     = SDLK_LCTRL;
238	keymap[EStdKeyRightCtrl]    = SDLK_RCTRL;
239	keymap[EStdKeyLeftFunc]     = SDLK_LMETA;
240	keymap[EStdKeyRightFunc]    = SDLK_RMETA;
241	keymap[EStdKeyInsert]       = SDLK_INSERT;
242	keymap[EStdKeyComma]        = SDLK_COMMA;
243	keymap[EStdKeyFullStop]     = SDLK_PERIOD;
244	keymap[EStdKeyForwardSlash] = SDLK_SLASH;
245	keymap[EStdKeyBackSlash]    = SDLK_BACKSLASH;
246	keymap[EStdKeySemiColon]    = SDLK_SEMICOLON;
247	keymap[EStdKeySingleQuote]  = SDLK_QUOTE;
248	keymap[EStdKeyHash]         = SDLK_HASH;
249	keymap[EStdKeySquareBracketLeft]    = SDLK_LEFTBRACKET;
250	keymap[EStdKeySquareBracketRight]   = SDLK_RIGHTBRACKET;
251	keymap[EStdKeyMinus]        = SDLK_MINUS;
252	keymap[EStdKeyEquals]       = SDLK_EQUALS;
253
254   	keymap[EStdKeyF1]          = SDLK_F1;  /* chr + q */
255   	keymap[EStdKeyF2]          = SDLK_F2;  /* chr + w */
256   	keymap[EStdKeyF3]          = SDLK_F3;  /* chr + e */
257   	keymap[EStdKeyF4]          = SDLK_F4;  /* chr + r */
258   	keymap[EStdKeyF5]          = SDLK_F5;  /* chr + t */
259   	keymap[EStdKeyF6]          = SDLK_F6;  /* chr + y */
260   	keymap[EStdKeyF7]          = SDLK_F7;  /* chr + i */
261   	keymap[EStdKeyF8]          = SDLK_F8;  /* chr + o */
262
263   	keymap[EStdKeyF9]          = SDLK_F9;  /* chr + a */
264   	keymap[EStdKeyF10]         = SDLK_F10; /* chr + s */
265   	keymap[EStdKeyF11]         = SDLK_F11; /* chr + d */
266   	keymap[EStdKeyF12]         = SDLK_F12; /* chr + f */
267
268    /* !!TODO
269	EStdKeyNumLock=0x1b,
270	EStdKeyScrollLock=0x1c,
271
272	EStdKeyNkpForwardSlash=0x84,
273	EStdKeyNkpAsterisk=0x85,
274	EStdKeyNkpMinus=0x86,
275	EStdKeyNkpPlus=0x87,
276	EStdKeyNkpEnter=0x88,
277	EStdKeyNkp1=0x89,
278	EStdKeyNkp2=0x8a,
279	EStdKeyNkp3=0x8b,
280	EStdKeyNkp4=0x8c,
281	EStdKeyNkp5=0x8d,
282	EStdKeyNkp6=0x8e,
283	EStdKeyNkp7=0x8f,
284	EStdKeyNkp8=0x90,
285	EStdKeyNkp9=0x91,
286	EStdKeyNkp0=0x92,
287	EStdKeyNkpFullStop=0x93,
288    EStdKeyMenu=0x94,
289    EStdKeyBacklightOn=0x95,
290    EStdKeyBacklightOff=0x96,
291    EStdKeyBacklightToggle=0x97,
292    EStdKeyIncContrast=0x98,
293    EStdKeyDecContrast=0x99,
294    EStdKeySliderDown=0x9a,
295    EStdKeySliderUp=0x9b,
296    EStdKeyDictaphonePlay=0x9c,
297    EStdKeyDictaphoneStop=0x9d,
298    EStdKeyDictaphoneRecord=0x9e,
299    EStdKeyHelp=0x9f,
300    EStdKeyOff=0xa0,
301    EStdKeyDial=0xa1,
302    EStdKeyIncVolume=0xa2,
303    EStdKeyDecVolume=0xa3,
304    EStdKeyDevice0=0xa4,
305    EStdKeyDevice1=0xa5,
306    EStdKeyDevice2=0xa6,
307    EStdKeyDevice3=0xa7,
308    EStdKeyDevice4=0xa8,
309    EStdKeyDevice5=0xa9,
310    EStdKeyDevice6=0xaa,
311    EStdKeyDevice7=0xab,
312    EStdKeyDevice8=0xac,
313    EStdKeyDevice9=0xad,
314    EStdKeyDeviceA=0xae,
315    EStdKeyDeviceB=0xaf,
316    EStdKeyDeviceC=0xb0,
317    EStdKeyDeviceD=0xb1,
318    EStdKeyDeviceE=0xb2,
319    EStdKeyDeviceF=0xb3,
320    EStdKeyApplication0=0xb4,
321    EStdKeyApplication1=0xb5,
322    EStdKeyApplication2=0xb6,
323    EStdKeyApplication3=0xb7,
324    EStdKeyApplication4=0xb8,
325    EStdKeyApplication5=0xb9,
326    EStdKeyApplication6=0xba,
327    EStdKeyApplication7=0xbb,
328    EStdKeyApplication8=0xbc,
329    EStdKeyApplication9=0xbd,
330    EStdKeyApplicationA=0xbe,
331    EStdKeyApplicationB=0xbf,
332    EStdKeyApplicationC=0xc0,
333    EStdKeyApplicationD=0xc1,
334    EStdKeyApplicationE=0xc2,
335    EStdKeyApplicationF=0xc3,
336    EStdKeyYes=0xc4,
337    EStdKeyNo=0xc5,
338    EStdKeyIncBrightness=0xc6,
339    EStdKeyDecBrightness=0xc7,
340    EStdKeyCaseOpen=0xc8,
341    EStdKeyCaseClose=0xc9
342    */
343
344}
345
346
347
348static SDL_keysym *TranslateKey(int scancode, SDL_keysym *keysym)
349{
350    char debug[256];
351    //SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
352
353	/* Set the keysym information */
354
355	keysym->scancode = scancode;
356
357    if ((scancode >= MAX_SCANCODE) &&
358        ((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
359        SDL_SetError("Too big scancode");
360        keysym->scancode = SDLK_UNKNOWN;
361	    keysym->mod = KMOD_NONE;
362        return keysym;
363    }
364
365	keysym->mod = SDL_GetModState(); //!!Is this right??
366
367    /* Handle function keys: F1, F2, F3 ... */
368    if (keysym->mod & KMOD_META) {
369        if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphapet keys */
370            switch(scancode) {
371                case 'Q': scancode = EStdKeyF1; break;
372                case 'W': scancode = EStdKeyF2; break;
373                case 'E': scancode = EStdKeyF3; break;
374                case 'R': scancode = EStdKeyF4; break;
375                case 'T': scancode = EStdKeyF5; break;
376                case 'Y': scancode = EStdKeyF6; break;
377                case 'U': scancode = EStdKeyF7; break;
378                case 'I': scancode = EStdKeyF8; break;
379                case 'A': scancode = EStdKeyF9; break;
380                case 'S': scancode = EStdKeyF10; break;
381                case 'D': scancode = EStdKeyF11; break;
382                case 'F': scancode = EStdKeyF12; break;
383            }
384            keysym->sym = keymap[scancode];
385        }
386    }
387
388    if (scancode >= ENonCharacterKeyBase) {
389        // Non character keys
390	    keysym->sym = keymap[scancode -
391            ENonCharacterKeyBase + 0x0081]; // !!hard coded
392    } else {
393	    keysym->sym = keymap[scancode];
394    }
395
396
397	/* If UNICODE is on, get the UNICODE value for the key */
398	keysym->unicode = 0;
399
400#if 0 // !!TODO:unicode
401
402	if ( SDL_TranslateUNICODE )
403    {
404		/* Populate the unicode field with the ASCII value */
405		keysym->unicode = scancode;
406	}
407#endif
408
409    //!!
410    //sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
411    //    keysym->scancode, keysym->sym, keysym->mod);
412    //SDL_TRACE(debug); //!!
413
414	return(keysym);
415}
416
417}; /* extern "C" */
418
419
420