[Scummvm-cvs-logs] SF.net SVN: scummvm:[35813] scummvm/trunk

sev at users.sourceforge.net sev at users.sourceforge.net
Sun Jan 11 01:20:28 CET 2009


Revision: 35813
          http://scummvm.svn.sourceforge.net/scummvm/?rev=35813&view=rev
Author:   sev
Date:     2009-01-11 00:20:27 +0000 (Sun, 11 Jan 2009)

Log Message:
-----------
Merge in Virtual Keybpard & KeyMapper branch,
- Merge is perfromed in order to not let rotting the code
- Makefile modifications were avoided

Stuff to resolve:
- Circular dependency of common/vkeybd from graphics/
- Make it compilable (?)
- Add some keyboards
- Decide on the key bindings

Modified Paths:
--------------
    scummvm/trunk/backends/events/default/default-events.cpp
    scummvm/trunk/backends/events/default/default-events.h
    scummvm/trunk/backends/platform/sdl/events.cpp
    scummvm/trunk/backends/platform/sdl/sdl.cpp
    scummvm/trunk/backends/platform/sdl/sdl.h
    scummvm/trunk/base/main.cpp
    scummvm/trunk/common/events.h
    scummvm/trunk/common/keyboard.h
    scummvm/trunk/common/stack.h
    scummvm/trunk/configure
    scummvm/trunk/gui/GuiManager.cpp
    scummvm/trunk/gui/dialog.cpp

Added Paths:
-----------
    scummvm/trunk/backends/keymapper/
    scummvm/trunk/backends/keymapper/action.cpp
    scummvm/trunk/backends/keymapper/action.h
    scummvm/trunk/backends/keymapper/hardware-key.h
    scummvm/trunk/backends/keymapper/keymap.cpp
    scummvm/trunk/backends/keymapper/keymap.h
    scummvm/trunk/backends/keymapper/keymapper.cpp
    scummvm/trunk/backends/keymapper/keymapper.h
    scummvm/trunk/backends/keymapper/remap-dialog.cpp
    scummvm/trunk/backends/keymapper/remap-dialog.h
    scummvm/trunk/backends/keymapper/types.h
    scummvm/trunk/backends/vkeybd/
    scummvm/trunk/backends/vkeybd/image-map.cpp
    scummvm/trunk/backends/vkeybd/image-map.h
    scummvm/trunk/backends/vkeybd/keycode-descriptions.h
    scummvm/trunk/backends/vkeybd/polygon.cpp
    scummvm/trunk/backends/vkeybd/polygon.h
    scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.cpp
    scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.h
    scummvm/trunk/backends/vkeybd/virtual-keyboard-parser.cpp
    scummvm/trunk/backends/vkeybd/virtual-keyboard-parser.h
    scummvm/trunk/backends/vkeybd/virtual-keyboard.cpp
    scummvm/trunk/backends/vkeybd/virtual-keyboard.h
    scummvm/trunk/backends/vkeybd/vkeybd.zip
    scummvm/trunk/graphics/surface-keycolored.cpp
    scummvm/trunk/graphics/surface-keycolored.h

Modified: scummvm/trunk/backends/events/default/default-events.cpp
===================================================================
--- scummvm/trunk/backends/events/default/default-events.cpp	2009-01-11 00:02:28 UTC (rev 35812)
+++ scummvm/trunk/backends/events/default/default-events.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -28,6 +28,9 @@
 #include "common/system.h"
 #include "common/config-manager.h"
 #include "backends/events/default/default-events.h"
+#include "backends/keymapper/keymapper.h"
+#include "backends/keymapper/remap-dialog.h"
+#include "backends/vkeybd/virtual-keyboard.h"
 
 #include "engines/engine.h"
 #include "gui/message.h"
@@ -193,9 +196,23 @@
 
 		_hasPlaybackEvent = false;
 	}
+
+#ifdef ENABLE_VKEYBD
+	_vk = new Common::VirtualKeyboard();
+#endif
+#ifdef ENABLE_KEYMAPPER
+	_keymapper = new Common::Keymapper(this);
+	_remap = false;
+#endif
 }
 
 DefaultEventManager::~DefaultEventManager() {
+#ifdef ENABLE_KEYMAPPER
+	delete _keymapper;
+#endif
+#ifdef ENABLE_VKEYBD
+	delete _vk;
+#endif
 	_boss->lockMutex(_timeMutex);
 	_boss->lockMutex(_recorderMutex);
 	_recordMode = kPassthrough;
@@ -254,6 +271,16 @@
 	_boss->deleteMutex(_recorderMutex);
 }
 
+void DefaultEventManager::init() {
+#ifdef ENABLE_VKEYBD
+	if (ConfMan.hasKey("vkeybd_pack_name")) {
+		_vk->loadKeyboardPack(ConfMan.get("vkeybd_pack_name"));
+	} else {
+		_vk->loadKeyboardPack("vkeybd");
+	}
+#endif
+}
+
 bool DefaultEventManager::playback(Common::Event &event) {
 
 	if (!_hasPlaybackEvent) {
@@ -357,9 +384,25 @@
 	if (!artificialEventQueue.empty()) {
 		event = artificialEventQueue.pop();
 		result = true;
-	} else
+	} else {
 		result = _boss->pollEvent(event);
 
+#ifdef ENABLE_KEYMAPPER
+		if (result) {
+			// send key press events to keymapper
+			if (event.type == Common::EVENT_KEYDOWN) {
+				if (_keymapper->mapKeyDown(event.kbd)) {
+					result = false;
+				}
+			} else if (event.type == Common::EVENT_KEYUP) {
+				if (_keymapper->mapKeyUp(event.kbd)) {
+					result = false;
+				}
+			}
+		}
+#endif
+	}
+
 	if (_recordMode != kPassthrough)  {
 
 		_boss->lockMutex(_recorderMutex);
@@ -425,6 +468,32 @@
 						event.type = Common::EVENT_RTL;
 				}
 			}
+#ifdef ENABLE_VKEYBD	
+			else if (event.kbd.keycode == Common::KEYCODE_F7 && event.kbd.flags == 0) {
+				if (_vk->isDisplaying()) {
+					_vk->close(true);
+				} else {
+					bool isPaused = (g_engine) ? g_engine->isPaused() : true;
+					if (!isPaused) g_engine->pauseEngine(true);
+					_vk->show();
+					if (!isPaused) g_engine->pauseEngine(false);
+					result = false;
+				}
+			}
+#endif
+#ifdef ENABLE_KEYMAPPER	
+			else if (event.kbd.keycode == Common::KEYCODE_F8 && event.kbd.flags == 0) {
+				if (!_remap) {
+					_remap = true;
+					Common::RemapDialog _remapDialog;
+					bool isPaused = (g_engine) ? g_engine->isPaused() : true;
+					if (!isPaused) g_engine->pauseEngine(true);
+					_remapDialog.runModal();
+					if (!isPaused) g_engine->pauseEngine(false);
+					_remap = false;
+				}
+			}
+#endif
 			break;
 
 		case Common::EVENT_KEYUP:
@@ -520,7 +589,7 @@
 	return result;
 }
 
