Added pushEvent to EventManager (from cpage88's branch) and changed VirtualKeyboard so that it uses this method to feed key presses its resulting key press events.

svn-id: r32977
This commit is contained in:
Stephen Kennedy 2008-07-09 13:33:36 +00:00
parent b035101732
commit 1f0b3ceb36
9 changed files with 155 additions and 60 deletions

View file

@ -153,7 +153,7 @@ bool VirtualKeyboardParser::parserCallback_Mode() {
Common::String resolutions = modeNode->values["resolutions"];
Common::StringTokenizer tok (resolutions, " ,");
uint16 scrW = _keyboard->_screenWidth, scrH = _keyboard->_screenHeight;
uint16 scrW = g_system->getOverlayWidth(), scrH = g_system->getOverlayHeight();
uint32 diff = 0xFFFFFFFF;
Common::String newResolution;
for (Common::String res = tok.nextToken(); res.size() > 0; res = tok.nextToken()) {

View file

@ -39,17 +39,18 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0), _keyDown(0) {
_parser = new VirtualKeyboardParser(this);
_loaded = _displaying = _drag = false;
_screenWidth = _system->getOverlayWidth();
_screenHeight = _system->getOverlayHeight();
_lastScreenChanged = _system->getScreenChangeID();
}
VirtualKeyboard::~VirtualKeyboard() {
// TODO: clean up event data pointers
deleteEventData();
delete _parser;
}
void VirtualKeyboard::reset() {
// TODO: clean up event data pointers
deleteEventData();
_modes.clear();
_initialMode = _currentMode = 0;
_kbdBound.left = _kbdBound.top
@ -60,8 +61,17 @@ void VirtualKeyboard::reset() {
_keyDown = 0;
_displaying = _drag = false;
_firstRun = true;
_screenWidth = _system->getOverlayWidth();
_screenHeight = _system->getOverlayHeight();
_lastScreenChanged = _system->getScreenChangeID();
}
void VirtualKeyboard::deleteEventData() {
ModeMap::iterator it_m;
EventMap::iterator it_e;
for (it_m = _modes.begin(); it_m != _modes.end(); it_m++) {
EventMap *evt = &(it_m->_value.events);
for (it_e = evt->begin(); it_e != evt->end(); it_e++)
delete it_e->_value.data;
}
}
bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
@ -116,31 +126,32 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {
void VirtualKeyboard::setDefaultPosition()
{
int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight();
int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
int16 posX = 0, posY = 0;
if (_screenWidth != kbdW) {
if (scrW != kbdW) {
switch (_hAlignment) {
case kAlignLeft:
posX = 0;
break;
case kAlignCentre:
posX = (_screenWidth - kbdW) / 2;
posX = (scrW - kbdW) / 2;
break;
case kAlignRight:
posX = _screenWidth - kbdW;
posX = scrW - kbdW;
break;
}
}
if (_screenHeight != kbdH) {
if (scrH != kbdH) {
switch (_vAlignment) {
case kAlignTop:
posY = 0;
break;
case kAlignMiddle:
posY = (_screenHeight - kbdH) / 2;
posY = (scrH - kbdH) / 2;
break;
case kAlignBottom:
posY = _screenHeight - kbdH;
posY = scrH - kbdH;
break;
}
}
@ -185,7 +196,7 @@ void VirtualKeyboard::processClick(const Common::String& area) {
switch (evt.type) {
case kEventKey:
// add virtual keypress to queue
_keyQueue.push_back(*(Common::KeyState*)evt.data);
_keyQueue.push(*(Common::KeyState*)evt.data);
break;
case kEventSwitchMode:
// switch to new mode
@ -218,28 +229,31 @@ void VirtualKeyboard::show() {
warning("Keyboard not loaded therefore can't be shown");
return;
}
if (_screenWidth != _system->getOverlayWidth() || _screenHeight != _system->getOverlayHeight()) {
_screenWidth = _system->getOverlayWidth();
_screenHeight = _system->getOverlayHeight();
if (!checkModeResolutions()) return;
}
if (_lastScreenChanged != _system->getScreenChangeID())
screenChanged();
switchMode(_initialMode);
_displaying = true;
if (_firstRun) {
_firstRun = false;
setDefaultPosition();
}
_system->showOverlay();
runLoop();
_system->hideOverlay();
}
void VirtualKeyboard::hide() {
_displaying = false;
}
void VirtualKeyboard::screenChanged() {
_lastScreenChanged = _system->getScreenChangeID();
if (!checkModeResolutions())
_displaying = false;
}
void VirtualKeyboard::runLoop() {
Common::EventManager *eventMan = _system->getEventManager();
_system->showOverlay();
while (_displaying) {
if (_needRedraw) redraw();
@ -274,10 +288,7 @@ void VirtualKeyboard::runLoop() {
}
break;
case Common::EVENT_SCREEN_CHANGED:
_screenWidth = _system->getOverlayWidth();
_screenHeight = _system->getOverlayHeight();
if (!checkModeResolutions())
_displaying = false;
screenChanged();
break;
case Common::EVENT_QUIT:
_system->quit();
@ -286,11 +297,20 @@ void VirtualKeyboard::runLoop() {
break;
}
// TODO - remove this line ?
if (!_displaying) break;
//if (!_displaying) break;
}
}
// clear keyboard from overlay
_system->hideOverlay();
// push keydown & keyup events into the event manager
Common::Event evt;
evt.synthetic = false;
while (!_keyQueue.empty()) {
evt.kbd = _keyQueue.pop();
evt.type = Common::EVENT_KEYDOWN;
eventMan->pushEvent(evt);
evt.type = Common::EVENT_KEYUP;
eventMan->pushEvent(evt);
}
}
void VirtualKeyboard::redraw() {
@ -300,8 +320,8 @@ void VirtualKeyboard::redraw() {
_system->clearOverlay();
_system->grabOverlay((OverlayColor*)surf.pixels, surf.w);
surf.blit(_currentMode->image, _kbdBound.left, _kbdBound.top, _system->RGBToColor(0xff, 0, 0xff));
_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h);
surf.free();
@ -309,22 +329,4 @@ void VirtualKeyboard::redraw() {
_needRedraw = false;
}
bool VirtualKeyboard::pollEvent(Common::Event &event) {
if (_displaying || (_keyQueue.empty() && !_keyDown))
return false;
event.synthetic = false; // ???
if (_keyDown) {
event.type = Common::EVENT_KEYUP;
event.kbd = *_keyDown;
_keyQueue.remove_at(0);
_keyDown = 0;
} else {
_keyDown = _keyQueue.begin();
event.type = Common::EVENT_KEYDOWN;
event.kbd = *_keyDown;
}
return true;
}
} // end of namespace GUI

View file

@ -33,6 +33,7 @@ class OSystem;
#include "common/hash-str.h"
#include "common/image-map.h"
#include "common/keyboard.h"
#include "common/queue.h"
#include "common/str.h"
#include "graphics/surface.h"
@ -97,13 +98,6 @@ public:
return _loaded;
}
/**
* Get the next virtual key event in the event queue.
* @param event point to an Event struct, which will be filled with the event data.
* @return true if an event was retrieved.
*/
bool pollEvent(Common::Event &event);
protected:
OSystem *_system;
@ -114,6 +108,8 @@ protected:
// TODO : sort order of all this stuff
void reset();
void deleteEventData();
void screenChanged();
bool checkModeResolutions();
void setDefaultPosition();
void move(int16 x, int16 y);
@ -133,7 +129,7 @@ protected:
Mode *_initialMode;
Mode *_currentMode;
int16 _screenWidth, _screenHeight;
int _lastScreenChanged;
Common::Rect _kbdBound;
HorizontalAlignment _hAlignment;
@ -143,7 +139,7 @@ protected:
Common::Point _dragPoint;
bool _drag;
Common::Array<Common::KeyState> _keyQueue;
Common::Queue<Common::KeyState> _keyQueue;
Common::KeyState *_keyDown;
};

View file

@ -31,6 +31,7 @@
#include "engines/engine.h"
#include "gui/message.h"
#include "gui/newgui.h"
#define RECORD_SIGNATURE 0x54455354
#define RECORD_VERSION 1
@ -196,6 +197,7 @@ DefaultEventManager::DefaultEventManager(OSystem *boss) :
}
DefaultEventManager::~DefaultEventManager() {
delete _vk;
_boss->lockMutex(_timeMutex);
_boss->lockMutex(_recorderMutex);
_recordMode = kPassthrough;
@ -351,10 +353,11 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
uint32 time = _boss->getMillis();
bool result;
// poll virtual keyboard
result = _vk->pollEvent(event);
// if no vk event, then poll backend
if (!result) result = _boss->pollEvent(event);
if (!_artificialEventQueue.empty()) {
event = _artificialEventQueue.pop();
result = true;
} else
result = _boss->pollEvent(event);
if (_recordMode != kPassthrough) {
@ -390,16 +393,17 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
_keyRepeatTime = time + kKeyRepeatInitialDelay;
#endif
// quick hack to show/hide keyboard
// HACK to show/hide keyboard (keyboard is not shown if gui is active)
if (event.kbd.keycode == Common::KEYCODE_F6 && event.kbd.flags == 0) {
if (_vk->isDisplaying()) {
_vk->hide();
} else {
} else if (!g_gui.isActive()) {
if (!_vk->isLoaded()) _vk->loadKeyboardPack("test");
bool isPaused = (g_engine) ? g_engine->isPaused() : true;
if (!isPaused) g_engine->pauseEngine(true);
_vk->show();
if (!isPaused) g_engine->pauseEngine(false);
result = false;
}
}
@ -466,4 +470,8 @@ bool DefaultEventManager::pollEvent(Common::Event &event) {
return result;
}
void DefaultEventManager::pushEvent(Common::Event event) {
_artificialEventQueue.push(event);
}
#endif // !defined(DISABLE_DEFAULT_EVENTMANAGER)

View file

@ -27,6 +27,7 @@
#define BACKEND_EVENTS_DEFAULT_H
#include "common/events.h"
#include "common/queue.h"
#include "common/savefile.h"
#include "backends/common/virtual-keyboard.h"
@ -47,6 +48,8 @@ class DefaultEventManager : public Common::EventManager {
Common::VirtualKeyboard *_vk;
Common::Queue<Common::Event> _artificialEventQueue;
Common::Point _mousePos;
int _buttonState;
int _modifierState;
@ -110,6 +113,7 @@ public:
~DefaultEventManager();
virtual bool pollEvent(Common::Event &event);
virtual void pushEvent(Common::Event event);
virtual void registerRandomSource(Common::RandomSource &rnd, const char *name);
virtual void processMillis(uint32 &millis);

View file

@ -142,6 +142,11 @@ public:
*/
virtual bool pollEvent(Common::Event &event) = 0;
/**
* Pushes a "fake" event into the event queue
*/
virtual void pushEvent(Common::Event event) = 0;
/** Register random source so it can be serialized in game test purposes **/
virtual void registerRandomSource(Common::RandomSource &rnd, const char *name) = 0;

View file

@ -209,6 +209,11 @@ public:
++i;
}
void pop_front() {
iterator i = begin();
i = erase(i);
}
List<t_T> &operator=(const List<t_T> &list) {
if (this != &list) {

71
common/queue.h Normal file
View file

@ -0,0 +1,71 @@
/* 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.
*
* $URL$
* $Id$
*/
#ifndef COMMON_QUEUE_H
#define COMMON_QUEUE_H
#include "common/scummsys.h"
#include "common/list.h"
namespace Common {
/**
* Variable size Queue class, implemented using our Array class.
*/
template<class T>
class Queue {
protected:
List<T> _queue;
public:
Queue<T>() {}
Queue<T>(const List<T> &queueContent) : _queue(queueContent) {}
bool empty() const {
return _queue.empty();
}
void clear() {
_queue.clear();
}
void push(const T &x) {
_queue.push_back(x);
}
T back() const {
return _queue.reverse_begin().operator*();
}
T front() const {
return _queue.begin().operator*();
}
T pop() {
T tmp = front();
_queue.pop_front();
return tmp;
}
int size() const {
return _queue.size();
}
};
} // End of namespace Common
#endif

View file

@ -398,6 +398,10 @@
RelativePath="..\..\common\ptr.h"
>
</File>
<File
RelativePath="..\..\common\queue.h"
>
</File>
<File
RelativePath="..\..\common\rect.h"
>