Lua: input.keyhook
[lsnes.git] / include / core / keymapper.hpp
blobd5e19f3e762153d0f10c33ca60fae7a9424f898e
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 <map>
10 #include <iostream>
11 #include "misc.hpp"
13 /**
14 * Takes in a raw command and returns the command that should be actually executed given the key polarity.
16 * parameter cmd: Raw command.
17 * parameter polarity: Polarity (True => Being pressed, False => Being released).
18 * returns: The fixed command, "" if no command should be executed.
19 * throws std::bad_alloc: Not enough memory.
21 std::string fixup_command_polarity(std::string cmd, bool polarity) throw(std::bad_alloc);
25 /**
26 * Modifier key.
28 * Each object of this class is a modifier key (e.g. left control) or group of modifier keys (e.g. control).
30 class modifier
32 public:
33 /**
34 * Create a new modifier.
36 * parameter name: Name of the modifier.
37 * throws std::bad_alloc: Not enough memory.
39 modifier(const std::string& name) throw(std::bad_alloc);
40 /**
41 * Create a new linked modifier.
43 * If modifiers A and B are both linked to C, then:
44 * - It is legal to specify A and/or B as modifier when modifier mask contains C.
45 * - If modifier contains C, then both A and B activate it.
47 * The usual use for linked modifiers is when there are two closely related keys (e.g. left ctrl and right ctrl)
48 * one wants to be able to be referred with single name.
50 * parameter name: Name of the modifier.
51 * parameter linkgroup: The name of modifier this modifier is linked to (this modifier should be created).
52 * throws std::bad_alloc: Not enough memory.
54 modifier(const std::string& name, const std::string& linkgroup) throw(std::bad_alloc);
55 /**
56 * Destructor
58 ~modifier() throw();
59 /**
60 * Look up a modifier.
62 * parameter name: The name of the modifier to look up.
63 * returns: The looked up modifier.
64 * throws std::bad_alloc: Not enough memory.
65 * throws std::runtime_error: No such modifier is known.
67 static modifier& lookup(const std::string& name) throw(std::bad_alloc, std::runtime_error);
68 /**
69 * Get name of modifier.
71 * returns: The name of this modifier.
72 * throws: std::bad_alloc: Not enough memory.
74 std::string name() const throw(std::bad_alloc);
75 /**
76 * Get name of linked modifier.
78 * returns: The name of linked modifier, "" if none.
79 * throws: std::bad_alloc: Not enough memory.
81 std::string linked_name() const throw(std::bad_alloc);
82 /**
83 * Get set of all modifiers.
85 static std::set<std::string> get_set() throw(std::bad_alloc);
86 private:
87 modifier(const modifier&);
88 modifier& operator=(const modifier&);
89 std::string modname;
92 /**
93 * A set of modifier keys.
95 class modifier_set
97 public:
98 /**
99 * Add a modifier into the set.
101 * parameter mod: The modifier to add.
102 * parameter really: If true, actually add the key. If false, do nothing.
103 * throws std::bad_alloc: Not enough memory.
105 void add(const modifier& mod, bool really = true) throw(std::bad_alloc);
107 * Remove a modifier from the set.
109 * parameter mod: The modifier to remove.
110 * parameter really: If true, actually remove the key. If false, do nothing.
111 * throws std::bad_alloc: Not enough memory.
113 void remove(const modifier& mod, bool really = true) throw(std::bad_alloc);
115 * Construct modifier set from comma-separated string.
117 * parameter modifiers: The modifiers as string
118 * returns: The constructed modifier set.
119 * throws std::bad_alloc: Not enough memory.
120 * throws std::runtime_error: Illegal modifier or wrong syntax.
122 static modifier_set construct(const std::string& modifiers) throw(std::bad_alloc, std::runtime_error);
124 * Check modifier against its mask for validity.
126 * This method checks that:
127 * - for each modifier in set, either that or its linkage group is in mask.
128 * - Both modifier and its linkage group isn't in either set or mask.
130 * parameter set: The set to check.
131 * parameter mask: The mask to check against.
132 * returns: True if set is valid, false if not.
133 * throws std::bad_alloc: Not enough memory.
135 static bool valid(const modifier_set& set, const modifier_set& mask) throw(std::bad_alloc);
137 * Check if this modifier set triggers the action.
139 * Modifier set triggers another if for each modifier or linkage group in mask:
140 * - Modifier appears in both set and trigger.
141 * - At least one modifier with this linkage group appears in both set and trigger.
142 * - Modifiers with this linkage group do not appear in either set nor trigger.
145 static bool triggers(const modifier_set& set, const modifier_set& trigger, const modifier_set& mask)
146 throw(std::bad_alloc);
148 * Equality check.
150 * parameter m: Another set.
151 * returns: True if two sets are equal, false if not.
153 bool operator==(const modifier_set& m) const throw();
155 private:
156 friend std::ostream& operator<<(std::ostream& os, const modifier_set& m);
157 std::set<const modifier*> set;
161 * Debugging print. Prints textual version of set into stream.
163 * parameter os: The stream to print to.
164 * parameter m: The modifier set to print.
165 * returns: reference to os.
167 std::ostream& operator<<(std::ostream& os, const modifier_set& m);
170 * Key or key group.
172 * Each object of this type is either one key or group of keys.
174 class keygroup
176 public:
178 * Key group type.
180 enum type
183 * Disabled.
185 KT_DISABLED,
187 * Singular button.
189 KT_KEY,
191 * Pressure-sensitive button
193 KT_PRESSURE_PM,
194 KT_PRESSURE_MP,
195 KT_PRESSURE_0P,
196 KT_PRESSURE_0M,
197 KT_PRESSURE_P0,
198 KT_PRESSURE_M0,
200 * Axis key pair.
202 KT_AXIS_PAIR,
203 KT_AXIS_PAIR_INVERSE,
205 * Hat.
207 KT_HAT,
209 * Mouse axis (this is not a real axis!).
211 KT_MOUSE
214 * Create a new key group.
216 * parameter name: Name of the key group.
217 * parameter t: Initial type of the key group.
218 * throws std::bad_alloc: Not enough memory.
220 keygroup(const std::string& name, enum type t) throw(std::bad_alloc);
222 * Destructor
224 ~keygroup() throw();
226 * Lookup key group by name.
228 * Parameter name: The key group name.
229 * Returns: The looked up key group, or NULL if not found.
231 static keygroup* lookup_by_name(const std::string& name) throw();
233 * Get the set of axes.
235 * Returns: The axis set (all axes).
236 * Throws std::bad_alloc: Not enough memory.
238 static std::set<std::string> get_axis_set() throw(std::bad_alloc);
240 * Change type of key group.
242 * parameter t: New type for the key group.
244 void change_type(enum type t) throw();
246 * Change calibration (Axis pairs and pressure buttons only).
248 * parameter left: The control value at extreme negative position.
249 * parameter center: The control value at center position.
250 * parameter right: The control value at extreme positive position.
251 * parameter tolerance: How wide is the neutral zone (must be larger than 0 and smaller than 1).
253 void change_calibration(short left, short center, short right, double tolerance);
255 * Change state of this key group.
257 * For KT_KEY, value is zero/nonzero.
258 * For KT_PRESSURE_* and KT_AXIS_PAIR*, value is -32768...32767.
259 * For KT_HAT, 1 is up, 2 is right, 4 is down, 8 is left (may be ORed).
260 * For KT_MOUSE, value is -32768...32767.
262 * parameter pos: New position.
263 * parameter modifiers: The modifier set that was pressed during the change.
265 void set_position(short pos, const modifier_set& modifiers) throw();
267 * Look up individual key by name.
269 * parameter name: The name of the key to look up.
270 * returns: First element is pointer to key group, second is key index within the group.
271 * throws std::bad_alloc: Not enough memory.
272 * throws std::runtime_error: No such key known.
274 static std::pair<keygroup*, unsigned> lookup(const std::string& name) throw(std::bad_alloc,
275 std::runtime_error);
277 * Look up key group name.
279 * returns: The name of the key group.
280 * throws std::bad_alloc: Not enough memory.
282 std::string name() throw(std::bad_alloc);
284 * Get set of all keys (including subkeys).
286 static std::set<std::string> get_keys() throw(std::bad_alloc);
289 * Key group parameters.
291 struct parameters
294 * Type
296 enum type ktype;
298 * Last known raw value.
300 short last_rawval;
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();
323 * Get all key parameters.
325 static std::map<std::string, struct parameters> get_all_parameters();
327 * Set callback requests on/off
329 void request_hook_callback(bool state);
330 private:
331 unsigned state;
332 enum type ktype;
333 short last_rawval;
334 short cal_left;
335 short cal_center;
336 short cal_right;
337 double cal_tolerance;
338 double compensate(short value);
339 double compensate2(double value);
340 void run_listeners(const modifier_set& modifiers, unsigned subkey, bool polarity, bool really, double x);
341 std::string keyname;
342 bool requests_hook;
346 * This class handles internals of mapping events from keyboard buttons and pseudo-buttons.
348 class keymapper
350 public:
352 * Binds a key, erroring out if binding would conflict with existing one.
354 * parameter mod: Modifier set to require to be pressed.
355 * parameter modmask: Modifier set to take into account.
356 * parameter keyname: Key to bind the action to.
357 * parameter command: The command to bind.
358 * throws std::bad_alloc: Not enough memory.
359 * throws std::runtime_error: The binding would conflict with existing one or invalid modifier/key.
361 static void bind(std::string mod, std::string modmask, std::string keyname, std::string command)
362 throw(std::bad_alloc, std::runtime_error);
364 * Unbinds a key, erroring out if binding does not exist..
366 * parameter mod: Modifier set to require to be pressed.
367 * parameter modmask: Modifier set to take into account.
368 * parameter keyname: Key to bind the action to.
369 * throws std::bad_alloc: Not enough memory.
370 * throws std::runtime_error: The binding does not exist.
372 static void unbind(std::string mod, std::string modmask, std::string keyname) throw(std::bad_alloc,
373 std::runtime_error);
375 * Dump list of bindigns as message to console.
377 * throws std::bad_alloc: Not enough memory.
379 static void dumpbindings() throw(std::bad_alloc);
381 * Get keys bound.
383 static std::set<std::string> get_bindings() throw(std::bad_alloc);
385 * Get command for key.
387 static std::string get_command_for(const std::string& keyspec) throw(std::bad_alloc);
389 * Bind command for key.
391 static void bind_for(const std::string& keyspec, const std::string& cmd) throw(std::bad_alloc,
392 std::runtime_error);
395 #endif