-void DefaultEventManager::pushEvent(Common::Event event) {
+void DefaultEventManager::pushEvent(const Common::Event &event) {
 
 	// If already received an EVENT_QUIT, don't add another one
 	if (event.type == Common::EVENT_QUIT) {

Modified: scummvm/trunk/backends/events/default/default-events.h
===================================================================
--- scummvm/trunk/backends/events/default/default-events.h	2009-01-11 00:02:28 UTC (rev 35812)
+++ scummvm/trunk/backends/events/default/default-events.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -29,9 +29,20 @@
 #include "common/events.h"
 #include "common/savefile.h"
 #include "common/mutex.h"
+#include "common/queue.h"
 
 class OSystem;
 
+namespace Common {
+#ifdef ENABLE_KEYMAPPER
+	class Keymapper;
+#endif
+#ifdef ENABLE_VKEYBD
+	class VirtualKeyboard;
+#endif
+}
+
+
 /*
 At some point we will remove pollEvent from OSystem and change
 DefaultEventManager to use a "boss" derived from this class:
@@ -47,6 +58,17 @@
 class DefaultEventManager : public Common::EventManager {
 	OSystem *_boss;
 
+#ifdef ENABLE_VKEYBD
+	Common::VirtualKeyboard *_vk;
+#endif
+
+#ifdef ENABLE_KEYMAPPER
+	Common::Keymapper *_keymapper;
+	bool _remap;
+#endif
+
+	Common::Queue<Common::Event> _artificialEventQueue;
+
 	Common::Point _mousePos;
 	int _buttonState;
 	int _modifierState;
@@ -111,8 +133,9 @@
 	DefaultEventManager(OSystem *boss);
 	~DefaultEventManager();
 
+	virtual void init();
 	virtual bool pollEvent(Common::Event &event);
-	virtual void pushEvent(Common::Event event);
+	virtual void pushEvent(const Common::Event &event);
 	virtual void registerRandomSource(Common::RandomSource &rnd, const char *name);
 	virtual void processMillis(uint32 &millis);
 
@@ -122,6 +145,10 @@
 	virtual int shouldQuit() const { return _shouldQuit; }
 	virtual int shouldRTL() const { return _shouldRTL; }
 	virtual void resetRTL() { _shouldRTL = false; }
+	
+#ifdef ENABLE_KEYMAPPER
+	virtual Common::Keymapper *getKeymapper() { return _keymapper; }
+#endif
 };
 
 #endif

Added: scummvm/trunk/backends/keymapper/action.cpp
===================================================================
--- scummvm/trunk/backends/keymapper/action.cpp	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/action.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,58 @@
+/* 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$
+*
+*/
+
+#include "backends/keymapper/action.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "backends/keymapper/keymap.h"
+
+namespace Common {
+
+Action::Action(Keymap *boss, const char *i,	String des, ActionType typ, 
+			   KeyType prefKey, int pri, int flg)
+	: _boss(boss), description(des), type(typ), preferredKey(prefKey),
+	priority(pri), flags(flg), _hwKey(0) {
+	assert(i);
+	assert(_boss);
+
+	strncpy(id, i, ACTION_ID_SIZE);
+
+	_boss->addAction(this);
+}
+
+void Action::mapKey(const HardwareKey *key) {
+	if (_hwKey) _boss->unregisterMapping(this);
+	_hwKey = key;
+	if (_hwKey) _boss->registerMapping(this, _hwKey);
+}
+
+const HardwareKey *Action::getMappedKey() const {
+	return _hwKey;
+}
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER


Property changes on: scummvm/trunk/backends/keymapper/action.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/action.h
===================================================================
--- scummvm/trunk/backends/keymapper/action.h	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/action.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,122 @@
+/* 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_ACTION_H
+#define COMMON_ACTION_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "backends/keymapper/types.h"
+#include "common/events.h"
+#include "common/func.h"
+#include "common/list.h"
+#include "common/str.h"
+
+namespace Common {
+
+struct HardwareKey;
+class Keymap;
+
+#define ACTION_ID_SIZE (4)
+
+struct Action {
+	/** unique id used for saving/loading to config */
+	char id[ACTION_ID_SIZE];
+	/** Human readable description */
+	String description;
+
+	/** Events to be sent when mapped key is pressed */
+	List<Event> events;
+	ActionType type;
+	KeyType preferredKey;
+	int priority;
+	int group;
+	int flags;
+
+private:
+	/** Hardware key that is mapped to this Action */
+	const HardwareKey *_hwKey;
+	Keymap *_boss;
+
+public:
+	Action(Keymap *boss, const char *id, String des = "", 
+		   ActionType typ = kGenericActionType,
+		   KeyType prefKey = kGenericKeyType,
+		   int pri = 0, int flg = 0 );
+
+	void addEvent(const Event &evt) { 
+		events.push_back(evt);
+	}
+
+	void addKeyEvent(const KeyState &ks) {
+		Event evt;
+		evt.type = EVENT_KEYDOWN;
+		evt.kbd = ks;
+		addEvent(evt);
+	}
+
+	void addLeftClickEvent() {
+		Event evt;
+		evt.type = EVENT_LBUTTONDOWN;
+		addEvent(evt);
+	}
+
+	void addMiddleClickEvent() {
+		Event evt;
+		evt.type = EVENT_MBUTTONDOWN;
+		addEvent(evt);
+	}
+
+	void addRightClickEvent() {
+		Event evt;
+		evt.type = EVENT_RBUTTONDOWN;
+		addEvent(evt);
+	}
+
+	Keymap *getBoss() { 
+		return _boss;
+	}
+
+	void mapKey(const HardwareKey *key);
+	const HardwareKey *getMappedKey() const;
+
+};
+
+struct ActionPriorityComp : public BinaryFunction<Action, Action, bool> {
+	bool operator()(const Action *x, const Action *y) const { 
+		return x->priority > y->priority;
+	}
+	bool operator()(const Action &x, const Action &y) const { 
+		return x.priority > y.priority;
+	}
+};
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef COMMON_ACTION_H


Property changes on: scummvm/trunk/backends/keymapper/action.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/hardware-key.h
===================================================================
--- scummvm/trunk/backends/keymapper/hardware-key.h	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/hardware-key.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,134 @@
+/* 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_HARDWARE_KEY_H
+#define COMMON_HARDWARE_KEY_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "backends/keymapper/types.h"
+
+namespace Common {
+
+
+#define HWKEY_ID_SIZE (4)
+/**
+* Describes an available hardware key 
+*/
+struct HardwareKey {
+	/** unique id used for saving/loading to config */
+	char id[HWKEY_ID_SIZE];
+	/** Human readable description */
+	String description; 
+	/** 
+	* The KeyState that is generated by the back-end 
+	* when this hardware key is pressed.
+	*/
+	KeyState key;
+
+	KeyType type;
+	ActionType preferredAction;
+
+	HardwareKey(const char *i, KeyState ky = KeyState(), String desc = "",
+				KeyType typ = kGenericKeyType, ActionType prefAct = kGenericActionType)
+		: key(ky), description(desc), type(typ), preferredAction(prefAct) {
+		assert(i);
+		strncpy(id, i, HWKEY_ID_SIZE);
+	}
+};
+
+
+/**
+ * Simple class to encapsulate a device's set of HardwareKeys.
+ * Each device should extend this and call addHardwareKey a number of times
+ * in its constructor to define the device's available keys.
+ */ 
+class HardwareKeySet {
+public:
+
+	HardwareKeySet() : _count(0) {}
+	virtual ~HardwareKeySet() {
+		List<const HardwareKey*>::iterator it;
+		for (it = _keys.begin(); it != _keys.end(); it++)
+			delete *it;
+	}
+
+	void addHardwareKey(HardwareKey *key) {
+		checkForKey(key);
+		_keys.push_back(key);
+		++_count;
+	}
+
+	const HardwareKey *findHardwareKey(const char *id) const {
+		List<const HardwareKey*>::iterator it;
+		for (it = _keys.begin(); it != _keys.end(); it++) {
+			if (strncmp((*it)->id, id, HWKEY_ID_SIZE) == 0)
+				return (*it);
+		}
+		return 0;
+	}
+
+	const HardwareKey *findHardwareKey(const KeyState& keystate) const {
+		List<const HardwareKey*>::iterator it;
+		for (it = _keys.begin(); it != _keys.end(); it++) {
+			if ((*it)->key == keystate)
+				return (*it);
+		}
+		return 0;
+	}
+
+	List<const HardwareKey*> getHardwareKeys() const {
+		return _keys;
+	}
+
+	uint count() const {
+		return _count;
+	}
+
+
+private:
+
+	void checkForKey(HardwareKey *key) {
+		List<const HardwareKey*>::iterator it;
+		for (it = _keys.begin(); it != _keys.end(); it++) {
+			if (strncmp((*it)->id, key->id, HWKEY_ID_SIZE) == 0)
+				error("Error adding HardwareKey '%s' - id of %s already in use!", key->description.c_str(), key->id);
+			else if ((*it)->key == key->key)
+				error("Error adding HardwareKey '%s' - key already in use!", key->description.c_str());
+		}
+	}
+
+	List<const HardwareKey*> _keys;
+	uint _count;
+};
+
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef COMMON_HARDWARE_KEY_H


Property changes on: scummvm/trunk/backends/keymapper/hardware-key.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/keymap.cpp
===================================================================
--- scummvm/trunk/backends/keymapper/keymap.cpp	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/keymap.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,304 @@
+/* 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$
+*
+*/
+
+#include "backends/keymapper/keymap.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "backends/keymapper/hardware-key.h"
+
+#define KEYMAP_KEY_PREFIX "keymap_"
+
+namespace Common {
+
+Keymap::Keymap(const Keymap& km) : _actions(km._actions), _keymap(), _configDomain(0) {
+	List<Action*>::iterator it;
+	for (it = _actions.begin(); it != _actions.end(); it++) {
+		const HardwareKey *hwKey = (*it)->getMappedKey();
+		if (hwKey) {
+			_keymap[hwKey->key] = *it;
+		}
+	}
+}
+
+Keymap::~Keymap() {
+	List<Action*>::iterator it;
+	for (it = _actions.begin(); it != _actions.end(); it++)
+		delete *it;
+}
+
+void Keymap::addAction(Action *action) {
+	if (findAction(action->id))
+		error("Action with id %s already in KeyMap!", action->id);
+	_actions.push_back(action);
+}
+
+void Keymap::registerMapping(Action *action, const HardwareKey *hwKey) {
+	HashMap<KeyState, Action*>::iterator it;
+	it = _keymap.find(hwKey->key);
+	// if key is already mapped to a different action then un-map it
+	if (it != _keymap.end() && action != it->_value) {
+		it->_value->mapKey(0);
+	}
+
+	_keymap[hwKey->key] = action;
+}
+
+void Keymap::unregisterMapping(Action *action) {
+	const HardwareKey *hwKey = action->getMappedKey();
+	if (hwKey) {
+		_keymap.erase(hwKey->key);
+	}
+}
+
+Action *Keymap::getAction(const char *id) {
+	return findAction(id);
+}
+
+Action *Keymap::findAction(const char *id) {
+	List<Action*>::iterator it;
+	for (it = _actions.begin(); it != _actions.end(); it++) {
+		if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
+			return *it;
+	}
+	return 0;
+}
+
+const Action *Keymap::findAction(const char *id) const {
+	List<Action*>::const_iterator it;
+	for (it = _actions.begin(); it != _actions.end(); it++) {
+		if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
+			return *it;
+	}
+	return 0;
+}
+
+Action *Keymap::getMappedAction(const KeyState& ks) const {
+	HashMap<KeyState, Action*>::iterator it;
+	it = _keymap.find(ks);
+	if (it == _keymap.end())
+		return 0;
+	else
+		return it->_value;
+}
+
+void Keymap::setConfigDomain(ConfigManager::Domain *dom) {
+	_configDomain = dom;
+}
+
+void Keymap::loadMappings(const HardwareKeySet *hwKeys) {
+	if (!_configDomain) return;
+	ConfigManager::Domain::iterator it;	
+	String prefix = KEYMAP_KEY_PREFIX + _name + "_";
+	for (it = _configDomain->begin(); it != _configDomain->end(); it++) {
+		const String& key = it->_key;
+		if (!key.hasPrefix(prefix.c_str()))
+			continue;
+
+		// parse Action ID
+		const char *actionId = key.c_str() + prefix.size();
+		Action *ua = getAction(actionId);
+		if (!ua) {
+			warning("'%s' keymap does not contain Action with ID %s", 
+				_name.c_str(), actionId);
+			_configDomain->erase(key);
+			continue;
+		}
+
+		const HardwareKey *hwKey = hwKeys->findHardwareKey(it->_value.c_str());
+		if (!hwKey) {
+			warning("HardwareKey with ID %s not known", it->_value.c_str());
+			_configDomain->erase(key);
+			continue;
+		}
+
+		ua->mapKey(hwKey);
+	}
+}
+
+void Keymap::saveMappings() {
+	if (!_configDomain) return;
+	List<Action*>::const_iterator it;
+	String prefix = KEYMAP_KEY_PREFIX + _name + "_";
+	for (it = _actions.begin(); it != _actions.end(); it++) {
+		uint actIdLen = strlen((*it)->id);
+		actIdLen = (actIdLen > ACTION_ID_SIZE) ? ACTION_ID_SIZE : actIdLen;
+		String actId((*it)->id, (*it)->id + actIdLen);
+		if ((*it)->getMappedKey()) {
+			uint hwIdLen = strlen((*it)->getMappedKey()->id);
+			hwIdLen = (hwIdLen > HWKEY_ID_SIZE) ? HWKEY_ID_SIZE : hwIdLen;
+			String hwId((*it)->getMappedKey()->id, (*it)->getMappedKey()->id + hwIdLen);
+			_configDomain->setVal(prefix + actId, hwId);
+		} else {
+			_configDomain->setVal(prefix + actId, "");
+		}
+	}
+}
+
+bool Keymap::isComplete(const HardwareKeySet *hwKeys) {
+	List<Action*>::iterator it;
+	bool allMapped = true;
+	uint numberMapped = 0;
+	for (it = _actions.begin(); it != _actions.end(); it++) {
+		if ((*it)->getMappedKey()) {
+			numberMapped++;
+		} else {
+			allMapped = false;
+		}
+	}
+	return allMapped || (numberMapped == hwKeys->count());
+}
+
+// TODO:
+// - current weakness:
+//     - if an action finds a key with required type but a parent action with 
+//       higher priority is using it, that key is never used
+void Keymap::automaticMapping(HardwareKeySet *hwKeys) {
+	// Create copies of action and key lists.
+	List<Action*> actions(_actions);
+	List<const HardwareKey*> keys(hwKeys->getHardwareKeys());
+
+	List<Action*>::iterator actIt;
+	List<const HardwareKey*>::iterator keyIt, selectedKey;
+	
+	// Remove actions and keys from local lists that have already been mapped.
+	actIt = actions.begin();
+	while (actIt != actions.end()) {
+		Action *act = *actIt;
+		const HardwareKey *key = act->getMappedKey();
+		if (key) {
+			keys.remove(key);
+			actIt = actions.erase(actIt);
+		} else {
+			++actIt;
+		}
+	}
+
+	// Sort remaining actions by priority.
+	ActionPriorityComp priorityComp;
+	sort(actions.begin(), actions.end(), priorityComp);
+	
+	// First mapping pass:
+	// - Match if a key's preferred action type is the same as the action's 
+	// type, or vice versa.
+	// - Priority is given to:
+	//     - keys that match action types over key types.
+	//     - keys that have not been used by parent maps.
+	// - If a key has been used by a parent map the new action must have a
+	//   higher priority than the parent action.
+	// - As soon as the number of skipped actions equals the number of keys 
+	//   remaining we stop matching. This means that the second pass will assign keys
+	//   to these higher priority skipped actions.
+	uint skipped = 0;
+	actIt = actions.begin();
+	while (actIt != actions.end() && skipped < keys.size()) {
+		selectedKey = keys.end();
+		int matchRank = 0;
+		Action *act = *actIt;
+		for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) {
+			if ((*keyIt)->preferredAction == act->type && act->type != kGenericActionType) {
+				Action *parentAct = getParentMappedAction((*keyIt)->key);
+				if (!parentAct) {
+					selectedKey = keyIt;
+					break;
+				} else if (parentAct->priority <= act->priority && matchRank < 3) {
+					selectedKey = keyIt;
+					matchRank = 3;
+				}
+			} else if ((*keyIt)->type == act->preferredKey && act->preferredKey != kGenericKeyType && matchRank < 2) {
+				Action *parentAct = getParentMappedAction((*keyIt)->key);
+				if (!parentAct) {
+					selectedKey = keyIt;
+					matchRank = 2;
+				} else if (parentAct->priority <= act->priority && matchRank < 1) {
+					selectedKey = keyIt;
+					matchRank = 1;
+				}
+			}
+		}
+		if (selectedKey != keys.end()) {
+			// Map action and delete action & key from local lists.
+			act->mapKey(*selectedKey);
+			keys.erase(selectedKey);
+			actIt = actions.erase(actIt);
+		} else {
+			// Skip action (will be mapped in next pass).
+			++actIt;
+			++skipped;
+		}
+	}
+
+	// Second mapping pass:
+	// - Maps any remaining actions to keys
+	// - priority given to:
+	//     - keys that have no parent action
+	//     - keys whose parent action has lower priority than the new action
+	//     - keys whose parent action has the lowest priority
+	// - is guaranteed to match a key if they are not all used up
+	for (actIt = actions.begin(); actIt != actions.end(); ++actIt) {
+		selectedKey = keys.end();
+		int matchRank = 0;
+		int lowestPriority = 0;
+		Action *act = *actIt;
+		for (keyIt = keys.begin(); keyIt != keys.end(); ++keyIt) {
+			Action *parentAct = getParentMappedAction((*keyIt)->key);
+			if (!parentAct) {
+				selectedKey = keyIt;
+				break;
+			} else if (matchRank < 2) {
+				if (parentAct->priority <= act->priority) {
+					matchRank = 2;
+					selectedKey = keyIt;
+				} else if (parentAct->priority < lowestPriority || matchRank == 0) {
+					matchRank = 1;
+					lowestPriority = parentAct->priority;
+					selectedKey = keyIt;
+				}
+			}
+		}
+		if (selectedKey != keys.end()) {
+			act->mapKey(*selectedKey);
+			keys.erase(selectedKey);
+		} else {// no match = no keys left 
+			break;
+		}
+	}
+}
+
+Action *Keymap::getParentMappedAction(KeyState key) {
+	if (_parent) {
+		Action *act = _parent->getMappedAction(key);
+		if (act)
+			return act;
+		else
+			return _parent->getParentMappedAction(key);
+	} else {
+		return 0;
+	}
+}
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER


Property changes on: scummvm/trunk/backends/keymapper/keymap.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/keymap.h
===================================================================
--- scummvm/trunk/backends/keymapper/keymap.h	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/keymap.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,154 @@
+/* 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_KEYMAP_H
+#define COMMON_KEYMAP_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "common/config-manager.h"
+#include "common/func.h"
+#include "common/hashmap.h"
+#include "common/keyboard.h"
+#include "common/list.h"
+#include "backends/keymapper/action.h"
+
+namespace Common {
+
+struct HardwareKey;
+class HardwareKeySet;
+
+/**
+ * Hash function for KeyState
+ */
+template<> struct Hash<KeyState>
+	: public UnaryFunction<KeyState, uint> {
+
+	uint operator()(const KeyState &val) const { 
+		return (uint)(val.keycode * (val.flags << 1));
+	}
+};
+
+class Keymap {
+public:
+	Keymap(const String& name, Keymap *parent = 0) : _name(name), _parent(parent) {}
+	Keymap(const Keymap& km);
+	~Keymap();
+
+public:
+	/**
+	 * Retrieves the Action with the given id
+	 * @param id id of Action to retrieve
+	 * @return Pointer to the Action or 0 if not found
+	 */
+	Action *getAction(const char *id);
+
+	/**
+	 * Get the list of all the Actions contained in this Keymap
+	 */
+	List<Action*>& getActions() { return _actions; }
+
+	/**
+	 * Find the Action that a key is mapped to
+	 * @param key	the key that is mapped to the required Action
+	 * @return		a pointer to the Action or 0 if no
+	 */
+	Action *getMappedAction(const KeyState& ks) const;
+	
+	void setConfigDomain(ConfigManager::Domain *dom);
+
+	/**
+	 * Load this keymap's mappings from the config manager.
+	 * @param hwKeys	the set to retrieve hardware key pointers from
+	 */
+	void loadMappings(const HardwareKeySet *hwKeys);
+
+	/**
+	 * Save this keymap's mappings to the config manager
+	 * @note Changes are *not* flushed to disk, to do so call ConfMan.flushToDisk()
+	 * @note Changes are *not* flushed to disk, to do so call ConfMan.flushToDisk()
+	 */
+	void saveMappings();
+
+	
+	void automaticMapping(HardwareKeySet *hwKeys);
+
+	/**
+	 * Returns true if all UserAction's in Keymap are mapped, or,
+	 * all HardwareKey's from the given set have been used up.
+	 */
+	bool isComplete(const HardwareKeySet *hwKeys);
+
+	const String& getName() { return _name; }
+	Keymap *getParent() { return _parent; }
+
+private:
+	friend struct Action;
+
+	/**
+	 * Adds a new Action to this Map, 
+	 * adding it at the back of the internal array
+	 * @param action the Action to add
+	 */
+	void addAction(Action *action);
+
+	/**
+	* Registers a HardwareKey to the given Action
+	* @param action Action in this Keymap
+	* @param key pointer to HardwareKey to map
+	* @see Action::mapKey
+	*/
+	void registerMapping(Action *action, const HardwareKey *key);
+
+	/**
+	* Unregisters a HardwareKey from the given Action (if one is mapped)
+	* @param action Action in this Keymap
+	* @see Action::mapKey
+	*/
+	void unregisterMapping(Action *action);
+
+	Action *findAction(const char *id);
+	const Action *findAction(const char *id) const;
+
+	void internalMapKey(Action *action, HardwareKey *hwKey);
+
+	Action *getParentMappedAction(KeyState key);
+
+	String _name;
+	Keymap *_parent;
+	List<Action*> _actions;
+	HashMap<KeyState, Action*> _keymap; 
+	ConfigManager::Domain *_configDomain;
+
+};
+
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef COMMON_KEYMAP_H


Property changes on: scummvm/trunk/backends/keymapper/keymap.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/keymapper.cpp
===================================================================
--- scummvm/trunk/backends/keymapper/keymapper.cpp	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/keymapper.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,225 @@
+/* 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$
+*
+*/
+
+#include "backends/keymapper/keymapper.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "common/config-manager.h"
+
+namespace Common {
+
+void Keymapper::Domain::addKeymap(Keymap *map) {
+	KeymapMap::iterator it = _keymaps.find(map->getName());
+	if (it != _keymaps.end())
+		delete _keymaps[map->getName()];
+	_keymaps[map->getName()] = map;
+}
+
+void Keymapper::Domain::deleteAllKeyMaps() {
+	KeymapMap::iterator it;
+	for (it = _keymaps.begin(); it != _keymaps.end(); it++)
+		delete it->_value;
+	_keymaps.clear();
+}
+
+Keymap *Keymapper::Domain::getKeymap(const String& name) {
+	KeymapMap::iterator it = _keymaps.find(name);
+	if (it != _keymaps.end())
+		return it->_value;
+	else
+		return 0;
+}
+
+Keymapper::Keymapper(EventManager *evtMgr)
+	: _eventMan(evtMgr), _enabled(true), _hardwareKeys(0) {
+	_globalDomain.setConfigDomain(ConfMan.getDomain(ConfigManager::kApplicationDomain));
+}
+
+Keymapper::~Keymapper() {
+	delete _hardwareKeys;
+}
+
+void Keymapper::registerHardwareKeySet(HardwareKeySet *keys) {
+	if (_hardwareKeys)
+		error("Hardware key set already registered!");
+	_hardwareKeys = keys;
+}
+
+void Keymapper::addGlobalKeymap(Keymap *keymap) {
+	initKeymap(_globalDomain.getConfigDomain(), keymap);
+	_globalDomain.addKeymap(keymap);
+}
+
+void Keymapper::refreshGameDomain() {
+	if (_gameDomain.getConfigDomain() != ConfMan.getActiveDomain()) {
+		cleanupGameKeymaps();
+		_gameDomain.setConfigDomain(ConfMan.getActiveDomain());
+	}
+}
+
+void Keymapper::addGameKeymap(Keymap *keymap) {
+	if (ConfMan.getActiveDomain() == 0)
+		error("Call to Keymapper::addGameKeymap when no game loaded");
+		
+	refreshGameDomain();
+	initKeymap(_gameDomain.getConfigDomain(), keymap);
+	_gameDomain.addKeymap(keymap);
+}
+
+void Keymapper::initKeymap(ConfigManager::Domain *domain, Keymap *map) {
+	map->setConfigDomain(domain);
+	map->loadMappings(_hardwareKeys);
+	if (map->isComplete(_hardwareKeys) == false) {
+		map->automaticMapping(_hardwareKeys);
+		map->saveMappings();
+		ConfMan.flushToDisk();
+	}
+}
+
+void Keymapper::cleanupGameKeymaps() {
+	_gameDomain.deleteAllKeyMaps();
+	Stack<MapRecord> newStack;
+	for (int i = 0; i < _activeMaps.size(); i++) {
+		if (!_activeMaps[i].global)
+			newStack.push(_activeMaps[i]);
+	}
+	_activeMaps = newStack;
+}
+
+Keymap *Keymapper::getKeymap(const String& name, bool &global) {
+	Keymap *keymap = _gameDomain.getKeymap(name);
+	global = false;
+	if (!keymap) {
+		keymap = _globalDomain.getKeymap(name);
+		global = true;
+	}
+	return keymap;
+}
+
+bool Keymapper::pushKeymap(const String& name, bool inherit) {
+	bool global;
+	Keymap *newMap = getKeymap(name, global);
+	if (!newMap) {
+		warning("Keymap '%s' not registered", name.c_str());
+		return false;
+	}
+	pushKeymap(newMap, inherit, global);
+	return true;
+}
+
+void Keymapper::pushKeymap(Keymap *newMap, bool inherit, bool global) {
+	MapRecord mr = {newMap, inherit, global};
+	_activeMaps.push(mr);
+}
+
+void Keymapper::popKeymap() {
+	if (!_activeMaps.empty())
+		_activeMaps.pop();
+}
+
+bool Keymapper::mapKeyDown(const KeyState& key) {
+	return mapKey(key, true);
+}
+
+bool Keymapper::mapKeyUp(const KeyState& key) {
+	return mapKey(key, false);
+}
+
+bool Keymapper::mapKey(const KeyState& key, bool keyDown) {
+	if (!_enabled) return false;
+	if (_activeMaps.empty()) return false;
+
+	Action *action = 0;
+	if (keyDown) {
+		// Search for key in active keymap stack
+		for (int i = _activeMaps.size() - 1; i >= 0; --i) {
+			MapRecord mr = _activeMaps[i];
+			action = mr.keymap->getMappedAction(key);
+			if (action || mr.inherit == false) break;
+		}
+		if (action) _keysDown[key] = action;
+	} else {
+		HashMap<KeyState, Action*>::iterator it = _keysDown.find(key);
+		if (it != _keysDown.end()) {
+			action = it->_value;
+			_keysDown.erase(key);
+		}
+	}
+	if (!action) return false;
+	executeAction(action, keyDown);
+	return true;
+}
+
+Action *Keymapper::getAction(const KeyState& key) {
+	Action *action = 0;
+	return action;
+}
+
+void Keymapper::executeAction(const Action *action, bool keyDown) {
+	List<Event>::iterator it;
+	for (it = action->events.begin(); it != action->events.end(); ++it) {
+		Event evt = *it;
+		switch (evt.type) {
+		case EVENT_KEYDOWN:
+			if (!keyDown) evt.type = EVENT_KEYUP;
+			break;
+		case EVENT_KEYUP:
+			if (keyDown) evt.type = EVENT_KEYDOWN;
+			break;
+		case EVENT_LBUTTONDOWN:
+			if (!keyDown) evt.type = EVENT_LBUTTONUP;
+			break;
+		case EVENT_LBUTTONUP:
+			if (keyDown) evt.type = EVENT_LBUTTONDOWN;
+			break;
+		case EVENT_RBUTTONDOWN:
+			if (!keyDown) evt.type = EVENT_RBUTTONUP;
+			break;
+		case EVENT_RBUTTONUP:
+			if (keyDown) evt.type = EVENT_RBUTTONDOWN;
+			break;
+		case EVENT_MBUTTONDOWN:
+			if (!keyDown) evt.type = EVENT_MBUTTONUP;
+			break;
+		case EVENT_MBUTTONUP:
+			if (keyDown) evt.type = EVENT_MBUTTONDOWN;
+			break;
+		default:
+			// don't deliver other events on key up
+			if (!keyDown) continue;
+		}
+		evt.mouse = _eventMan->getMousePos();
+		_eventMan->pushEvent(evt);
+	}
+}
+
+const HardwareKey *Keymapper::getHardwareKey(const KeyState& key) {
+	return (_hardwareKeys) ? _hardwareKeys->findHardwareKey(key) : 0;
+}
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER


Property changes on: scummvm/trunk/backends/keymapper/keymapper.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/keymapper.h
===================================================================
--- scummvm/trunk/backends/keymapper/keymapper.h	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/keymapper.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,210 @@
+/* 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_KEYMAPPER_H
+#define COMMON_KEYMAPPER_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "common/events.h"
+#include "common/list.h"
+#include "common/hashmap.h"
+#include "common/stack.h"
+#include "backends/keymapper/hardware-key.h"
+#include "backends/keymapper/keymap.h"
+
+namespace Common {
+
+class Keymapper {
+public:
+	
+	struct MapRecord {
+		Keymap* keymap;
+		bool inherit;
+		bool global;
+	};
+
+	/* Nested class that represents a set of keymaps */
+	class Domain {
+		typedef HashMap<String, Keymap*, 
+			IgnoreCase_Hash, IgnoreCase_EqualTo> KeymapMap;
+
+	public:
+		Domain() : _configDomain(0) {}
+		~Domain() { 
+			deleteAllKeyMaps();
+		}
+
+		void setConfigDomain(ConfigManager::Domain *confDom) { 
+			_configDomain = confDom;
+		}
+		ConfigManager::Domain *getConfigDomain() {
+			return _configDomain;
+		}
+
+		void addKeymap(Keymap *map);
+
+		void deleteAllKeyMaps();
+
+		Keymap *getKeymap(const String& name);
+		
+		typedef KeymapMap::iterator iterator;
+		typedef KeymapMap::const_iterator const_iterator;
+		iterator begin() { return _keymaps.begin(); }
+		const_iterator begin() const { return _keymaps.begin(); }
+		iterator end() { return _keymaps.end(); }
+		const_iterator end() const { return _keymaps.end(); }
+		uint32 count() { return _keymaps.size(); }
+	private:
+		ConfigManager::Domain *_configDomain;
+		KeymapMap _keymaps;
+	};
+
+	Keymapper(EventManager *eventMan);
+	~Keymapper();
+
+	/**
+	 * Registers a HardwareKeySet with the Keymapper
+	 * @note should only be called once (during backend initialisation)
+	 */
+	void registerHardwareKeySet(HardwareKeySet *keys);
+
+	/**
+	 * Get the HardwareKeySet that is registered with the Keymapper
+	 */
+	HardwareKeySet *getHardwareKeySet() { return _hardwareKeys; }
+
+	/**
+	 * Add a keymap to the global domain.
+	 * If a saved key setup exists for it in the ini file it will be used.
+	 * Else, the key setup will be automatically mapped.
+	 */
+	void addGlobalKeymap(Keymap *keymap);
+
+	/**
+	 * Add a keymap to the game domain.
+	 * @see addGlobalKeyMap
+	 * @note initGame() should be called before any game keymaps are added.
+	 */
+	void addGameKeymap(Keymap *keymap);
+
+	/**
+	 * Should be called at end of game to tell Keymapper to deactivate and free
+	 * any game keymaps that are loaded.
+	 */
+	void cleanupGameKeymaps();
+
+	/**
+	 * Obtain a keymap of the given name from the keymapper.
+	 * Game keymaps have priority over global keymaps
+	 * @param name		name of the keymap to return
+	 * @param global	set to true if returned keymap is global, false if game
+	 */
+	Keymap *getKeymap(const String& name, bool &global);
+
+	/**
+	 * Push a new keymap to the top of the active stack, activating 
+	 * it for use.
+	 * @param name		name of the keymap to push
+	 * @param inherit	if true keymapper will iterate down the 
+	 *					stack it cannot find a key in the new map
+	 * @return			true if succesful
+	 */
+	bool pushKeymap(const String& name, bool inherit = false);
+
+	/**
+	 * Pop the top keymap off the active stack.
+	 */
+	void popKeymap();
+
+	/**
+	 * @brief Map a key press event.
+	 * If the active keymap contains a Action mapped to the given key, then 
+	 * the Action's events are pushed into the EventManager's event queue.
+	 * @param key		key that was pressed
+	 * @param keyDown	true for key down, false for key up
+	 * @return			true if key was mapped
+	 */
+	bool mapKey(const KeyState& key, bool keyDown);
+
+	/**
+	 * @brief Map a key down event.
+	 * @see mapKey
+	 */
+	bool mapKeyDown(const KeyState& key);
+
+	/**
+	 * @brief Map a key up event.
+	 * @see mapKey
+	 */
+	bool mapKeyUp(const KeyState& key);
+
+	/**
+	 * Enable/disable the keymapper
+	 */
+	void setEnabled(bool enabled) { _enabled = enabled; }
+
+	/**
+	 * Return a HardwareKey pointer for the given key state
+	 */
+	const HardwareKey *getHardwareKey(const KeyState& key);
+
+	Domain& getGlobalDomain() { return _globalDomain; }
+	Domain& getGameDomain() { return _gameDomain; }
+	Stack<MapRecord>& getActiveStack() { return _activeMaps; }
+
+private:
+
+	void initKeymap(ConfigManager::Domain *domain, Keymap *keymap);
+	void refreshGameDomain();
+
+	Domain _globalDomain;
+	Domain _gameDomain;
+
+	HardwareKeySet *_hardwareKeys;
+
+	void pushKeymap(Keymap *newMap, bool inherit, bool global);
+	
+	Action *getAction(const KeyState& key);
+	void executeAction(const Action *act, bool keyDown);
+
+	typedef List<HardwareKey*>::iterator Iterator;
+
+	EventManager *_eventMan;
+
+	bool _enabled;
+
+	Stack<MapRecord> _activeMaps;
+	HashMap<KeyState, Action*> _keysDown;
+
+};
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef COMMON_KEYMAPPER_H


Property changes on: scummvm/trunk/backends/keymapper/keymapper.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/remap-dialog.cpp
===================================================================
--- scummvm/trunk/backends/keymapper/remap-dialog.cpp	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/remap-dialog.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,334 @@
+/* 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$
+ */
+
+#include "backends/keymapper/remap-dialog.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "gui/eval.h"
+#include "gui/newgui.h"
+#include "gui/PopUpWidget.h"
+#include "gui/ScrollBarWidget.h"
+
+namespace Common {
+
+enum {
+	kRemapCmd = 'REMP',
+	kCloseCmd = 'CLOS'
+};
+
+RemapDialog::RemapDialog()
+	: Dialog("remap"), _keymapTable(0), _activeRemapAction(0), _topAction(0), _remapTimeout(0) {
+
+	_keymapper = g_system->getEventManager()->getKeymapper();
+	assert(_keymapper);
+
+	int labelWidth = g_gui.evaluator()->getVar("remap_popup_labelW");
+	_kmPopUp = new GUI::PopUpWidget(this, "remap_popup", "Keymap: ", labelWidth);
+
+	_scrollBar = new GUI::ScrollBarWidget(this, 0, 0, 0, 0);
+
+	new GUI::ButtonWidget(this, "remap_close_button", "Close", kCloseCmd);
+}
+
+RemapDialog::~RemapDialog() {
+	if (_keymapTable) free(_keymapTable);
+}
+
+void RemapDialog::open() {
+	bool divider = false;
+	_activeKeymaps = &_keymapper->getActiveStack();
+	if (_activeKeymaps->size() > 0) {
+		_kmPopUp->appendEntry(_activeKeymaps->top().keymap->getName() + " (Active)");
+		divider = true;
+	}
+
+	Keymapper::Domain *_globalKeymaps = &_keymapper->getGlobalDomain();
+	Keymapper::Domain *_gameKeymaps = 0;
+
+	int keymapCount = 0;
+	if (_globalKeymaps->count() == 0)
+		_globalKeymaps = 0;
+	else
+		keymapCount += _globalKeymaps->count();
+
+	if (ConfMan.getActiveDomain() != 0) {
+		_gameKeymaps = &_keymapper->getGameDomain();
+		if (_gameKeymaps->count() == 0)
+			_gameKeymaps = 0;
+		else
+			keymapCount += _gameKeymaps->count();
+	}
+
+	_keymapTable = (Keymap**)malloc(sizeof(Keymap*) * keymapCount);
+
+	Keymapper::Domain::iterator it;
+	uint32 idx = 0;
+	if (_globalKeymaps) {
+		if (divider) _kmPopUp->appendEntry("");
+		for (it = _globalKeymaps->begin(); it != _globalKeymaps->end(); it++) {
+			_kmPopUp->appendEntry(it->_value->getName() + " (Global)", idx);
+			_keymapTable[idx++] = it->_value;
+		}
+		divider = true;
+	}
+	if (_gameKeymaps) {
+		if (divider) _kmPopUp->appendEntry("");
+		for (it = _gameKeymaps->begin(); it != _gameKeymaps->end(); it++) {
+			_kmPopUp->appendEntry(it->_value->getName() + " (Game)", idx);
+			_keymapTable[idx++] = it->_value;
+		}
+	}
+
+	_changes = false;
+
+	Dialog::open();
+
+	_kmPopUp->setSelected(0);
+	loadKeymap();
+}
+
+void RemapDialog::close() {
+	_kmPopUp->clearEntries();
+	if (_keymapTable) {
+		free(_keymapTable);
+		_keymapTable = 0;
+	}
+	if (_changes) 
+		ConfMan.flushToDisk();
+	Dialog::close();
+}
+
+void RemapDialog::reflowLayout() {
+	int scrollbarWidth, buttonHeight;
+	if (g_gui.getWidgetSize() == GUI::kBigWidgetSize) {
+		buttonHeight = GUI::kBigButtonHeight;
+		scrollbarWidth = GUI::kBigScrollBarWidth;
+	} else {
+		buttonHeight = GUI::kButtonHeight;
+		scrollbarWidth = GUI::kNormalScrollBarWidth;
+	}
+	int areaX = g_gui.evaluator()->getVar("remap_keymap_area.x");
+	int areaY = g_gui.evaluator()->getVar("remap_keymap_area.y");
+	int areaW = g_gui.evaluator()->getVar("remap_keymap_area.w");
+	int areaH = g_gui.evaluator()->getVar("remap_keymap_area.h");
+	int spacing = g_gui.evaluator()->getVar("remap_spacing");
+	int labelWidth = g_gui.evaluator()->getVar("remap_label_width");
+	int buttonWidth = g_gui.evaluator()->getVar("remap_button_width");
+	int colWidth = labelWidth + buttonWidth + spacing;
+	_colCount = (areaW - scrollbarWidth) / colWidth;
+	_rowCount = (areaH + spacing) / (buttonHeight + spacing);
+	if (_colCount <= 0 || _rowCount <= 0) 
+		error("Remap dialog too small to display any keymaps!");
+
+	_kmPopUp->changeLabelWidth(labelWidth);
+
+	_scrollBar->resize(areaX + areaW - scrollbarWidth, areaY, scrollbarWidth, areaH);
+	_scrollBar->_entriesPerPage = _rowCount;
+	_scrollBar->_numEntries = 1;
+	_scrollBar->recalc();
+
+	uint textYOff = (buttonHeight - kLineHeight) / 2;
+	uint oldSize = _keymapWidgets.size();
+	uint newSize = _rowCount * _colCount;
+	_keymapWidgets.reserve(newSize);
+	for (uint i = 0; i < newSize; i++) {
+		ActionWidgets widg;
+		if (i >= _keymapWidgets.size()) {
+			widg.actionText = 
+				new GUI::StaticTextWidget(this, 0, 0, 0, 0, "", Graphics::kTextAlignRight);
+			widg.keyButton = 
+				new GUI::ButtonWidget(this, 0, 0, 0, 0, "", kRemapCmd + i);
+			_keymapWidgets.push_back(widg);
+		} else {
+			widg = _keymapWidgets[i];
+		}
+		uint x = areaX + (i % _colCount) * colWidth;
+		uint y = areaY + (i / _colCount) * (buttonHeight + spacing);
+		widg.actionText->resize(x, y + textYOff, labelWidth, kLineHeight);
+		widg.keyButton->resize(x + labelWidth, y, buttonWidth, buttonHeight);
+	}
+	while (oldSize > newSize) {
+		ActionWidgets widg = _keymapWidgets.remove_at(--oldSize);
+		removeWidget(widg.actionText);
+		delete widg.actionText;
+		removeWidget(widg.keyButton);
+		delete widg.keyButton;
+	}
+	Dialog::reflowLayout();
+}
+
+void RemapDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) {
+	if (cmd >= kRemapCmd && cmd < kRemapCmd + _keymapWidgets.size()) {
+		startRemapping(cmd - kRemapCmd);
+	} else if (cmd == GUI::kPopUpItemSelectedCmd) {
+		loadKeymap();
+	} else if (cmd == GUI::kSetPositionCmd) {
+		refreshKeymap();
+	} else if (cmd == kCloseCmd) {
+		close();
+	} else {
+		GUI::Dialog::handleCommand(sender, cmd, data);
+	}
+}
+
+void RemapDialog::startRemapping(uint i) {
+	if (_topAction + i >= _currentActions.size()) return; 
+	_remapTimeout = getMillis() + kRemapTimeoutDelay;
+	_activeRemapAction = _currentActions[_topAction + i].action;
+	_keymapWidgets[i].keyButton->setLabel("...");
+	_keymapWidgets[i].keyButton->draw();
+	_keymapper->setEnabled(false);
+
+}
+
+void RemapDialog::stopRemapping() {
+	_topAction = -1;
+	refreshKeymap();
+	_activeRemapAction = 0;
+	_keymapper->setEnabled(true);
+}
+
+void RemapDialog::handleKeyUp(Common::KeyState state) {
+	if (_activeRemapAction) {
+		const HardwareKey *hwkey = _keymapper->getHardwareKey(state);
+		if (hwkey) {
+			_activeRemapAction->mapKey(hwkey);
+			// TODO:   _activeRemapAction->getParent()->saveMappings();
+			_changes = true;
+			stopRemapping();
+		}
+	} else {
+		GUI::Dialog::handleKeyDown(state);
+	}
+}
+
+void RemapDialog::handleMouseDown(int x, int y, int button, int clickCount) {
+	if (_activeRemapAction)
+		stopRemapping();
+	else
+		Dialog::handleMouseDown(x, y, button, clickCount);
+}
+
+void RemapDialog::handleTickle() {
+	if (_activeRemapAction && getMillis() > _remapTimeout)
+		stopRemapping();
+	Dialog::handleTickle();
+}
+
+void RemapDialog::loadKeymap() {
+	_currentActions.clear();
+	if (_activeKeymaps->size() > 0 && _kmPopUp->getSelected() == 0) {
+		// load active keymaps
+
+		List<const HardwareKey*> freeKeys (_keymapper->getHardwareKeySet()->getHardwareKeys());
+
+		// add most active keymap's keys
+		Keymapper::MapRecord top = _activeKeymaps->top();
+		List<Action*>::iterator actIt;
+		for (actIt = top.keymap->getActions().begin(); actIt != top.keymap->getActions().end(); ++actIt) {
+			Action *act = *actIt;
+			ActionInfo info = {act, false, act->description};
+			_currentActions.push_back(info);
+			if (act->getMappedKey())
+				freeKeys.remove(act->getMappedKey());
+		}
+		
+		// loop through remaining finding mappings for unmapped keys
+		if (top.inherit) {
+			for (int i = _activeKeymaps->size() - 2; i >= 0; --i) {
+				Keymapper::MapRecord mr = (*_activeKeymaps)[i];
+				List<const HardwareKey*>::iterator keyIt = freeKeys.begin();
+				while (keyIt != freeKeys.end()) {
+					Action *act = mr.keymap->getMappedAction((*keyIt)->key);
+					if (act) {
+						ActionInfo info = {act, true, act->description + " (" + mr.keymap->getName() + ")"};
+						_currentActions.push_back(info);
+						freeKeys.erase(keyIt++);
+					} else {
+						++keyIt;
+					}
+				}
+				if (mr.inherit == false || freeKeys.empty()) break;
+			}
+		}
+
+	} else if (_kmPopUp->getSelected() != -1) {
+		Keymap *km = _keymapTable[_kmPopUp->getSelectedTag()];
+
+		List<Action*>::iterator it;
+		for (it = km->getActions().begin(); it != km->getActions().end(); it++) {
+			ActionInfo info = {*it, false, (*it)->description};
+			_currentActions.push_back(info);
+		}
+	}
+
+	// refresh scroll bar
+	_scrollBar->_currentPos = 0;
+	_scrollBar->_numEntries = (_currentActions.size() + _colCount - 1) / _colCount;
+	_scrollBar->recalc();
+	// force refresh
+	_topAction = -1;
+	refreshKeymap();
+}
+
+void RemapDialog::refreshKeymap() {
+	int newTopAction = _scrollBar->_currentPos * _colCount;
+	if (newTopAction == _topAction) return;
+	_topAction = newTopAction;
+
+	//_container->draw();
+	_scrollBar->draw();
+
+	uint actionI = _topAction;
+	for (uint widgetI = 0; widgetI < _keymapWidgets.size(); widgetI++) {
+		ActionWidgets& widg = _keymapWidgets[widgetI];
+		if (actionI < _currentActions.size()) {
+			ActionInfo&    info = _currentActions[actionI];
+			widg.actionText->setLabel(info.description + ": ");
+			widg.actionText->setEnabled(!info.inherited);
+			const HardwareKey *mappedKey = info.action->getMappedKey();
+			if (mappedKey)
+				widg.keyButton->setLabel(mappedKey->description);
+			else
+				widg.keyButton->setLabel("-");
+			widg.actionText->clearFlags(GUI::WIDGET_INVISIBLE);
+			widg.keyButton->clearFlags(GUI::WIDGET_INVISIBLE);
+			actionI++; 
+		} else {
+			widg.actionText->setFlags(GUI::WIDGET_INVISIBLE);
+			widg.keyButton->setFlags(GUI::WIDGET_INVISIBLE);
+		}
+		//widg.actionText->draw();
+		//widg.keyButton->draw();
+	}
+	// need to redraw entire Dialog so that invisible 
+	// widgets disappear
+	draw();
+}
+
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER


Property changes on: scummvm/trunk/backends/keymapper/remap-dialog.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/remap-dialog.h
===================================================================
--- scummvm/trunk/backends/keymapper/remap-dialog.h	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/remap-dialog.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,98 @@
+/* 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 REMAP_DIALOG_H
+#define REMAP_DIALOG_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+#include "backends/keymapper/keymapper.h"
+#include "gui/dialog.h"
+
+namespace GUI {
+	class PopupWidget;
+	class ScrollBarWidget;
+}
+
+namespace Common {
+
+class RemapDialog : public GUI::Dialog {
+public:
+	RemapDialog();
+	virtual ~RemapDialog();
+	virtual void open();
+	virtual void close();
+	virtual void reflowLayout();
+	virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+	virtual void handleKeyUp(Common::KeyState state);
+	virtual void handleMouseDown(int x, int y, int button, int clickCount);
+	virtual void handleTickle();
+
+protected:
+	struct ActionWidgets {
+		GUI::StaticTextWidget *actionText;
+		GUI::ButtonWidget *keyButton;
+	};
+	struct ActionInfo {
+		Action *action;
+		bool inherited;
+		String description;
+	};
+
+	void loadKeymap();
+	void refreshKeymap();
+	void startRemapping(uint i);
+	void stopRemapping();
+
+	Keymapper *_keymapper;
+	Stack<Keymapper::MapRecord> *_activeKeymaps;
+	Keymap** _keymapTable;
+
+	Array<ActionInfo> _currentActions;
+	int _topAction;
+
+	Rect _keymapArea;
+
+	GUI::PopUpWidget *_kmPopUp;
+	//GUI::ContainerWidget *_container;
+	GUI::ScrollBarWidget *_scrollBar;
+
+	uint _colCount, _rowCount;
+
+	Array<ActionWidgets> _keymapWidgets;
+	Action *_activeRemapAction;
+	uint32 _remapTimeout;
+	static const uint32 kRemapTimeoutDelay = 3000;
+
+	bool _changes;
+
+};
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef REMAP_DIALOG_H


Property changes on: scummvm/trunk/backends/keymapper/remap-dialog.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/keymapper/types.h
===================================================================
--- scummvm/trunk/backends/keymapper/types.h	                        (rev 0)
+++ scummvm/trunk/backends/keymapper/types.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,77 @@
+/* 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_TYPES_H
+#define COMMON_TYPES_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_KEYMAPPER
+
+namespace Common {
+
+enum KeyType {
+	kGenericKeyType,
+	kDirUpKeyType,
+	kDirDownKeyType,
+	kDirLeftKeyType,
+	kDirRightKeyType,
+	kActionKeyType,
+	kTriggerLeftKeyType,
+	kTriggerRightKeyType,
+	kStartKeyType,
+	kSelectKeyType,
+	/*  ...  */
+
+	kKeyTypeMax
+};
+
+enum ActionType {
+	kGenericActionType,
+
+	// common actions
+	kDirUpActionType,
+	kDirDownActionType,
+	kDirLeftActionType,
+	kDirRightActionType,
+	kLeftClickActionType,
+	kRightClickActionType,
+	kSaveActionType,
+	kMenuActionType,
+	kQuitActionType,
+	kVirtualKeyboardActionType,
+	kKeyRemapActionType,
+	kVolumeUpActionType,
+	kVolumeDownActionType,
+
+
+	kActionTypeMax
+};
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_KEYMAPPER
+
+#endif // #ifndef COMMON_TYPES_H


Property changes on: scummvm/trunk/backends/keymapper/types.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Modified: scummvm/trunk/backends/platform/sdl/events.cpp
===================================================================
--- scummvm/trunk/backends/platform/sdl/events.cpp	2009-01-11 00:02:28 UTC (rev 35812)
+++ scummvm/trunk/backends/platform/sdl/events.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -24,6 +24,7 @@
  */
 
 #include "backends/platform/sdl/sdl.h"
+#include "backends/keymapper/keymapper.h"
 #include "common/util.h"
 #include "common/events.h"
 
@@ -521,3 +522,62 @@
 	return false;
 }
 
+void OSystem_SDL::setupKeymapper() {
+#ifdef ENABLE_KEYMAPPER
+	using namespace Common;
+	Keymapper *mapper = getEventManager()->getKeymapper();
+
+	HardwareKeySet *keySet = new HardwareKeySet();
+	keySet->addHardwareKey(new HardwareKey( "a", KeyState(KEYCODE_a), "a", kActionKeyType ));
+	keySet->addHardwareKey(new HardwareKey( "s", KeyState(KEYCODE_s), "s", kActionKeyType ));
+	keySet->addHardwareKey(new HardwareKey( "d", KeyState(KEYCODE_d), "d", kActionKeyType ));
+	keySet->addHardwareKey(new HardwareKey( "f", KeyState(KEYCODE_f), "f", kActionKeyType ));
+	keySet->addHardwareKey(new HardwareKey( "n", KeyState(KEYCODE_n), "n (vk)", kTriggerLeftKeyType, kVirtualKeyboardActionType ));
+	keySet->addHardwareKey(new HardwareKey( "m", KeyState(KEYCODE_m), "m (remap)", kTriggerRightKeyType, kKeyRemapActionType ));
+	keySet->addHardwareKey(new HardwareKey( "[", KeyState(KEYCODE_LEFTBRACKET), "[ (select)", kSelectKeyType ));
+	keySet->addHardwareKey(new HardwareKey( "]", KeyState(KEYCODE_RIGHTBRACKET), "] (start)", kStartKeyType ));
+	mapper->registerHardwareKeySet(keySet);
+
+	Keymap *globalMap = new Keymap("global");
+	Keymap *guiMap = new Keymap("gui");
+	Action *act;
+	Event evt ;
+
+	act = new Action(globalMap, "MENU", "Menu", kGenericActionType, kSelectKeyType);
+	act->addKeyEvent(KeyState(KEYCODE_F5, ASCII_F5, 0));
+	
+	act = new Action(globalMap, "SKCT", "Skip", kGenericActionType, kActionKeyType);
+	act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
+
+	act = new Action(globalMap, "PAUS", "Pause", kGenericActionType, kStartKeyType);
+	act->addKeyEvent(KeyState(KEYCODE_SPACE, ' ', 0));
+	
+	act = new Action(globalMap, "SKLI", "Skip line", kGenericActionType, kActionKeyType);
+	act->addKeyEvent(KeyState(KEYCODE_PERIOD, '.', 0));
+
+	act = new Action(globalMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType);
+	act->addKeyEvent(KeyState(KEYCODE_F6, ASCII_F6, 0));
+
+	act = new Action(globalMap, "REMP", "Remap keys", kKeyRemapActionType);
+	act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+
+	mapper->addGlobalKeymap(globalMap);
+
+	act = new Action(guiMap, "CLOS", "Close", kGenericActionType, kStartKeyType);
+	act->addKeyEvent(KeyState(KEYCODE_ESCAPE, ASCII_ESCAPE, 0));
+	
+	act = new Action(guiMap, "CLIK", "Mouse click");
+	act->addLeftClickEvent();
+
+	act = new Action(guiMap, "VIRT", "Display keyboard", kVirtualKeyboardActionType);
+	act->addKeyEvent(KeyState(KEYCODE_F6, ASCII_F6, 0));
+
+	act = new Action(guiMap, "REMP", "Remap keys", kKeyRemapActionType);
+	act->addKeyEvent(KeyState(KEYCODE_F7, ASCII_F7, 0));
+
+	mapper->addGlobalKeymap(guiMap);
+
+	mapper->pushKeymap("global");
+#endif
+}
+

Modified: scummvm/trunk/backends/platform/sdl/sdl.cpp
===================================================================
--- scummvm/trunk/backends/platform/sdl/sdl.cpp	2009-01-11 00:02:28 UTC (rev 35812)
+++ scummvm/trunk/backends/platform/sdl/sdl.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -169,6 +169,11 @@
 		setupMixer();
 	}
 
