ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

keymap.cpp

Go to the documentation of this file.
00001 /* ScummVM - Graphic Adventure Engine
00002  *
00003  * ScummVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the COPYRIGHT
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "backends/keymapper/keymap.h"
00024 
00025 #ifdef ENABLE_KEYMAPPER
00026 
00027 #include "common/system.h"
00028 
00029 #include "backends/keymapper/hardware-input.h"
00030 #include "backends/keymapper/keymapper-defaults.h"
00031 
00032 #define KEYMAP_KEY_PREFIX "keymap_"
00033 
00034 namespace Common {
00035 
00036 Keymap::Keymap(const Keymap& km) : _actions(km._actions), _keymap(), _nonkeymap(), _configDomain(0) {
00037     List<Action *>::iterator it;
00038 
00039     for (it = _actions.begin(); it != _actions.end(); ++it) {
00040         const HardwareInput *hwInput = (*it)->getMappedInput();
00041 
00042         if (hwInput) {
00043             if (hwInput->type == kHardwareInputTypeKeyboard)
00044                 _keymap[hwInput->key] = *it;
00045             else if (hwInput->type == kHardwareInputTypeGeneric)
00046                 _nonkeymap[hwInput->inputCode] = *it;
00047         }
00048     }
00049 }
00050 
00051 Keymap::~Keymap() {
00052     List<Action *>::iterator it;
00053 
00054     for (it = _actions.begin(); it != _actions.end(); ++it)
00055         delete *it;
00056 }
00057 
00058 void Keymap::addAction(Action *action) {
00059     if (findAction(action->id))
00060         error("Action with id %s already in KeyMap", action->id);
00061 
00062     _actions.push_back(action);
00063 }
00064 
00065 void Keymap::registerMapping(Action *action, const HardwareInput *hwInput) {
00066     if (hwInput->type == kHardwareInputTypeKeyboard) {
00067         HashMap<KeyState, Action *>::iterator it = _keymap.find(hwInput->key);
00068         // if input is already mapped to a different action then unmap it from there
00069         if (it != _keymap.end() && action != it->_value)
00070             it->_value->mapInput(0);
00071         // now map it
00072         _keymap[hwInput->key] = action;
00073     } else if (hwInput->type == kHardwareInputTypeGeneric) {
00074         HashMap<HardwareInputCode, Action *>::iterator it = _nonkeymap.find(hwInput->inputCode);
00075         // if input is already mapped to a different action then unmap it from there
00076         if (it != _nonkeymap.end() && action != it->_value)
00077             it->_value->mapInput(0);
00078         // now map it
00079         _nonkeymap[hwInput->inputCode] = action;
00080     }
00081 }
00082 
00083 void Keymap::unregisterMapping(Action *action) {
00084     const HardwareInput *hwInput = action->getMappedInput();
00085 
00086     if (hwInput) {
00087         if (hwInput->type == kHardwareInputTypeKeyboard)
00088             _keymap.erase(hwInput->key);
00089         else if (hwInput->type == kHardwareInputTypeGeneric)
00090             _nonkeymap.erase(hwInput->inputCode);
00091     }
00092 }
00093 
00094 Action *Keymap::getAction(const char *id) {
00095     return findAction(id);
00096 }
00097 
00098 Action *Keymap::findAction(const char *id) {
00099     List<Action *>::iterator it;
00100 
00101     for (it = _actions.begin(); it != _actions.end(); ++it) {
00102         if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
00103             return *it;
00104     }
00105     return 0;
00106 }
00107 
00108 const Action *Keymap::findAction(const char *id) const {
00109     List<Action *>::const_iterator it;
00110 
00111     for (it = _actions.begin(); it != _actions.end(); ++it) {
00112         if (strncmp((*it)->id, id, ACTION_ID_SIZE) == 0)
00113             return *it;
00114     }
00115 
00116     return 0;
00117 }
00118 
00119 Action *Keymap::getMappedAction(const KeyState& ks) const {
00120     HashMap<KeyState, Action *>::iterator it;
00121 
00122     it = _keymap.find(ks);
00123 
00124     if (it == _keymap.end())
00125         return 0;
00126     else
00127         return it->_value;
00128 }
00129 
00130 Action *Keymap::getMappedAction(const HardwareInputCode code) const {
00131     HashMap<HardwareInputCode, Action *>::iterator it;
00132 
00133     it = _nonkeymap.find(code);
00134 
00135     if (it == _nonkeymap.end())
00136         return 0;
00137     else
00138         return it->_value;
00139 }
00140 
00141 void Keymap::setConfigDomain(ConfigManager::Domain *dom) {
00142     _configDomain = dom;
00143 }
00144 
00145 void Keymap::loadMappings(const HardwareInputSet *hwKeys) {
00146     if (!_configDomain)
00147         return;
00148 
00149     if (_actions.empty())
00150         return;
00151 
00152     Common::KeymapperDefaultBindings *defaults = g_system->getKeymapperDefaultBindings();
00153 
00154     HashMap<String, const HardwareInput *> mappedInputs;
00155     List<Action*>::iterator it;
00156     String prefix = KEYMAP_KEY_PREFIX + _name + "_";
00157 
00158     for (it = _actions.begin(); it != _actions.end(); ++it) {
00159         Action* ua = *it;
00160         String actionId(ua->id);
00161         String confKey = prefix + actionId;
00162 
00163         String hwInputId = _configDomain->getVal(confKey);
00164 
00165         bool defaulted = false;
00166         // fall back to the platform-specific defaults
00167         if (hwInputId.empty() && defaults) {
00168             hwInputId = defaults->getDefaultBinding(_name, actionId);
00169             if (!hwInputId.empty())
00170                 defaulted = true;
00171         }
00172         // there's no mapping
00173         if (hwInputId.empty())
00174             continue;
00175 
00176         const HardwareInput *hwInput = hwKeys->findHardwareInput(hwInputId.c_str());
00177 
00178         if (!hwInput) {
00179             warning("HardwareInput with ID '%s' not known", hwInputId.c_str());
00180             continue;
00181         }
00182 
00183         if (defaulted) {
00184             if (mappedInputs.contains(hwInputId)) {
00185                 debug(1, "Action [%s] not falling back to hardcoded default value [%s] because the hardware input is in use", confKey.c_str(), hwInputId.c_str());
00186                 continue;
00187             }
00188             warning("Action [%s] fell back to hardcoded default value [%s]", confKey.c_str(), hwInputId.c_str());
00189         }
00190 
00191         mappedInputs.setVal(hwInputId, hwInput);
00192         // map the key
00193         ua->mapInput(hwInput);
00194     }
00195 }
00196 
00197 void Keymap::saveMappings() {
00198     if (!_configDomain)
00199         return;
00200 
00201     List<Action *>::const_iterator it;
00202     String prefix = KEYMAP_KEY_PREFIX + _name + "_";
00203 
00204     for (it = _actions.begin(); it != _actions.end(); ++it) {
00205         uint actIdLen = strlen((*it)->id);
00206 
00207         actIdLen = (actIdLen > ACTION_ID_SIZE) ? ACTION_ID_SIZE : actIdLen;
00208 
00209         String actId((*it)->id, (*it)->id + actIdLen);
00210         String hwId = "";
00211 
00212         if ((*it)->getMappedInput()) {
00213             hwId = (*it)->getMappedInput()->id;
00214         }
00215         _configDomain->setVal(prefix + actId, hwId);
00216     }
00217 }
00218 
00219 bool Keymap::isComplete(const HardwareInputSet *hwInputs) {
00220     List<Action *>::iterator it;
00221     bool allMapped = true;
00222     uint numberMapped = 0;
00223 
00224     for (it = _actions.begin(); it != _actions.end(); ++it) {
00225         if ((*it)->getMappedInput()) {
00226             ++numberMapped;
00227         } else {
00228             allMapped = false;
00229         }
00230     }
00231 
00232     return allMapped || (numberMapped == hwInputs->size());
00233 }
00234 
00235 } // End of namespace Common
00236 
00237 #endif // #ifdef ENABLE_KEYMAPPER


Generated on Sat Mar 23 2019 05:01:45 for ResidualVM by doxygen 1.7.1
curved edge   curved edge