aboutsummaryrefslogtreecommitdiff
path: root/backends/keymapper/keymapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'backends/keymapper/keymapper.cpp')
-rw-r--r--backends/keymapper/keymapper.cpp225
1 files changed, 225 insertions, 0 deletions
diff --git a/backends/keymapper/keymapper.cpp b/backends/keymapper/keymapper.cpp
new file mode 100644
index 0000000000..c64732a618
--- /dev/null
+++ b/backends/keymapper/keymapper.cpp
@@ -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