+	// Setup the keymapper with backend's set of keys
+	// NOTE: must be done before creating TimerManager 
+	// to avoid race conditions in creating EventManager
+	setupKeymapper();
+
 	// Create and hook up the timer manager, if none exists yet (we check for
 	// this to allow subclasses to provide their own).
 	if (_timer == 0) {

Modified: scummvm/trunk/backends/platform/sdl/sdl.h
===================================================================
--- scummvm/trunk/backends/platform/sdl/sdl.h	2009-01-11 00:02:28 UTC (rev 35812)
+++ scummvm/trunk/backends/platform/sdl/sdl.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -137,6 +137,9 @@
 	// Returns true if an event was retrieved.
 	virtual bool pollEvent(Common::Event &event); // overloaded by CE backend
 
+	// Sets up the keymapper with the backends hardware key set
+	virtual void setupKeymapper();
+
 	// Set function that generates samples
 	virtual void setupMixer();
 	static void mixCallback(void *s, byte *samples, int len);

Added: scummvm/trunk/backends/vkeybd/image-map.cpp
===================================================================
--- scummvm/trunk/backends/vkeybd/image-map.cpp	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/image-map.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,73 @@
+/* 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$
+ *
+ */
+
+#include "backends/vkeybd/image-map.h"
+
+#ifdef ENABLE_VKEYBD
+
+namespace Common {
+
+ImageMap::~ImageMap() {
+	removeAllAreas();
+}
+
+Polygon *ImageMap::createArea(const String& id) {
+	if (_areas.contains(id)) {
+		warning("Image map already contains an area with target of '%s'", id.c_str());
+		return 0;
+	}
+	Polygon *p = new Polygon();
+	_areas[id] = p;
+	return p;
+}
+
+void ImageMap::removeArea(const String& id) {
+	if (!_areas.contains(id))
+		return;
+	delete _areas[id];
+	_areas.erase(id);
+}
+
+void ImageMap::removeAllAreas() {
+	HashMap<String, Polygon*>::iterator it;
+	for (it = _areas.begin(); it != _areas.end(); it++) {
+		delete it->_value;
+	}
+	_areas.clear();
+}
+
+String ImageMap::findMapArea(int16 x, int16 y) {
+	HashMap<String, Polygon*>::iterator it;
+	for (it = _areas.begin(); it != _areas.end(); it++) {
+		if (it->_value->contains(x, y))
+			return it->_key;
+	}
+	return "";
+}
+
+
+} // End of namespace Common
+
+#endif // #ifdef ENABLE_VKEYBD


Property changes on: scummvm/trunk/backends/vkeybd/image-map.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/image-map.h
===================================================================
--- scummvm/trunk/backends/vkeybd/image-map.h	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/image-map.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,59 @@
+/* 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_IMAGEMAP_H
+#define COMMON_IMAGEMAP_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_VKEYBD
+
+#include "common/hashmap.h"
+#include "common/hash-str.h"
+#include "backends/vkeybd/polygon.h"
+
+namespace Common {
+
+class ImageMap {
+
+public:
+
+	~ImageMap();
+	
+	Polygon *createArea(const String& id);
+	void removeArea(const String& id);
+	void removeAllAreas();
+	String findMapArea(int16 x, int16 y);
+
+protected:
+	HashMap<String, Polygon*> _areas;
+};
+
+
+} // End of namespace Common
+
+#endif // #ifdef ENABLE_VKEYBD
+
+#endif // #ifndef COMMON_IMAGEMAP_H


Property changes on: scummvm/trunk/backends/vkeybd/image-map.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/keycode-descriptions.h
===================================================================
--- scummvm/trunk/backends/vkeybd/keycode-descriptions.h	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/keycode-descriptions.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,335 @@
+#ifndef KEYCODE_DESCRIPTIONS_H
+#define KEYCODE_DESCRIPTIONS_H
+
+#ifdef ENABLE_VKEYBD
+
+static const char *keycodeDescTable[] = {
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"Backspace",
+	"Tab",
+	"",
+	"",
+	"Clear",
+	"Return",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"Pause",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"Escape",
+	"",
+	"",
+	"",
+	"",
+	" ",
+	"!",
+	"\"",
+	"#",
+	"$",
+	"%",
+	"&",
+	"'",
+	"(",
+	")",
+	"*",
+	"+",
+	",",
+	"-",
+	".",
+	"/",
+	"0",
+	"1",
+	"2",
+	"3",
+	"4",
+	"5",
+	"6",
+	"7",
+	"8",
+	"9",
+	":",
+	";",
+	"<",
+	"=",
+	">",
+	"?",
+	"@",
+	"A",
+	"B",
+	"C",
+	"D",
+	"E",
+	"F",
+	"G",
+	"H",
+	"I",
+	"J",
+	"K",
+	"L",
+	"M",
+	"N",
+	"O",
+	"P",
+	"Q",
+	"R",
+	"S",
+	"T",
+	"U",
+	"V",
+	"W",
+	"X",
+	"Y",
+	"Z",
+	"[",
+	"\\",
+	"]",
+	"^",
+	"_",
+	"`",
+	"a",
+	"b",
+	"c",
+	"d",
+	"e",
+	"f",
+	"g",
+	"h",
+	"i",
+	"j",
+	"k",
+	"l",
+	"m",
+	"n",
+	"o",
+	"p",
+	"q",
+	"r",
+	"s",
+	"t",
+	"u",
+	"v",
+	"w",
+	"x",
+	"y",
+	"z",
+	"{",
+	"|",
+	"}",
+	"~",
+	"Delete",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"",
+	"0",
+	"1",
+	"2",
+	"3",
+	"4",
+	"5",
+	"6",
+	"7",
+	"8",
+	"9",
+	".",
+	"/",
+	"*",
+	"-",
+	"+",
+	"Enter",
+	"=",
+	"Up",
+	"Down",
+	"Right",
+	"Left",
+	"Ins",
+	"Home",
+	"End",
+	"Page Up",
+	"Page Down",
+	"F1",
+	"F2",
+	"F3",
+	"F4",
+	"F5",
+	"F6",
+	"F7",
+	"F8",
+	"F9",
+	"F10",
+	"F11",
+	"F12",
+	"F13",
+	"F14",
+	"F15",
+	"",
+	"",
+	"",
+	"Num Lock",
+	"Caps Lock",
+	"Scroll Lock",
+	"Shift",
+	"Shift",
+	"Ctrl",
+	"Ctrl",
+	"Alt",
+	"Alt",
+	"Meta",
+	"Meta",
+	"Super",
+	"Super",
+	"Mode",
+	"Compose",
+	"Help",
+	"Print",
+	"SysReq",
+	"Break",
+	"Menu",
+	"Power",
+	"\x80",
+	"Undo"
+};
+static const int keycodeDescTableSize = 322;
+
+#endif // #ifdef ENABLE_VKEYBD
+
+#endif // #ifndef KEYCODE_DESCRIPTIONS_H


Property changes on: scummvm/trunk/backends/vkeybd/keycode-descriptions.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/polygon.cpp
===================================================================
--- scummvm/trunk/backends/vkeybd/polygon.cpp	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/polygon.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,59 @@
+/* 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$
+ *
+ */
+
+#include "backends/vkeybd/polygon.h"
+
+#ifdef ENABLE_VKEYBD
+
+namespace Common {
+
+bool Polygon::contains(int16 x, int16 y) const {
+	int yflag0;
+	int yflag1;
+	bool inside_flag = false;
+	unsigned int pt;
+
+	const Point *vtx0 = &_points[_points.size() - 1];
+	const Point *vtx1 = &_points[0];
+
+	yflag0 = (vtx0->y >= y);
+	for (pt = 0; pt < _points.size(); pt++, vtx1++) {
+		yflag1 = (vtx1->y >= y);
+		if (yflag0 != yflag1) {
+			if (((vtx1->y - y) * (vtx0->x - vtx1->x) >=
+				(vtx1->x - x) * (vtx0->y - vtx1->y)) == yflag1) {
+				inside_flag = !inside_flag;
+			}
+		}
+		yflag0 = yflag1;
+		vtx0 = vtx1;
+	}
+
+	return inside_flag;
+}
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_VKEYBD


Property changes on: scummvm/trunk/backends/vkeybd/polygon.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/polygon.h
===================================================================
--- scummvm/trunk/backends/vkeybd/polygon.h	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/polygon.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,120 @@
+/* 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_POLYGON_H
+#define COMMON_POLYGON_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_VKEYBD
+
+#include "common/array.h"
+#include "common/rect.h"
+
+namespace Common {
+
+struct Polygon {
+
+
+	Polygon() {}
+	Polygon(const Polygon& p) : _points(p._points), _bound(p._bound) {}
+	Polygon(Array<Point> p) : _points(p) {
+		if (p.empty()) return;
+		_bound = Rect(p[0].x, p[0].y, p[0].x, p[0].y);
+		for (uint i = 1; i < p.size(); i++) {
+			_bound.extend(Rect(p[i].x, p[i].y, p[i].x, p[i].y));
+		}
+	}
+	Polygon(Point *p, int n) {
+		for (int i = 0; i < n; i++) {
+			addPoint(p[i]);
+		}
+	}
+	virtual ~Polygon() {}
+
+	void addPoint(const Point& p) {
+		_points.push_back(p);
+		_bound.extend(Rect(p.x, p.y, p.x, p.y));
+	}
+
+	void addPoint(int16 x, int16 y) {
+		addPoint(Point(x,y));
+	}
+
+	uint getPointCount() {
+		return _points.size();
+	}
+
+	/*!	@brief check if given position is inside this polygon
+
+		@param x the horizontal position to check
+		@param y the vertical position to check
+
+		@return true if the given position is inside this polygon, false otherwise
+	*/
+	virtual bool contains(int16 x, int16 y) const;
+
+	/*!	@brief check if given point is inside this polygon
+
+		@param p the point to check
+
+		@return true if the given point is inside this polygon, false otherwise
+	*/
+	virtual bool contains(const Point &p) const {
+		return contains(p.x, p.y);
+	}
+
+	virtual void moveTo(int16 x, int16 y) {
+		int16 dx = x - ((_bound.right + _bound.left) / 2);
+		int16 dy = y - ((_bound.bottom + _bound.top) / 2);
+		translate(dx, dy);
+	}
+
+	virtual void moveTo(const Point &p) {
+		moveTo(p.x, p.y);
+	}
+
+	virtual void translate(int16 dx, int16 dy) {
+		Array<Point>::iterator it;
+		for (it = _points.begin(); it != _points.end(); it++) {
+			it->x += dx;
+			it->y += dy;
+		}
+	}
+
+	virtual Rect getBoundingRect() const {
+		return _bound;
+	}
+
+private:
+	Array<Point> _points;
+	Rect _bound;
+};
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_VKEYBD
+
+#endif // #ifndef COMMON_POLYGON_H


Property changes on: scummvm/trunk/backends/vkeybd/polygon.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.cpp
===================================================================
--- scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.cpp	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,421 @@
+/* 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$
+*
+*/
+
+#include "backends/vkeybd/virtual-keyboard-gui.h"
+
+#ifdef ENABLE_VKEYBD
+
+#include "graphics/cursorman.h"
+#include "gui/newgui.h"
+
+namespace Common {
+
+VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd)
+	: _kbd(kbd), _displaying(false), _drag(false),	
+	_drawCaret(false), 	_displayEnabled(false),	_firstRun(true), 
+	_cursorAnimateTimer(0), _cursorAnimateCounter(0) {
+	
+	assert(_kbd);
+	assert(g_system);
+	_system = g_system;
+	
+	_lastScreenChanged = _system->getScreenChangeID();
+	_screenW = _system->getOverlayWidth();
+	_screenH = _system->getOverlayHeight();
+
+	
+	memset(_cursor, 0xFF, sizeof(_cursor));
+}
+
+VirtualKeyboardGUI::~VirtualKeyboardGUI() {
+	_overlayBackup.free();
+	_dispSurface.free();
+}
+
+void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) {
+	_kbdSurface = mode->image;
+	_kbdTransparentColor = mode->transparentColor;
+	_kbdBound.setWidth(_kbdSurface->w);
+	_kbdBound.setHeight(_kbdSurface->h);
+
+	if (mode->displayArea)
+		setupDisplayArea(*(mode->displayArea), mode->displayFontColor);
+
+	if (_displaying) {
+		extendDirtyRect(_kbdBound);
+		redraw();
+	}
+}
+
+void VirtualKeyboardGUI::setupDisplayArea(Rect& r, OverlayColor forecolor) {
+
+	_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
+	if (!fontIsSuitable(_dispFont, r)) {
+		_dispFont = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont);
+		if (!fontIsSuitable(_dispFont, r)) {
+			_displayEnabled = false;
+			return;
+		}
+	}
+	_dispX = _kbdBound.left + r.left;
+	_dispY = _kbdBound.top + r.top + (r.height() - _dispFont->getFontHeight()) / 2;
+	_dispI = 0;
+	_dispForeColor = forecolor;
+	_dispBackColor = _dispForeColor + 0xFF;
+	_dispSurface.create(r.width(), _dispFont->getFontHeight(), sizeof(OverlayColor));
+	_dispSurface.fillRect(Rect(_dispSurface.w, _dispSurface.h), _dispBackColor);
+	_displayEnabled = true;
+}
+
+bool VirtualKeyboardGUI::fontIsSuitable(const Graphics::Font *font, const Rect& rect) {
+	return (font->getMaxCharWidth() < rect.width() &&
+			font->getFontHeight() < rect.height());
+}
+
+void VirtualKeyboardGUI::checkScreenChanged() {
+	if (_lastScreenChanged != _system->getScreenChangeID())
+		screenChanged(); 
+}
+
+void VirtualKeyboardGUI::initSize(int16 w, int16 h) {
+	_screenW = w;
+	_screenH = h;
+}
+
+void VirtualKeyboardGUI::run() {
+	if (_firstRun) {
+		_firstRun = false;
+		moveToDefaultPosition();
+	}
+
+	if (!g_gui.isActive()) {
+		_system->showOverlay();
+		_system->clearOverlay();
+	}
+	_overlayBackup.create(_screenW, _screenH, sizeof(OverlayColor));
+	_system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w);
+
+	setupCursor();
+
+	forceRedraw();
+	_displaying = true;
+	mainLoop();
+
+	removeCursor();
+
+	_system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h);
+	if (!g_gui.isActive()) _system->hideOverlay();
+
+	_overlayBackup.free();
+	_dispSurface.free();
+}
+
+void VirtualKeyboardGUI::close() {
+	_displaying = false;
+}
+
+void VirtualKeyboardGUI::reset() {
+	_kbdBound.left = _kbdBound.top
+		= _kbdBound.right = _kbdBound.bottom = 0;
+	_displaying = _drag = false;
+	_firstRun = true;
+	_lastScreenChanged = _system->getScreenChangeID();
+	_kbdSurface = 0;
+}
+
+void VirtualKeyboardGUI::moveToDefaultPosition()
+{
+	int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height();
+	int16 x = 0, y = 0;
+	if (_screenW != kbdW) {
+		switch (_kbd->_hAlignment) {
+		case VirtualKeyboard::kAlignLeft:
+			x = 0;
+			break;
+		case VirtualKeyboard::kAlignCentre:
+			x = (_screenW - kbdW) / 2;
+			break;
+		case VirtualKeyboard::kAlignRight:
+			x = _screenW - kbdW;
+			break;
+		}
+	}
+	if (_screenH != kbdH) {
+		switch (_kbd->_vAlignment) {
+		case VirtualKeyboard::kAlignTop:
+			y = 0;
+			break;
+		case VirtualKeyboard::kAlignMiddle:
+			y = (_screenH - kbdH) / 2;
+			break;
+		case VirtualKeyboard::kAlignBottom:
+			y = _screenH - kbdH;
+			break;
+		}
+	}
+	move(x, y);
+}
+
+void VirtualKeyboardGUI::move(int16 x, int16 y) {
+	// add old position to dirty area
+	if (_displaying) extendDirtyRect(_kbdBound);
+
+	// snap to edge of screen
+	if (ABS(x) < SNAP_WIDTH)
+		x = 0;
+	int16 x2 = _screenW - _kbdBound.width();
+	if (ABS(x - x2) < SNAP_WIDTH)
+		x = x2;
+	if (ABS(y) < SNAP_WIDTH)
+		y = 0;
+	int16 y2 = _screenH - _kbdBound.height();
+	if (ABS(y - y2) < SNAP_WIDTH)
+		y = y2;
+
+	_dispX += x - _kbdBound.left;
+	_dispY += y - _kbdBound.top;
+	_kbdBound.moveTo(x, y);
+
+	if (_displaying) {
+		// add new position to dirty area
+		extendDirtyRect(_kbdBound);
+		redraw();
+	}
+}
+
+void VirtualKeyboardGUI::screenChanged() {
+	_lastScreenChanged = _system->getScreenChangeID();
+	int16 newScreenW = _system->getOverlayWidth();
+	int16 newScreenH = _system->getOverlayHeight();
+	if (_screenW != newScreenW || _screenH != newScreenH) {
+		_screenW = newScreenW;
+		_screenH = newScreenH;
+		if (!_kbd->checkModeResolutions()) {
+			_displaying = false;
+			return;
+		}
+		moveToDefaultPosition();
+	}
+}
+
+
+void VirtualKeyboardGUI::mainLoop() {
+	Common::EventManager *eventMan = _system->getEventManager();
+
+	while (_displaying) {
+		if (_kbd->_keyQueue.hasStringChanged())
+			updateDisplay();
+		animateCaret();
+		animateCursor();
+		redraw();
+		_system->updateScreen();
+		Common::Event event;
+		while (eventMan->pollEvent(event)) {
+			switch (event.type) {
+			case Common::EVENT_LBUTTONDOWN:
+				if (_kbdBound.contains(event.mouse)) {
+					_kbd->handleMouseDown(event.mouse.x - _kbdBound.left,
+										  event.mouse.y - _kbdBound.top);
+				}
+				break;
+			case Common::EVENT_LBUTTONUP:
+				if (_kbdBound.contains(event.mouse)) {
+					_kbd->handleMouseUp(event.mouse.x - _kbdBound.left,
+										event.mouse.y - _kbdBound.top);
+				}
+				break;
+			case Common::EVENT_MOUSEMOVE:
+				if (_drag)
+					move(event.mouse.x - _dragPoint.x, 
+						event.mouse.y - _dragPoint.y);
+				break;
+			case Common::EVENT_SCREEN_CHANGED:
+				screenChanged();
+				break;
+			case Common::EVENT_QUIT:
+				_system->quit();
+				return;
+			default:
+				break;
+			}
+		}
+		// Delay for a moment
+		_system->delayMillis(10);
+	}
+}
+
+void VirtualKeyboardGUI::startDrag(int16 x, int16 y) {
+	_drag = true;
+	_dragPoint.x = x;
+	_dragPoint.y = y;
+}
+
+void VirtualKeyboardGUI::endDrag() {
+	_drag = false;
+}
+
+void VirtualKeyboardGUI::extendDirtyRect(const Rect &r) {
+	if (_dirtyRect.isValidRect()) {
+		_dirtyRect.extend(r);
+	} else {
+		_dirtyRect = r;
+	}
+	_dirtyRect.clip(Rect(_overlayBackup.w, _overlayBackup.h));
+}
+
+void VirtualKeyboardGUI::resetDirtyRect() {
+	_dirtyRect.setWidth(-1);
+}
+
+void VirtualKeyboardGUI::forceRedraw() {
+	updateDisplay();
+	extendDirtyRect(Rect(_overlayBackup.w, _overlayBackup.h));
+	redraw();
+}
+
+void VirtualKeyboardGUI::redraw() {
+	assert(_kbdSurface);
+	int16 w = _dirtyRect.width();
+	int16 h = _dirtyRect.height();
+	if (w <= 0 || h <= 0) return;
+	
+	Graphics::SurfaceKeyColored surf;
+	surf.create(w, h, sizeof(OverlayColor));
+
+	OverlayColor *dst = (OverlayColor *)surf.pixels;
+	const OverlayColor *src = (OverlayColor *) _overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top);
+
+	while (h--) {
+		memcpy(dst, src, surf.w * sizeof(OverlayColor));
+		dst += surf.w;
+		src += _overlayBackup.w;
+	}
+
+	surf.blit(_kbdSurface, _kbdBound.left - _dirtyRect.left, 
+			  _kbdBound.top - _dirtyRect.top, _kbdTransparentColor);
+	if (_displayEnabled) {
+		surf.blit(&_dispSurface, _dispX - _dirtyRect.left, 
+				  _dispY - _dirtyRect.top, _dispBackColor);
+	}
+	_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 
+							   _dirtyRect.left, _dirtyRect.top, surf.w, surf.h);
+
+	surf.free();
+	
+	resetDirtyRect();
+}
+
+uint VirtualKeyboardGUI::calculateEndIndex(const String& str, uint startIndex) {
+	int16 w = 0;
+	while (w <= _dispSurface.w && startIndex < str.size()) {
+		w += _dispFont->getCharWidth(str[startIndex++]);
+	}
+	if (w > _dispSurface.w) startIndex--;
+	return startIndex;
+}
+
+void VirtualKeyboardGUI::animateCaret() {
+	if (!_displayEnabled) return;
+
+	if (_system->getMillis() % kCaretBlinkTime < kCaretBlinkTime / 2) {
+		if (!_drawCaret) {
+			_drawCaret = true;			
+			_dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispForeColor);
+			extendDirtyRect(Rect(_dispX + _caretX, _dispY, _dispX + _caretX + 1, _dispY + _dispSurface.h));
+		}
+	} else {
+		if (_drawCaret) {
+			_drawCaret = false;
+			_dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispBackColor);
+			extendDirtyRect(Rect(_dispX + _caretX, _dispY, _dispX + _caretX + 1, _dispY + _dispSurface.h));
+		}
+	}
+}
+
+void VirtualKeyboardGUI::updateDisplay() {
+	if (!_displayEnabled) return;
+
+	// calculate the text to display
+	uint cursorPos = _kbd->_keyQueue.getInsertIndex();
+	String wholeText = _kbd->_keyQueue.getString();
+	uint dispTextEnd;
+	if (_dispI > cursorPos)
+		_dispI = cursorPos;
+	
+	dispTextEnd = calculateEndIndex(wholeText, _dispI);
+	while (cursorPos > dispTextEnd)
+		dispTextEnd = calculateEndIndex(wholeText, ++_dispI);
+	
+	String dispText = String(wholeText.c_str() + _dispI, wholeText.c_str() + dispTextEnd);
+
+	// draw to display surface
+	_dispSurface.fillRect(Rect(_dispSurface.w, _dispSurface.h), _dispBackColor);
+	_dispFont->drawString(&_dispSurface, dispText, 0, 0, _dispSurface.w, _dispForeColor);
+	
+	String beforeCaret(wholeText.c_str() + _dispI, wholeText.c_str() + cursorPos);
+	_caretX = _dispFont->getStringWidth(beforeCaret);
+	if (_drawCaret) _dispSurface.drawLine(_caretX, 0, _caretX, _dispSurface.h, _dispForeColor);
+
+	extendDirtyRect(Rect(_dispX, _dispY, _dispX + _dispSurface.w, _dispY + _dispSurface.h));
+}
+
+void VirtualKeyboardGUI::setupCursor() {
+	const byte palette[] = {
+		255, 255, 255, 0,
+		255, 255, 255, 0,
+		171, 171, 171, 0,
+		87,  87,  87, 0
+	};
+
+	CursorMan.pushCursorPalette(palette, 0, 4);
+	CursorMan.pushCursor(NULL, 0, 0, 0, 0);
+	CursorMan.showMouse(true);
+}
+
+void VirtualKeyboardGUI::animateCursor() {
+	int time = _system->getMillis();
+	if (time > _cursorAnimateTimer + kCursorAnimateDelay) {
+		for (int i = 0; i < 15; i++) {
+			if ((i < 6) || (i > 8)) {
+				_cursor[16 * 7 + i] = _cursorAnimateCounter;
+				_cursor[16 * i + 7] = _cursorAnimateCounter;
+			}
+		}
+
+		CursorMan.replaceCursor(_cursor, 16, 16, 7, 7);
+
+		_cursorAnimateTimer = time;
+		_cursorAnimateCounter = (_cursorAnimateCounter + 1) % 4;
+	}
+}
+
+void VirtualKeyboardGUI::removeCursor() {
+	CursorMan.popCursor();
+	CursorMan.popCursorPalette();
+}
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_VKEYBD


