2
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
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.
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.
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
20
slouken@devolution.com
25
Handle the event stream, converting Epoc events into SDL events
27
Epoc version by Hannu Viitala (hannu.j.viitala@mbnet.fi)
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"
43
#include "SDL_epocvideo.h"
44
#include "SDL_epocevents_c.h"
46
#include<linereader.h>
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);
59
TBool isCursorVisible = EFalse;
61
int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
66
// SDL_TRACE1("hws %d", aWsEvent.Type());
68
switch (aWsEvent.Type())
70
case EEventPointer: /* Mouse pointer events */
73
const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
75
if(mode == EPointerCursorNone)
77
return 0; //TODO: Find out why events are get despite of cursor should be off
80
const TPointerEvent* pointerEvent = aWsEvent.Pointer();
81
TPoint mousePos = pointerEvent->iPosition;
83
/*!! TODO Pointer do not yet work properly
84
//SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
86
if (Private->EPOC_ShrinkedHeight) {
87
mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
89
if (Private->EPOC_ShrinkedWidth) {
90
mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
94
posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
96
switch (pointerEvent->iType)
98
case TPointerEvent::EButton1Down:
99
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
101
case TPointerEvent::EButton1Up:
102
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
104
case TPointerEvent::EButton2Down:
105
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
107
case TPointerEvent::EButton2Up:
108
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
110
case TPointerEvent::EButton3Down:
111
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
113
case TPointerEvent::EButton3Up:
114
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
120
case EEventKeyDown: /* Key events */
122
#ifdef SYMBIAN_CRYSTAL
123
// special case: 9300/9500 rocker down, simulate left mouse button
124
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
126
const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
127
if(mode != EPointerCursorNone)
128
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
131
(void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
133
#ifndef DISABLE_JOYSTICK
134
/* Special handling */
135
switch((int)keysym.sym) {
137
if (!isCursorVisible) {
138
/* Enable virtual cursor */
139
HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
142
/* Disable virtual cursor */
143
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
145
isCursorVisible = !isCursorVisible;
149
posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
153
case EEventKeyUp: /* Key events */
155
#ifdef SYMBIAN_CRYSTAL
156
// special case: 9300/9500 rocker up, simulate left mouse button
157
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
159
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
162
posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
166
case EEventFocusGained: /* SDL window got focus */
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:-)
173
RedrawWindowL(_this);
177
case EEventFocusLost: /* SDL window lost focus */
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"));
192
Private->EPOC_IsWindowFocused = EFalse;
194
posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
199
g.Construct(TUint32(&g), EFalse);
200
g.EnableReceiptOfFocus(EFalse);
202
w.Construct(g, TUint32(&w));
203
w.SetExtent(TPoint(0, 0), Private->EPOC_WsWindow.Size());
204
w.SetOrdinalPosition(0);
211
Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(Private->EPOC_WsWindowGroupID, -1);
218
const TInt curr = Private->EPOC_WsSession.GetFocusWindowGroup();
219
if(curr != Private->EPOC_WsWindowGroupID)
225
if(1 < Private->EPOC_WsSession.GetWindowGroupOrdinalPriority(Private->EPOC_WsWindowGroupID))
227
Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, -1);
229
Private->EPOC_WsSession.SetWindowGroupOrdinalPosition(focus, 0);
232
/*//and the request redraw
233
TRawEvent redrawEvent;
234
redrawEvent.Set(TRawEvent::ERedraw);
235
Private->EPOC_WsSession.SimulateRawEvent(redrawEvent);
236
Private->EPOC_WsSession.Flush();*/
239
// Wait and eat events until focus is gained again
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);
256
case EEventModifiersChanged:
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)));
290
void EPOC_PumpEvents(_THIS)
292
int posted = 0; // !! Do we need this?
293
//Private->EPOC_WsSession.EventReady(&Private->EPOC_WsEventStatus);
294
while (Private->EPOC_WsEventStatus != KRequestPending) {
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);
304
_LIT(KMapFileName, "C:\\sdl_info\\sdlkeymap.cfg");
305
LOCAL_C void ReadL(RFs& aFs, RArray<TInt>& aArray)
308
TFileName name(KMapFileName);
309
for(TInt i = 'z'; drive < 0 && i >= 'a'; i--)
311
name[0] = (TUint16)i;
312
if(BaflUtils::FileExists(aFs, name))
317
CLineReader* reader = CLineReader::NewLC(aFs, name);
318
while(reader->NextL())
320
TPtrC ln = reader->Current();
325
const TPtrC token = line.NextToken();
326
if(token.Length() == 0)
332
User::LeaveIfError(lex.Val(value));
333
User::LeaveIfError(aArray.Append(value));
338
CleanupStack::PopAndDestroy();
342
void EPOC_InitOSKeymap(_THIS)
346
/* Initialize the key translation table */
347
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
348
keymap[i] = SDLK_UNKNOWN;
352
for ( i = 0; i<32; ++i ){
353
keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
355
/* e.g. Alphabet keys */
356
for ( i = 0; i<32; ++i ){
357
keymap['A' + i] = (SDLKey)(SDLK_a+i);
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;
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 */
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 */
411
#ifndef SYMBIAN_CRYSTAL
414
keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */
416
keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */
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 */
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 */
437
///////////////////////////////////////////////////////////
440
if(KErrNone == fs.Connect())
443
TRAPD(err, ReadL(fs, array));
444
if(err == KErrNone && array.Count() > 0)
447
SDLKey temp[MAX_SCANCODE];
448
Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
450
for(TInt k = 0; k < array.Count(); k+= 2)
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)
456
keymap[oldval] = temp[newval];
464
///////////////////////////////////////////////////////////
468
EStdKeyScrollLock=0x1c,
470
EStdKeyNkpForwardSlash=0x84,
471
EStdKeyNkpAsterisk=0x85,
472
EStdKeyNkpMinus=0x86,
474
EStdKeyNkpEnter=0x88,
485
EStdKeyNkpFullStop=0x93,
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,
500
EStdKeyIncVolume=0xa2,
501
EStdKeyDecVolume=0xa3,
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,
536
EStdKeyIncBrightness=0xc6,
537
EStdKeyDecBrightness=0xc7,
538
EStdKeyCaseOpen=0xc8,
539
EStdKeyCaseClose=0xc9
546
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
549
//SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
551
/* Set the keysym information */
553
keysym->scancode = scancode;
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;
563
keysym->mod = SDL_GetModState();
565
/* Handle function keys: F1, F2, F3 ... */
566
if (keysym->mod & KMOD_META) {
567
if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
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;
582
keysym->sym = keymap[scancode];
586
if (scancode >= ENonCharacterKeyBase) {
587
// Non character keys
588
keysym->sym = keymap[scancode -
589
ENonCharacterKeyBase + 0x0081]; // !!hard coded
591
keysym->sym = keymap[scancode];
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;
604
/* If UNICODE is on, get the UNICODE value for the key */
607
#if 0 // !!TODO:unicode
609
if ( SDL_TranslateUNICODE )
611
/* Populate the unicode field with the ASCII value */
612
keysym->unicode = scancode;
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); //!!