blob: 2452daed6febc4807e68e89354cf455ecffc2409 [file] [log] [blame]
#include "epoc_sdl.h"
#include <stdio.h>
#undef NULL
extern "C" {
//#define DEBUG_TRACE_ENABLED
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_keysym.h"
#include "SDL_keyboard.h"
#include "SDL_events_c.h"
#include "SDL_timer.h"
} /* extern "C" */
#include "SDL_epocvideo.h"
#include "SDL_epocevents_c.h"
#include "sdlepocapi.h"
#include <eikenv.h>
#include<bautils.h>
extern "C"
{
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
}
//extern "C" {
/* The translation tables from a console scancode to a SDL keysym */
static SDLKey keymap[MAX_SCANCODE];
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym);
void DisableKeyBlocking(_THIS);
//} /* extern "C" */
SDLKey* KeyMap()
{
return keymap;
}
TBool isCursorVisible = EFalse;
void ResetKeyMap()
{
int i;
/* Initialize the key translation table */
for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
keymap[i] = SDLK_UNKNOWN;
/* Numbers */
for ( i = 0; i<32; ++i ){
keymap[' ' + i] = (SDLKey)(SDLK_SPACE+i);
}
/* e.g. Alphabet keys */
for ( i = 0; i<32; ++i ){
keymap['A' + i] = (SDLKey)(SDLK_a+i);
}
keymap[EStdKeyBackspace] = SDLK_BACKSPACE;
keymap[EStdKeyTab] = SDLK_TAB;
keymap[EStdKeyEnter] = SDLK_RETURN;
keymap[EStdKeyEscape] = SDLK_ESCAPE;
keymap[EStdKeySpace] = SDLK_SPACE;
keymap[EStdKeyPause] = SDLK_PAUSE;
keymap[EStdKeyHome] = SDLK_HOME;
keymap[EStdKeyEnd] = SDLK_END;
keymap[EStdKeyPageUp] = SDLK_PAGEUP;
keymap[EStdKeyPageDown] = SDLK_PAGEDOWN;
keymap[EStdKeyDelete] = SDLK_DELETE;
keymap[EStdKeyUpArrow] = SDLK_UP;
keymap[EStdKeyDownArrow] = SDLK_DOWN;
keymap[EStdKeyLeftArrow] = SDLK_LEFT;
keymap[EStdKeyRightArrow] = SDLK_RIGHT;
keymap[EStdKeyCapsLock] = SDLK_CAPSLOCK;
keymap[EStdKeyLeftShift] = SDLK_LSHIFT;
keymap[EStdKeyRightShift] = SDLK_RSHIFT;
keymap[EStdKeyLeftAlt] = SDLK_LALT;
keymap[EStdKeyRightAlt] = SDLK_RALT;
keymap[EStdKeyLeftCtrl] = SDLK_LCTRL;
keymap[EStdKeyRightCtrl] = SDLK_RCTRL;
keymap[EStdKeyLeftFunc] = SDLK_LMETA;
keymap[EStdKeyRightFunc] = SDLK_RMETA;
keymap[EStdKeyInsert] = SDLK_INSERT;
keymap[EStdKeyComma] = SDLK_COMMA;
keymap[EStdKeyFullStop] = SDLK_PERIOD;
keymap[EStdKeyForwardSlash] = SDLK_SLASH;
keymap[EStdKeyBackSlash] = SDLK_BACKSLASH;
keymap[EStdKeySemiColon] = SDLK_SEMICOLON;
keymap[EStdKeySingleQuote] = SDLK_QUOTE;
keymap[EStdKeyHash] = SDLK_HASH;
keymap[EStdKeySquareBracketLeft] = SDLK_LEFTBRACKET;
keymap[EStdKeySquareBracketRight] = SDLK_RIGHTBRACKET;
keymap[EStdKeyMinus] = SDLK_MINUS;
keymap[EStdKeyEquals] = SDLK_EQUALS;
keymap[EStdKeyF1] = SDLK_F1;
keymap[EStdKeyF2] = SDLK_F2;
keymap[EStdKeyF3] = SDLK_F3;
keymap[EStdKeyF4] = SDLK_F4;
keymap[EStdKeyF5] = SDLK_F5;
keymap[EStdKeyF6] = SDLK_F6;
keymap[EStdKeyF7] = SDLK_F7;
keymap[EStdKeyF8] = SDLK_F8;
keymap[EStdKeyF9] = SDLK_F9;
keymap[EStdKeyF10] = SDLK_F10;
keymap[EStdKeyF11] = SDLK_F11;
keymap[EStdKeyF12] = SDLK_F12;
keymap[EStdKeyXXX] = SDLK_RETURN; /* "fire" key */
keymap[EStdKeyDevice3] = SDLK_RETURN; /* "fire" key */
keymap[EStdKeyNkpAsterisk] = SDLK_ASTERISK;
keymap[EStdKeyYes] = SDLK_HOME; /* "call" key */
keymap[EStdKeyNo] = SDLK_END; /* "end call" key */
keymap[EStdKeyDevice0] = SDLK_SPACE; /* right menu key */
keymap[EStdKeyDevice1] = SDLK_ESCAPE; /* left menu key */
keymap[EStdKeyDevice2] = SDLK_POWER; /* power key */
keymap[EStdKeyMenu] = SDLK_MENU; // menu key
keymap[EStdKeyDevice6] = SDLK_LEFT; // Rocker (joystick) left
keymap[EStdKeyDevice7] = SDLK_RIGHT; // Rocker (joystick) right
keymap[EStdKeyDevice8] = SDLK_UP; // Rocker (joystick) up
keymap[EStdKeyDevice9] = SDLK_DOWN; // Rocker (joystick) down
keymap[EStdKeyLeftFunc] = SDLK_LALT; //chr?
keymap[EStdKeyRightFunc] = SDLK_RALT;
keymap[EStdKeyDeviceA] = SDLK_RETURN; /* "fire" key */
///////////////////////////////////////////////////////////
/*
RFs fs;
if(KErrNone == fs.Connect())
{
RArray<TInt> array;
TRAPD(err, ReadL(fs, array));
if(err == KErrNone && array.Count() > 0)
{
SDLKey temp[MAX_SCANCODE];
Mem::Copy(temp, keymap, MAX_SCANCODE * sizeof(SDLKey));
for(TInt k = 0; k < array.Count(); k+= 2)
{
const TInt oldval = array[k];
const TInt newval = array[k + 1];
if(oldval >= 0 && oldval < MAX_SCANCODE && newval >= 0 && newval < MAX_SCANCODE)
{
keymap[oldval] = temp[newval];
}
}
}
array.Close();
}
fs.Close();*/
///////////////////////////////////////////////////////////
keymap[EStdKeyNumLock] = SDLK_NUMLOCK;
keymap[EStdKeyScrollLock] = SDLK_SCROLLOCK;
keymap[EStdKeyNkpForwardSlash] = SDLK_KP_DIVIDE;
keymap[EStdKeyNkpAsterisk] = SDLK_KP_MULTIPLY;
keymap[EStdKeyNkpMinus] = SDLK_KP_MINUS;
keymap[EStdKeyNkpPlus] = SDLK_KP_PLUS;
keymap[EStdKeyNkpEnter] = SDLK_KP_ENTER;
keymap[EStdKeyNkp1] = SDLK_KP1;
keymap[EStdKeyNkp2] = SDLK_KP2;
keymap[EStdKeyNkp3] = SDLK_KP3;
keymap[EStdKeyNkp4] = SDLK_KP4;
keymap[EStdKeyNkp5] = SDLK_KP5;
keymap[EStdKeyNkp6] = SDLK_KP6;
keymap[EStdKeyNkp7] = SDLK_KP7;
keymap[EStdKeyNkp8] = SDLK_KP8;
keymap[EStdKeyNkp9] = SDLK_KP9;
keymap[EStdKeyNkp0] = SDLK_KP0;
keymap[EStdKeyNkpFullStop] = SDLK_KP_PERIOD;
/*
keymap[EStdKeyMenu] = SDLK_MENU; should be, but not yet
keymap[EStdKeyBacklightOn] =
keymap[EStdKeyBacklightOff] =
keymap[EStdKeyBacklightToggle] =
keymap[EStdKeyIncContrast] =
keymap[EStdKeyDecContrast] =
keymap[EStdKeySliderDown] =
keymap[EStdKeySliderUp] =
keymap[EStdKeyDictaphonePlay] =
keymap[EStdKeyDictaphoneStop] =
keymap[EStdKeyDictaphoneRecord] =
keymap[EStdKeyHelp] =
keymap[EStdKeyOff] =
keymap[EStdKeyDial] =
keymap[EStdKeyIncVolume] =
keymap[EStdKeyDecVolume] =
keymap[EStdKeyDevice0] =
keymap[EStdKeyDevice1] =
keymap[EStdKeyDevice2] =
keymap[EStdKeyDevice3] =
keymap[EStdKeyDevice4] =
keymap[EStdKeyDevice5] =
keymap[EStdKeyDevice6] =
keymap[EStdKeyDevice7] =
keymap[EStdKeyDevice8] =
keymap[EStdKeyDevice9] =
keymap[EStdKeyDeviceA] =
keymap[EStdKeyDeviceB] =
keymap[EStdKeyDeviceC] =
keymap[EStdKeyDeviceD] =
keymap[EStdKeyDeviceE] =
keymap[EStdKeyDeviceF] =
keymap[EStdKeyApplication0] =
keymap[EStdKeyApplication1] =
keymap[EStdKeyApplication2] =
keymap[EStdKeyApplication3] =
keymap[EStdKeyApplication4] =
keymap[EStdKeyApplication5] =
keymap[EStdKeyApplication6] =
keymap[EStdKeyApplication7] =
keymap[EStdKeyApplication8] =
keymap[EStdKeyApplication9] =
keymap[EStdKeyApplicationA] =
keymap[EStdKeyApplicationB] =
keymap[EStdKeyApplicationC] =
keymap[EStdKeyApplicationD] =
keymap[EStdKeyApplicationE] =
keymap[EStdKeyApplicationF] =
keymap[EStdKeyYes] =
keymap[EStdKeyNo] =
keymap[EStdKeyIncBrightness] =
keymap[EStdKeyDecBrightness] =
keymap[EStdKeyCaseOpen] =
keymap[EStdKeyCaseClose] = */
}
int EPOC_HandleWsEvent(_THIS, const TWsEvent& aWsEvent)
{
int posted = 0;
SDL_keysym keysym;
// SDL_TRACE1("hws %d", aWsEvent.Type());
switch (aWsEvent.Type())
{
case EEventPointer: /* Mouse pointer events */
{
/* const TPointerCursorMode mode = EpocSdlEnv::PointerMode();
if(mode == EPointerCursorNone)
{
return 0; //TODO: Find out why events are get despite of cursor should be off
}
*/
const TPointerEvent* pointerEvent = aWsEvent.Pointer();
const TPoint mousePos = EpocSdlEnv::WindowCoordinates(pointerEvent->iPosition);
/*!! TODO Pointer do not yet work properly
//SDL_TRACE1("SDL: EPOC_HandleWsEvent, pointerEvent->iType=%d", pointerEvent->iType); //!!
if (Private->EPOC_ShrinkedHeight) {
mousePos.iY <<= 1; // Scale y coordinate to shrinked screen height
}
if (Private->EPOC_ShrinkedWidth) {
mousePos.iX <<= 1; // Scale x coordinate to shrinked screen width
}
*/
posted += SDL_PrivateMouseMotion(0, 0, mousePos.iX, mousePos.iY); /* Absolute position on screen */
switch (pointerEvent->iType)
{
case TPointerEvent::EButton1Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
break;
case TPointerEvent::EButton1Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
break;
case TPointerEvent::EButton2Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_RIGHT, 0, 0);
break;
case TPointerEvent::EButton2Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_RIGHT, 0, 0);
break;
case TPointerEvent::EButton3Down:
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_MIDDLE, 0, 0);
break;
case TPointerEvent::EButton3Up:
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_MIDDLE, 0, 0);
break;
} // switch
break;
}
case EEventKeyDown: /* Key events */
{
#ifdef SYMBIAN_CRYSTAL
// special case: 9300/9500 rocker down, simulate left mouse button
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
{
const TPointerCursorMode mode = Private->EPOC_WsSession.PointerCursorMode();
if(mode != EPointerCursorNone)
posted += SDL_PrivateMouseButton(SDL_PRESSED, SDL_BUTTON_LEFT, 0, 0);
}
#endif
(void*)TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym);
#ifndef DISABLE_JOYSTICK
/* Special handling */
switch((int)keysym.sym) {
case SDLK_CAPSLOCK:
if (!isCursorVisible) {
/* Enable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Visible);
}
else {
/* Disable virtual cursor */
HAL::Set(HAL::EMouseState, HAL::EMouseState_Invisible);
}
isCursorVisible = !isCursorVisible;
break;
}
#endif
posted += SDL_PrivateKeyboard(SDL_PRESSED, &keysym);
break;
}
case EEventKeyUp: /* Key events */
{
#ifdef SYMBIAN_CRYSTAL
// special case: 9300/9500 rocker up, simulate left mouse button
if (aWsEvent.Key()->iScanCode == EStdKeyDeviceA)
{
posted += SDL_PrivateMouseButton(SDL_RELEASED, SDL_BUTTON_LEFT, 0, 0);
}
#endif
posted += SDL_PrivateKeyboard(SDL_RELEASED, TranslateKey(_this, aWsEvent.Key()->iScanCode, &keysym));
break;
}
case EEventFocusGained: /* SDL window got focus */
{
Private->iIsWindowFocused = ETrue;
posted += SDL_PrivateAppActive(1, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
/* Draw window background and screen buffer */
DisableKeyBlocking(_this); //Markus: guess why:-)
//RedrawWindowL(_this);
break;
}
case EEventFocusLost: /* SDL window lost focus */
{
Private->iIsWindowFocused = EFalse;
posted += SDL_PrivateAppActive(0, SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS);
break;
}
case EEventModifiersChanged:
{
TModifiersChangedEvent* modEvent = aWsEvent.ModifiersChanged();
TUint modstate = KMOD_NONE;
if (modEvent->iModifiers == EModifierLeftShift)
modstate |= KMOD_LSHIFT;
if (modEvent->iModifiers == EModifierRightShift)
modstate |= KMOD_RSHIFT;
if (modEvent->iModifiers == EModifierLeftCtrl)
modstate |= KMOD_LCTRL;
if (modEvent->iModifiers == EModifierRightCtrl)
modstate |= KMOD_RCTRL;
if (modEvent->iModifiers == EModifierLeftAlt)
modstate |= KMOD_LALT;
if (modEvent->iModifiers == EModifierRightAlt)
modstate |= KMOD_RALT;
if (modEvent->iModifiers == EModifierLeftFunc)
modstate |= KMOD_LMETA;
if (modEvent->iModifiers == EModifierRightFunc)
modstate |= KMOD_RMETA;
if (modEvent->iModifiers == EModifierCapsLock)
modstate |= KMOD_CAPS;
SDL_SetModState(STATIC_CAST(SDLMod,(modstate | KMOD_LSHIFT)));
break;
}
case EEventScreenDeviceChanged:
{
EpocSdlEnv::WaitDeviceChange();
}
break;
default:
break;
}
return posted;
}
extern "C" {
void EPOC_PumpEvents(_THIS)
{
MEventQueue& events = EpocSdlEnv::EventQueue();
while(events.HasData())
{
events.Lock();
//there have to be a copy, so we can release
//lock immediately. HandleWsEvent may cause
//deadlock otherwise.
const TWsEvent event = events.Shift();
events.Unlock();
// const TWsEvent& event = events.Top();
EPOC_HandleWsEvent(_this, event);
// events.Shift();
}
}
void EPOC_InitOSKeymap(_THIS)
{
ResetKeyMap();
EpocSdlEnv::ObserverEvent(MSDLObserver::EEventKeyMapInit ,0);
}
static SDL_keysym *TranslateKey(_THIS, int scancode, SDL_keysym *keysym)
{
// char debug[256];
//SDL_TRACE1("SDL: TranslateKey, scancode=%d", scancode); //!!
/* Set the keysym information */
keysym->scancode = scancode;
if ((scancode >= MAX_SCANCODE) &&
((scancode - ENonCharacterKeyBase + 0x0081) >= MAX_SCANCODE)) {
SDL_SetError("Too big scancode");
keysym->scancode = SDLK_UNKNOWN;
keysym->mod = KMOD_NONE;
return keysym;
}
keysym->mod = SDL_GetModState();
/* Handle function keys: F1, F2, F3 ... */
if (keysym->mod & KMOD_META) {
if (scancode >= 'A' && scancode < ('A' + 24)) { /* first 32 alphabet keys */
switch(scancode) {
case 'Q': scancode = EStdKeyF1; break;
case 'W': scancode = EStdKeyF2; break;
case 'E': scancode = EStdKeyF3; break;
case 'R': scancode = EStdKeyF4; break;
case 'T': scancode = EStdKeyF5; break;
case 'Y': scancode = EStdKeyF6; break;
case 'U': scancode = EStdKeyF7; break;
case 'I': scancode = EStdKeyF8; break;
case 'A': scancode = EStdKeyF9; break;
case 'S': scancode = EStdKeyF10; break;
case 'D': scancode = EStdKeyF11; break;
case 'F': scancode = EStdKeyF12; break;
}
keysym->sym = keymap[scancode];
}
}
if (scancode >= ENonCharacterKeyBase) {
// Non character keys
keysym->sym = keymap[scancode -
ENonCharacterKeyBase + 0x0081]; // !!hard coded
} else {
keysym->sym = keymap[scancode];
}
/* Remap the arrow keys if the device is rotated */
/*
if (Private->EPOC_ScreenOrientation == CFbsBitGc::EGraphicsOrientationRotated270) {
switch(keysym->sym) {
case SDLK_UP: keysym->sym = SDLK_LEFT; break;
case SDLK_DOWN: keysym->sym = SDLK_RIGHT; break;
case SDLK_LEFT: keysym->sym = SDLK_DOWN; break;
case SDLK_RIGHT:keysym->sym = SDLK_UP; break;
}
}
*/
/* If UNICODE is on, get the UNICODE value for the key */
keysym->unicode = 0;
#if 0 // !!TODO:unicode
if ( SDL_TranslateUNICODE )
{
/* Populate the unicode field with the ASCII value */
keysym->unicode = scancode;
}
#endif
//!!
//sprintf(debug, "SDL: TranslateKey: keysym->scancode=%d, keysym->sym=%d, keysym->mod=%d",
// keysym->scancode, keysym->sym, keysym->mod);
//SDL_TRACE(debug); //!!
return(keysym);
}
} /* extern "C" */