1 /* ScummVM - Graphic Adventure Engine
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26 #include "backends/keymapper/keymapper.h"
28 #ifdef ENABLE_KEYMAPPER
30 #include "common/config-manager.h"
34 void Keymapper::Domain::addKeymap(Keymap
*map
) {
35 iterator it
= find(map
->getName());
40 setVal(map
->getName(), map
);
43 void Keymapper::Domain::deleteAllKeyMaps() {
44 for (iterator it
= begin(); it
!= end(); it
++)
50 Keymap
*Keymapper::Domain::getKeymap(const String
& name
) {
51 iterator it
= find(name
);
59 Keymapper::Keymapper(EventManager
*evtMgr
)
60 : _eventMan(evtMgr
), _enabled(true), _hardwareKeys(0) {
61 ConfigManager::Domain
*confDom
= ConfMan
.getDomain(ConfigManager::kKeymapperDomain
);
63 _globalDomain
.setConfigDomain(confDom
);
66 Keymapper::~Keymapper() {
70 void Keymapper::registerHardwareKeySet(HardwareKeySet
*keys
) {
72 error("Hardware key set already registered");
75 warning("No hardware keys are supplied");
82 void Keymapper::addGlobalKeymap(Keymap
*keymap
) {
83 initKeymap(_globalDomain
, keymap
);
86 void Keymapper::addGameKeymap(Keymap
*keymap
) {
87 if (ConfMan
.getActiveDomain() == 0)
88 error("Call to Keymapper::addGameKeymap when no game loaded");
90 // Detect whether the active game changed since last call.
91 // If so, flush the game key configuration.
92 if (_gameDomain
.getConfigDomain() != ConfMan
.getActiveDomain()) {
94 _gameDomain
.setConfigDomain(ConfMan
.getActiveDomain());
97 initKeymap(_gameDomain
, keymap
);
100 void Keymapper::initKeymap(Domain
&domain
, Keymap
*map
) {
101 if (!_hardwareKeys
) {
102 warning("No hardware keys were registered yet (%s)", map
->getName().c_str());
106 map
->setConfigDomain(domain
.getConfigDomain());
107 map
->loadMappings(_hardwareKeys
);
109 if (map
->isComplete(_hardwareKeys
) == false) {
110 map
->automaticMapping(_hardwareKeys
);
112 ConfMan
.flushToDisk();
115 domain
.addKeymap(map
);
118 void Keymapper::cleanupGameKeymaps() {
119 // Flush all game specific keymaps
120 _gameDomain
.deleteAllKeyMaps();
122 // Now restore the stack of active maps. Re-add all global keymaps, drop
123 // the game specific (=deleted) ones.
124 Stack
<MapRecord
> newStack
;
126 for (int i
= 0; i
< _activeMaps
.size(); i
++) {
127 if (_activeMaps
[i
].global
)
128 newStack
.push(_activeMaps
[i
]);
131 _activeMaps
= newStack
;
134 Keymap
*Keymapper::getKeymap(const String
& name
, bool &global
) {
135 Keymap
*keymap
= _gameDomain
.getKeymap(name
);
139 keymap
= _globalDomain
.getKeymap(name
);
146 bool Keymapper::pushKeymap(const String
& name
, bool inherit
) {
148 Keymap
*newMap
= getKeymap(name
, global
);
151 warning("Keymap '%s' not registered", name
.c_str());
155 pushKeymap(newMap
, inherit
, global
);
160 void Keymapper::pushKeymap(Keymap
*newMap
, bool inherit
, bool global
) {
161 MapRecord mr
= {newMap
, inherit
, global
};
163 _activeMaps
.push(mr
);
166 void Keymapper::popKeymap() {
167 if (!_activeMaps
.empty())
171 bool Keymapper::notifyEvent(const Common::Event
&ev
) {
172 if (ev
.type
== Common::EVENT_KEYDOWN
)
173 return mapKeyDown(ev
.kbd
);
174 else if (ev
.type
== Common::EVENT_KEYUP
)
175 return mapKeyUp(ev
.kbd
);
180 bool Keymapper::mapKeyDown(const KeyState
& key
) {
181 return mapKey(key
, true);
184 bool Keymapper::mapKeyUp(const KeyState
& key
) {
185 return mapKey(key
, false);
188 bool Keymapper::mapKey(const KeyState
& key
, bool keyDown
) {
189 if (!_enabled
|| _activeMaps
.empty())
195 // Search for key in active keymap stack
196 for (int i
= _activeMaps
.size() - 1; i
>= 0; --i
) {
197 MapRecord mr
= _activeMaps
[i
];
199 action
= mr
.keymap
->getMappedAction(key
);
201 if (action
|| mr
.inherit
== false)
206 _keysDown
[key
] = action
;
208 HashMap
<KeyState
, Action
*>::iterator it
= _keysDown
.find(key
);
210 if (it
!= _keysDown
.end()) {
212 _keysDown
.erase(key
);
219 executeAction(action
, keyDown
);
224 Action
*Keymapper::getAction(const KeyState
& key
) {
230 void Keymapper::executeAction(const Action
*action
, bool keyDown
) {
231 List
<Event
>::const_iterator it
;
233 for (it
= action
->events
.begin(); it
!= action
->events
.end(); ++it
) {
238 if (!keyDown
) evt
.type
= EVENT_KEYUP
;
241 if (keyDown
) evt
.type
= EVENT_KEYDOWN
;
243 case EVENT_LBUTTONDOWN
:
244 if (!keyDown
) evt
.type
= EVENT_LBUTTONUP
;
246 case EVENT_LBUTTONUP
:
247 if (keyDown
) evt
.type
= EVENT_LBUTTONDOWN
;
249 case EVENT_RBUTTONDOWN
:
250 if (!keyDown
) evt
.type
= EVENT_RBUTTONUP
;
252 case EVENT_RBUTTONUP
:
253 if (keyDown
) evt
.type
= EVENT_RBUTTONDOWN
;
255 case EVENT_MBUTTONDOWN
:
256 if (!keyDown
) evt
.type
= EVENT_MBUTTONUP
;
258 case EVENT_MBUTTONUP
:
259 if (keyDown
) evt
.type
= EVENT_MBUTTONDOWN
;
262 // don't deliver other events on key up
263 if (!keyDown
) continue;
266 evt
.mouse
= _eventMan
->getMousePos();
271 const HardwareKey
*Keymapper::findHardwareKey(const KeyState
& key
) {
272 return (_hardwareKeys
) ? _hardwareKeys
->findHardwareKey(key
) : 0;
275 } // end of namespace Common
277 #endif // #ifdef ENABLE_KEYMAPPER