Property changes on: scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.h
===================================================================
--- scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.h	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.h	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,159 @@
+/* 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_VIRTUAL_KEYBOARD_GUI_H
+#define COMMON_VIRTUAL_KEYBOARD_GUI_H
+
+#include "common/scummsys.h"
+
+#ifdef ENABLE_VKEYBD
+
+#include "backends/vkeybd/virtual-keyboard.h"
+#include "common/rect.h"
+#include "common/system.h"
+#include "graphics/fontman.h"
+#include "graphics/surface-keycolored.h"
+
+namespace Common {
+
+/**
+ * Class to handle the drawing of the virtual keyboard to the overlay, and the
+ * execution of the keyboard's main loop.
+ * This includes the blitting of the appropriate bitmap in the correct location,
+ * as well as the drawing of the virtual keyboard display.
+ */
+class VirtualKeyboardGUI {
+
+public:
+
+	VirtualKeyboardGUI(VirtualKeyboard *kbd);
+	~VirtualKeyboardGUI();
+
+	/**
+	 * Updates the GUI when the Mode of the keyboard is changes
+	 */
+	void initMode(VirtualKeyboard::Mode *mode);
+
+	/**
+	 * Starts the drawing of the keyboard, and runs the main event loop.
+	 */
+	void run();
+
+	/**
+	 * Interrupts the event loop and resets the overlay to its initial state.
+	 */	 
+	void close();
+	
+	bool isDisplaying() { return _displaying; }
+
+	/**
+	 * Reset the class to an initial state
+	 */
+	void reset();
+
+	/**
+	 * Activates drag mode. Takes the keyboard-relative coordinates of the 
+	 * cursor as an argument.
+	 */
+	void startDrag(int16 x, int16 y);
+
+	/**
+	 * Deactivates drag mode
+	 * */
+	void endDrag();
+	
+	/**
+	 * Checks for a screen change in the backend and re-inits the virtual 
+	 * keyboard if it has.
+	 */
+	void checkScreenChanged();
+	
+	/**
+	 * Sets the GUI's internal screen size variables
+	 */ 
+	void initSize(int16 w, int16 h);
+
+private:
+
+	OSystem *_system;
+
+	VirtualKeyboard *_kbd;
+	Rect _kbdBound;
+	Graphics::Surface *_kbdSurface;
+	OverlayColor _kbdTransparentColor;
+
+	Point _dragPoint;
+	bool _drag;
+	static const int SNAP_WIDTH = 10;
+
+	Graphics::Surface _overlayBackup;
+	Rect _dirtyRect;
+
+	bool _displayEnabled;
+	Graphics::Surface _dispSurface;
+	const Graphics::Font *_dispFont;
+	int16 _dispX, _dispY;
+	uint _dispI;
+	OverlayColor _dispForeColor, _dispBackColor;
+
+	int _lastScreenChanged;
+	int16 _screenW, _screenH;
+
+	bool _displaying;
+	bool _firstRun;
+
+	void setupDisplayArea(Rect& r, OverlayColor forecolor);
+	void move(int16 x, int16 y);
+	void moveToDefaultPosition();
+	void screenChanged();
+	void mainLoop();
+	void extendDirtyRect(const Rect &r);
+	void resetDirtyRect();
+	void redraw();
+	void forceRedraw();
+	void updateDisplay();
+	bool fontIsSuitable(const Graphics::Font *font, const Rect& rect);
+	uint calculateEndIndex(const String& str, uint startIndex);
+
+	bool _drawCaret;
+	int16 _caretX;
+	static const int kCaretBlinkTime = 500;
+	void animateCaret();
+
+	static const int kCursorAnimateDelay = 250;
+	int _cursorAnimateCounter;
+	int	_cursorAnimateTimer;
+	byte _cursor[2048];
+	void setupCursor();
+	void removeCursor();
+	void animateCursor();
+
+};
+
+} // end of namespace Common
+
+#endif // #ifdef ENABLE_VKEYBD
+
+#endif // #ifndef COMMON_VIRTUAL_KEYBOARD_GUI_H


