More backports of stuff from the wxwidgets branch
[lsnes.git] / generic / keymapper.hpp
blobc7e29fbe641e5d16bfdc51532fcc0c308fd36115
1 #ifndef _keymapper__hpp__included__
2 #define _keymapper__hpp__included__
4 #include <string>
5 #include <sstream>
6 #include <stdexcept>
7 #include <list>
8 #include <set>
9 #include <iostream>
10 #include "misc.hpp"
12 /**
13 * Takes in a raw command and returns the command that should be actually executed given the key polarity.
15 * parameter cmd: Raw command.
16 * parameter polarity: Polarity (True => Being pressed, False => Being released).
17 * returns: The fixed command, "" if no command should be executed.
18 * throws std::bad_alloc: Not enough memory.
20 std::string fixup_command_polarity(std::string cmd, bool polarity) throw(std::bad_alloc);
24 /**
25 * Modifier key.
27 * Each object of this class is a modifier key (e.g. left control) or group of modifier keys (e.g. control).
29 class modifier
31 public:
32 /**
33 * Create a new modifier.
35 * parameter name: Name of the modifier.
36 * throws std::bad_alloc: Not enough memory.
38 modifier(const std::string& name) throw(std::bad_alloc);
39 /**
40 * Create a new linked modifier.
42 * If modifiers A and B are both linked to C, then:
43 * - It is legal to specify A and/or B as modifier when modifier mask contains C.
44 * - If modifier contains C, then both A and B activate it.
46 * The usual use for linked modifiers is when there are two closely related keys (e.g. left ctrl and right ctrl)
47 * one wants to be able to be referred with single name.
49 * parameter name: Name of the modifier.
50 * parameter linkgroup: The name of modifier this modifier is linked to (this modifier should be created).
51 * throws std::bad_alloc: Not enough memory.
53 modifier(const std::string& name, const std::string& linkgroup) throw(std::bad_alloc);
54 /**
55 * Destructor
57 ~modifier() throw();
58 /**
59 * Look up a modifier.
61 * parameter name: The name of the modifier to look up.
62 * returns: The looked up modifier.
63 * throws std::bad_alloc: Not enough memory.
64 * throws std::runtime_error: No such modifier is known.
66 static modifier& lookup(const std::string& name) throw(std::bad_alloc, std::runtime_error);
67 /**
68 * Get name of modifier.
70 * returns: The name of this modifier.
71 * throws: std::bad_alloc: Not enough memory.
73 std::string name() const throw(std::bad_alloc);
74 private:
75 modifier(const modifier&);
76 modifier& operator=(const modifier&);
77 std::string modname;
80 /**
81 * A set of modifier keys.
83 class modifier_set
85 public:
86 /**
87 * Add a modifier into the set.
89 * parameter mod: The modifier to add.
90 * parameter really: If true, actually add the key. If false, do nothing.
91 * throws std::bad_alloc: Not enough memory.
93 void add(const modifier& mod, bool really = true) throw(std::bad_alloc);
94 /**
95 * Remove a modifier from the set.
97 * parameter mod: The modifier to remove.
98 * parameter really: If true, actually remove the key. If false, do nothing.
99 * throws std::bad_alloc: Not enough memory.
101 void remove(const modifier& mod, bool really = true) throw(std::bad_alloc);
103 * Construct modifier set from comma-separated string.
105 * parameter modifiers: The modifiers as string
106 * returns: The constructed modifier set.
107 * throws std::bad_alloc: Not enough memory.
108 * throws std::runtime_error: Illegal modifier or wrong syntax.
110 static modifier_set construct(const std::string& modifiers) throw(std::bad_alloc, std::runtime_error);
112 * Check modifier against its mask for validity.
114 * This method checks that:
115 * - for each modifier in set, either that or its linkage group is in mask.
116 * - Both modifier and its linkage group isn't in either set or mask.
118 * parameter set: The set to check.
119 * parameter mask: The mask to check against.
120 * returns: True if set is valid, false if not.
121 * throws std::bad_alloc: Not enough memory.
123 static bool valid(const modifier_set& set, const modifier_set& mask) throw(std::bad_alloc);
125 * Check if this modifier set triggers the action.
127 * Modifier set triggers another if for each modifier or linkage group in mask:
128 * - Modifier appears in both set and trigger.
129 * - At least one modifier with this linkage group appears in both set and trigger.
130 * - Modifiers with this linkage group do not appear in either set nor trigger.
133 static bool triggers(const modifier_set& set, const modifier_set& trigger, const modifier_set& mask)
134 throw(std::bad_alloc);
136 * Equality check.
138 * parameter m: Another set.
139 * returns: True if two sets are equal, false if not.
141 bool operator==(const modifier_set& m) const throw();
143 private:
144 friend std::ostream& operator<<(std::ostream& os, const modifier_set& m);
145 std::set<const modifier*> set;
149 * Debugging print. Prints textual version of set into stream.
151 * parameter os: The stream to print to.
152 * parameter m: The modifier set to print.
153 * returns: reference to os.
155 std::ostream& operator<<(std::ostream& os, const modifier_set& m);
158 * Key or key group.
160 * Each object of this type is either one key or group of keys.
162 class keygroup
164 public:
166 * Key group type.
168 enum type
171 * Disabled.
173 KT_DISABLED,
175 * Singular button.
177 KT_KEY,
179 * Pressure-sensitive button
181 KT_PRESSURE_PM,
182 KT_PRESSURE_MP,
183 KT_PRESSURE_0P,
184 KT_PRESSURE_0M,
185 KT_PRESSURE_P0,
186 KT_PRESSURE_M0,
188 * Axis key pair.
190 KT_AXIS_PAIR,
191 KT_AXIS_PAIR_INVERSE,
193 * Hat.
195 KT_HAT
198 * Create a new key group.
200 * parameter name: Name of the key group.
201 * parameter t: Initial type of the key group.
202 * throws std::bad_alloc: Not enough memory.
204 keygroup(const std::string& name, enum type t) throw(std::bad_alloc);
206 * Destructor
208 ~keygroup() throw();
210 * Change type of key group.
212 * parameter t: New type for the key group.
214 void change_type(enum type t) throw();
216 * Change calibration (Axis pairs and pressure buttons only).
218 * parameter left: The control value at extreme negative position.
219 * parameter center: The control value at center position.
220 * parameter right: The control value at extreme positive position.
221 * parameter tolerance: How wide is the neutral zone (must be larger than 0 and smaller than 1).
223 void change_calibration(short left, short center, short right, double tolerance);
225 * Change state of this key group.
227 * For KT_KEY, value is zero/nonzero.
228 * For KT_PRESSURE_* and KT_AXIS_PAIR*, value is -32768...32767.
229 * For KT_HAT, 1 is up, 2 is right, 4 is down, 8 is left (may be ORed).
231 * parameter pos: New position.
232 * parameter modifiers: The modifier set that was pressed during the change.
234 void set_position(short pos, const modifier_set& modifiers) throw();
236 * Look up individual key by name.
238 * parameter name: The name of the key to look up.
239 * returns: First element is pointer to key group, second is key index within the group.
240 * throws std::bad_alloc: Not enough memory.
241 * throws std::runtime_error: No such key known.
243 static std::pair<keygroup*, unsigned> lookup(const std::string& name) throw(std::bad_alloc,
244 std::runtime_error);
246 * Look up key group name.
248 * returns: The name of the key group.
249 * throws std::bad_alloc: Not enough memory.
251 std::string name() throw(std::bad_alloc);
253 * Keyboard key listener.
255 struct key_listener
258 * Invoked on key.
260 * parameter modifiers: The modifiers pressed during the transition.
261 * parameter keygroup: The key group key is in.
262 * parameter subkey: Key index within the key group (identifies individual key).
263 * parameter polarity: True if key is going down, false if going up.
264 * parameter name: The name of the individual key.
266 virtual void key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
267 bool polarity, const std::string& name) = 0;
270 * Add key listener.
272 * parameter l: The new key listener.
273 * throw std::bad_alloc: Not enough memory.
275 void add_key_listener(key_listener& l) throw(std::bad_alloc);
277 * Remove key listener.
279 * parameter l: The key listener to remove.
280 * throw std::bad_alloc: Not enough memory.
282 void remove_key_listener(key_listener& l) throw(std::bad_alloc);
284 * Set exclusive key listener.
286 * When exclusive key listener is active, all keys are sent to it and not to normal key listeners.
288 * parameter l: The new exclusive key listener or NULL if exclusive key listener is to be removed.
290 static void set_exclusive_key_listener(key_listener* l) throw();
293 * Key group parameters.
295 struct parameters
298 * Type
300 enum type ktype;
302 * Calibration left.
304 short cal_left;
306 * Calibration center.
308 short cal_center;
310 * Calibration right.
312 short cal_right;
314 * Calibration tolerance.
316 double cal_tolerance;
319 * Get parameters.
321 struct parameters get_parameters();
322 private:
323 unsigned state;
324 enum type ktype;
325 short cal_left;
326 short cal_center;
327 short cal_right;
328 double cal_tolerance;
329 double compensate(short value);
330 double compensate2(double value);
331 void run_listeners(const modifier_set& modifiers, unsigned subkey, bool polarity, bool really, double x);
332 std::list<key_listener*> listeners;
333 std::string keyname;
334 static key_listener* exclusive;
338 * This class handles internals of mapping events from keyboard buttons and pseudo-buttons.
340 class keymapper
342 public:
344 * Binds a key, erroring out if binding would conflict with existing one.
346 * parameter mod: Modifier set to require to be pressed.
347 * parameter modmask: Modifier set to take into account.
348 * parameter keyname: Key to bind the action to.
349 * parameter command: The command to bind.
350 * throws std::bad_alloc: Not enough memory.
351 * throws std::runtime_error: The binding would conflict with existing one or invalid modifier/key.
353 static void bind(std::string mod, std::string modmask, std::string keyname, std::string command)
354 throw(std::bad_alloc, std::runtime_error);
356 * Unbinds a key, erroring out if binding does not exist..
358 * parameter mod: Modifier set to require to be pressed.
359 * parameter modmask: Modifier set to take into account.
360 * parameter keyname: Key to bind the action to.
361 * throws std::bad_alloc: Not enough memory.
362 * throws std::runtime_error: The binding does not exist.
364 static void unbind(std::string mod, std::string modmask, std::string keyname) throw(std::bad_alloc,
365 std::runtime_error);
368 * Dump list of bindigns as message to console.
370 * throws std::bad_alloc: Not enough memory.
372 static void dumpbindings() throw(std::bad_alloc);
375 #endif