scummvm/backends/events/wincesdl/wincesdl-events.cpp
2019-04-15 08:06:39 +03:00

344 lines
10 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#ifdef _WIN32_WCE
#include "common/config-manager.h"
#include "backends/events/wincesdl/wincesdl-events.h"
#include "backends/platform/wince/CEActionsPocket.h"
#include "backends/platform/wince/CEActionsSmartphone.h"
#include "backends/platform/wince/CEDevice.h"
#include "backends/platform/sdl/sdl.h"
WINCESdlEventSource::WINCESdlEventSource()
: _tapTime(0), _closeClick(false), _rbutton(false),
_graphicsMan(0) {
}
void WINCESdlEventSource::init(WINCESdlGraphicsManager *graphicsMan) {
assert(graphicsMan);
_graphicsMan = graphicsMan;
}
bool WINCESdlEventSource::processMouseEvent(Common::Event &event, int x, int y) {
event.mouse.x = x;
event.mouse.y = y;
// Update the "keyboard mouse" coords
_km.x = event.mouse.x * MULTIPLIER;
_km.y = event.mouse.y * MULTIPLIER;
// Adjust for the screen scaling
if (_graphicsMan->_zoomDown)
event.mouse.y += 240;
event.mouse.x = event.mouse.x * _graphicsMan->_scaleFactorXd / _graphicsMan->_scaleFactorXm;
event.mouse.y = event.mouse.y * _graphicsMan->_scaleFactorYd / _graphicsMan->_scaleFactorYm;
return true;
}
bool WINCESdlEventSource::pollEvent(Common::Event &event) {
SDL_Event ev;
ev.type = SDL_NOEVENT;
DWORD currentTime;
bool keyEvent = false;
bool freeLookActive = _graphicsMan->getFreeLookState();
int deltaX, deltaY;
memset(&event, 0, sizeof(Common::Event));
if (handleKbdMouse(event)) {
return true;
}
// If the screen changed, send an Common::EVENT_SCREEN_CHANGED
int screenID = _graphicsMan->getScreenChangeID();
if (screenID != _lastScreenID) {
_lastScreenID = screenID;
event.type = Common::EVENT_SCREEN_CHANGED;
return true;
}
CEDevice::wakeUp();
currentTime = GetTickCount();
while (SDL_PollEvent(&ev)) {
switch (ev.type) {
case SDL_KEYDOWN:
debug(1, "Key down %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
// KMOD_RESERVED is used if the key has been injected by an external buffer
if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) {
keyEvent = true;
_graphicsMan->_lastKeyPressed = ev.key.keysym.sym;
_graphicsMan->_keyRepeatTime = currentTime;
_graphicsMan->_keyRepeat = 0;
if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, true))
return true;
}
if (GUI_Actions::Instance()->mappingActive())
event.kbd.flags = 0xFF;
else if (ev.key.keysym.sym == SDLK_PAUSE) {
_graphicsMan->_lastKeyPressed = 0;
event.type = Common::EVENT_PREDICTIVE_DIALOG;
return true;
}
event.type = Common::EVENT_KEYDOWN;
if (!GUI::Actions::Instance()->mappingActive())
event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
else
event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
event.kbd.ascii ^= 0x20;
event.kbd.flags = Common::KBD_SHIFT;
}
return true;
case SDL_KEYUP:
debug(1, "Key up %X %s", ev.key.keysym.sym, SDL_GetKeyName((SDLKey)ev.key.keysym.sym));
// KMOD_RESERVED is used if the key has been injected by an external buffer
if (ev.key.keysym.mod != KMOD_RESERVED && !GUI::Actions::Instance()->mappingActive()) {
keyEvent = true;
_graphicsMan->_lastKeyPressed = 0;
if (!GUI_Actions::Instance()->mappingActive() && GUI_Actions::Instance()->performMapped(ev.key.keysym.sym, false))
return true;
}
if (GUI_Actions::Instance()->mappingActive())
event.kbd.flags = 0xFF;
else if (ev.key.keysym.sym == SDLK_PAUSE) {
_graphicsMan->_lastKeyPressed = 0;
return false; // chew up the show agi dialog key up event
}
event.type = Common::EVENT_KEYUP;
if (!GUI::Actions::Instance()->mappingActive())
event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym;
else
event.kbd.keycode = (Common::KeyCode)mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
event.kbd.ascii = mapKeyCE(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode, GUI::Actions::Instance()->mappingActive());
if (ev.key.keysym.mod == KMOD_RESERVED && ev.key.keysym.unicode == KMOD_SHIFT) {
event.kbd.ascii ^= 0x20;
event.kbd.flags = Common::KBD_SHIFT;
}
return true;
case SDL_MOUSEMOTION:
event.type = Common::EVENT_MOUSEMOVE;
if (!processMouseEvent(event, ev.motion.x, ev.motion.y)) {
return false;
}
// update KbdMouse
_km.x = ev.motion.x * MULTIPLIER;
_km.y = ev.motion.y * MULTIPLIER;
_graphicsMan->setMousePos(event.mouse.x, event.mouse.y);
return true;
case SDL_MOUSEBUTTONDOWN:
if (ev.button.button == SDL_BUTTON_LEFT)
event.type = Common::EVENT_LBUTTONDOWN;
else if (ev.button.button == SDL_BUTTON_RIGHT)
event.type = Common::EVENT_RBUTTONDOWN;
else
break;
if (!processMouseEvent(event, ev.button.x, ev.button.y)) {
return false;
}
// update KbdMouse
_km.x = ev.button.x * MULTIPLIER;
_km.y = ev.button.y * MULTIPLIER;
if (event.mouse.x > _tapX)
deltaX = event.mouse.x - _tapX;
else
deltaX = _tapX - event.mouse.x;
if (event.mouse.y > _tapY)
deltaY = event.mouse.y - _tapY;
else
deltaY = _tapY - event.mouse.y;
_closeClick = (deltaX <= 5 && deltaY <= 5);
if (!_isSmartphone) {
// handle double-taps
if (_tapTime) { // second tap
if (_closeClick && (GetTickCount() - _tapTime < 1000)) {
if (event.mouse.y <= 20 &&
_graphicsMan->_panelInitialized &&
!_graphicsMan->_noDoubleTapPT) {
// top of screen (show panel)
_graphicsMan->swap_panel_visibility();
} else if (!_graphicsMan->_noDoubleTapRMB) {
// right click
event.type = Common::EVENT_RBUTTONDOWN;
_rbutton = true;
}
}
_tapTime = 0;
} else {
_tapTime = GetTickCount();
_tapX = event.mouse.x;
_tapY = event.mouse.y;
}
}
if (freeLookActive && !_closeClick) {
_rbutton = false;
_tapTime = 0;
_tapX = event.mouse.x;
_tapY = event.mouse.y;
event.type = Common::EVENT_MOUSEMOVE;
_graphicsMan->setMousePos(event.mouse.x, event.mouse.y);
}
if (_graphicsMan->_toolbarHandler.action(event.mouse.x, event.mouse.y, true)) {
if (!_graphicsMan->_toolbarHandler.drawn()) {
_graphicsMan->_toolbarHighDrawn = false;
_graphicsMan->internUpdateScreen();
}
if (_graphicsMan->_newOrientation != _graphicsMan->_orientationLandscape) {
_graphicsMan->_orientationLandscape = _graphicsMan->_newOrientation;
_graphicsMan->_toolbarHighDrawn = false;
ConfMan.setInt("landscape", _graphicsMan->_orientationLandscape);
ConfMan.flushToDisk();
_graphicsMan->hotswapGFXMode();
}
return false;
}
return true;
case SDL_MOUSEBUTTONUP:
if (ev.button.button == SDL_BUTTON_LEFT)
event.type = Common::EVENT_LBUTTONUP;
else if (ev.button.button == SDL_BUTTON_RIGHT)
event.type = Common::EVENT_RBUTTONUP;
else
break;
if (_rbutton) {
event.type = Common::EVENT_RBUTTONUP;
_rbutton = false;
}
if (!processMouseEvent(event, ev.button.x, ev.button.y)) {
return false;
}
// update KbdMouse
_km.x = ev.button.x * MULTIPLIER;
_km.y = ev.button.y * MULTIPLIER;
if (freeLookActive && !_closeClick) {
_tapX = event.mouse.x;
_tapY = event.mouse.y;
event.type = Common::EVENT_MOUSEMOVE;
_graphicsMan->setMousePos(event.mouse.x, event.mouse.y);
}
if (_graphicsMan->_toolbarHandler.action(event.mouse.x, event.mouse.y, false)) {
if (!_graphicsMan->_toolbarHandler.drawn()) {
_graphicsMan->_toolbarHighDrawn = false;
_graphicsMan->internUpdateScreen();
}
return false;
}
return true;
case SDL_VIDEOEXPOSE:
_graphicsMan->notifyVideoExpose();
break;
case SDL_QUIT:
event.type = Common::EVENT_QUIT;
return true;
case SDL_ACTIVEEVENT:
if (ev.active.state & SDL_APPMOUSEFOCUS)
debug(2, "%s mouse focus.", ev.active.gain ? "Got" : "Lost");
if (ev.active.state & SDL_APPINPUTFOCUS)
debug(2, "%s input focus.", ev.active.gain ? "Got" : "Lost");
if (ev.active.state & SDL_APPACTIVE)
debug(2, "%s total focus.", ev.active.gain ? "Got" : "Lost");
if (ev.active.state & SDL_APPINPUTFOCUS) {
_graphicsMan->_hasfocus = ev.active.gain;
SDL_PauseAudio(!_graphicsMan->_hasfocus);
if (_graphicsMan->_hasfocus)
_graphicsMan->notifyVideoExpose();
}
break;
}
}
// Simulate repeated key for backend
if (!keyEvent && _graphicsMan->_lastKeyPressed && (int)currentTime > _graphicsMan->_keyRepeatTime + _graphicsMan->_keyRepeatTrigger) {
_graphicsMan->_keyRepeatTime = currentTime;
_graphicsMan->_keyRepeat++;
GUI_Actions::Instance()->performMapped(_graphicsMan->_lastKeyPressed, true);
}
return false;
}
int WINCESdlEventSource::mapKeyCE(SDLKey key, SDLMod mod, Uint16 unicode, bool unfilter) {
if (GUI::Actions::Instance()->mappingActive())
return key;
if (unfilter) {
switch (key) {
case SDLK_ESCAPE:
return SDLK_BACKSPACE;
case SDLK_F8:
return SDLK_ASTERISK;
case SDLK_F9:
return SDLK_HASH;
default:
return key;
}
}
if (key >= SDLK_KP0 && key <= SDLK_KP9) {
return key - SDLK_KP0 + '0';
} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
return key;
} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
return 0;
}
return key;
}
#endif /* _WIN32_WCE */