Property changes on: scummvm/trunk/backends/vkeybd/virtual-keyboard-gui.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:keywords
   + Date Rev Author URL Id
Added: svn:eol-style
   + native

Added: scummvm/trunk/backends/vkeybd/virtual-keyboard-parser.cpp
===================================================================
--- scummvm/trunk/backends/vkeybd/virtual-keyboard-parser.cpp	                        (rev 0)
+++ scummvm/trunk/backends/vkeybd/virtual-keyboard-parser.cpp	2009-01-11 00:20:27 UTC (rev 35813)
@@ -0,0 +1,367 @@
+/* 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$
+ *
+ */
+
+#include "backends/vkeybd/virtual-keyboard-parser.h"
+
+#ifdef ENABLE_VKEYBD
+
+#include "common/keyboard.h"
+#include "graphics/imageman.h"
+#include "common/util.h"
+
+namespace Common {
+
+VirtualKeyboardParser::VirtualKeyboardParser(VirtualKeyboard *kbd) 
+	: XMLParser(), _keyboard(kbd) {
+}
+
+void VirtualKeyboardParser::cleanup() {
+	_mode = 0;
+	_kbdParsed = false;
+	_initialModeName.clear();
+	if (_parseMode == kParseFull) {
+		// reset keyboard to remove existing config
+		_keyboard->reset();
+	}
+}
+
+bool VirtualKeyboardParser::closedKeyCallback(ParserNode *node) {
+	if (node->name.equalsIgnoreCase("keyboard")) {
+		_kbdParsed = true;
+		if (!_keyboard->_initialMode)
+			return parserError("Initial mode of keyboard pack not defined");
+	} else if (node->name.equalsIgnoreCase("mode")) {
+		if (!_layoutParsed) {
+			return parserError("'%s' layout missing from '%s' mode", 
+				_mode->resolution.c_str(), _mode->name.c_str());
+		}
+	}
+	return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_keyboard(ParserNode *node) {
+
+	if (_kbdParsed)
+		return parserError("Only a single keyboard element is allowed");
+
+	// if not full parse then we're done
+	if (_parseMode == kParseCheckResolutions)
+		return true;
+
+	_initialModeName = node->values["initial_mode"];
+
+	if (node->values.contains("h_align")) {
+		String h = node->values["h_align"];
+		if (h.equalsIgnoreCase("left"))
+			_keyboard->_hAlignment = VirtualKeyboard::kAlignLeft;
+		else if (h.equalsIgnoreCase("centre") || h.equalsIgnoreCase("center"))
+			_keyboard->_hAlignment = VirtualKeyboard::kAlignCentre;
+		else if (h.equalsIgnoreCase("right"))
+			_keyboard->_hAlignment = VirtualKeyboard::kAlignRight;
+	}
+
+	if (node->values.contains("v_align")) {
+		String v = node->values["h_align"];
+		if (v.equalsIgnoreCase("top"))
+			_keyboard->_vAlignment = VirtualKeyboard::kAlignTop;
+		else if (v.equalsIgnoreCase("middle") || v.equalsIgnoreCase("center"))
+			_keyboard->_vAlignment = VirtualKeyboard::kAlignMiddle;
+		else if (v.equalsIgnoreCase("bottom"))
+			_keyboard->_vAlignment = VirtualKeyboard::kAlignBottom;
+	}
+
+	return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_mode(ParserNode *node) {
+
+	String name = node->values["name"];
+
+	if (_parseMode == kParseFull) {
+		// if full parse then add new mode to keyboard
+		if (_keyboard->_modes.contains(name))
+			return parserError("Mode '%s' has already been defined", name.c_str());
+
+		VirtualKeyboard::Mode mode;
+		mode.name = name;
+		_keyboard->_modes[name] = mode;
+	}
+
+	_mode = &(_keyboard->_modes[name]);
+	if (name == _initialModeName)
+		_keyboard->_initialMode = _mode;
+
+	String resolutions = node->values["resolutions"];
+	StringTokenizer tok (resolutions, " ,");
+
+	// select best resolution simply by minimising the difference between the 
+	// overlay size and the resolution dimensions.
+	// TODO: improve this by giving preference to a resolution that is smaller
+	// than the overlay res (so the keyboard can't be too big for the screen)
+	uint16 scrW = g_system->getOverlayWidth(), scrH = g_system->getOverlayHeight();
+	uint32 diff = 0xFFFFFFFF;
+	String newResolution;
+	for (String res = tok.nextToken(); res.size() > 0; res = tok.nextToken()) {
+		int resW, resH;
+		if (sscanf(res.c_str(), "%dx%d", &resW, &resH) != 2) {
+			return parserError("Invalid resolution specification");
+		} else {
+			if (resW == scrW && resH == scrH) {
+				newResolution = res;
+				break;
+			} else {
+				uint32 newDiff = ABS(scrW - resW) + ABS(scrH - resH);
+				if (newDiff < diff) {
+					diff = newDiff;
+					newResolution = res;
+				}
+			}
+		}
+	}
+
+	if (newResolution.empty())
+		return parserError("No acceptable resolution was found");
+
+	if (_parseMode == kParseCheckResolutions) {
+		if (_mode->resolution == newResolution) {
+			node->ignore = true;
+			return true;
+		} else {
+			// remove data relating to old resolution
+			ImageMan.unregisterSurface(_mode->bitmapName);
+			_mode->bitmapName.clear();
+			_mode->image = 0;
+			_mode->imageMap.removeAllAreas();
+			delete _mode->displayArea;
+			_mode->displayArea = 0;
+		}
+	}
+
+	_mode->resolution = newResolution;
+	_layoutParsed = false;
+
+	return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_event(ParserNode *node) {
+	
+	// if just checking resolutions we're done
+	if (_parseMode == kParseCheckResolutions)
+		return true;
+
+	String name = node->values["name"];
+	if (_mode->events.contains(name))
+		return parserError("Event '%s' has already been defined", name.c_str());
+
+	VirtualKeyboard::VKEvent *evt = new VirtualKeyboard::VKEvent();
+	evt->name = name;
+
+	String type = node->values["type"];
+	if (type.equalsIgnoreCase("key")) {
+		if (!node->values.contains("code") || !node->values.contains("ascii")) {
+			delete evt;
+			return parserError("Key event element must contain code and ascii attributes");
+		}
+		evt->type = VirtualKeyboard::kVKEventKey;
+
+		KeyState *ks = (KeyState*) malloc(sizeof(KeyState));
+		ks->keycode = (KeyCode)atoi(node->values["code"].c_str());
+		ks->ascii = atoi(node->values["ascii"].c_str());
+		ks->flags = 0;
+		if (node->values.contains("modifiers"))
+			ks->flags = parseFlags(node->values["modifiers"]);
+		evt->data = ks;
+
+	} else if (type.equalsIgnoreCase("modifier")) {
+		if (!node->values.contains("modifiers")) {
+			delete evt;
+			return parserError("Key modifier element must contain modifier attributes");
+		}
+		
+		evt->type = VirtualKeyboard::kVKEventModifier;
+		byte *flags = (byte*) malloc(sizeof(byte));
+		*(flags) = parseFlags(node->values["modifiers"]);
+		evt->data = flags;
+
+	} else if (type.equalsIgnoreCase("switch_mode")) {
+		if (!node->values.contains("mode")) {
+			delete evt;
+			return parserError("Switch mode event element must contain mode attribute");
+		}
+
+		evt->type = VirtualKeyboard::kVKEventSwitchMode;
+		String& mode = node->values["mode"];
+		char *str = (char*) malloc(sizeof(char) * mode.size() + 1);
+		memcpy(str, mode.c_str(), sizeof(char) * mode.size());
+		str[mode.size()] = 0;
+		evt->data = str;
+	} else if (type.equalsIgnoreCase("submit")) {
+		evt->type = VirtualKeyboard::kVKEventSubmit;
+	} else if (type.equalsIgnoreCase("cancel")) {
+		evt->type = VirtualKeyboard::kVKEventCancel;
+	} else if (type.equalsIgnoreCase("clear")) {
+		evt->type = VirtualKeyboard::kVKEventClear;
+	} else if (type.equalsIgnoreCase("delete")) {
+		evt->type = VirtualKeyboard::kVKEventDelete;
+	} else if (type.equalsIgnoreCase("move_left")) {
+		evt->type = VirtualKeyboard::kVKEventMoveLeft;
+	} else if (type.equalsIgnoreCase("move_right")) {
+		evt->type = VirtualKeyboard::kVKEventMoveRight;
+	} else {
+		delete evt;
+		return parserError("Event type '%s' not known", type.c_str());
+	}
+
+	_mode->events[name] = evt;
+
+	return true;
+}
+
+bool VirtualKeyboardParser::parserCallback_layout(ParserNode *node) {
+
+	assert(!_mode->resolution.empty());
+
+	String res = node->values["resolution"];
+
+	if (res != _mode->resolution) {
+		node->ignore = true;
+		return true;
+	}
+
+	_mode->bitmapName = node->values["bitmap"];
+	_mode->image = ImageMan.getSurface(_mode->bitmapName);
+	if (!_mode->image) {
+		if (!ImageMan.registerSurface(_mode->bitmapName, 0))
+			return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
+
+		_mode->image = ImageMan.getSurface(_mode->bitmapName);
+		if (!_mode->image)
+			return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());
+	}
+	
+	if (node->values.contains("transparent_color")) {
+		int r, g, b;
+		if (!parseIntegerKey(node->values["transparent_color"].c_str(), 3, &r, &g, &b))
+			return parserError("Could not parse color value");
+		_mode->transparentColor = g_system->RGBToColor(r, g, b);
+	} else // default to purple
+		_mode->transparentColor = g_system->RGBToColor(255, 0, 255); 
+
+	if (node->values.contains("display_font_color")) {
+		int r, g, b;
+		if (!parseIntegerKey(node->values["display_font_color"].c_str(), 3, &r, &g, &b))
+			return parserError("Could not parse color value");
+		_mode->displayFontColor = g_system->RGBToColor(r, g, b);
+	} else
+		_mode->displayFontColor = g_system->RGBToColor(0, 0, 0); // default to black
+
+	_layoutParsed = true;
+
+	return true;
+}
+

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list