Fix binding to multi-button keygroup
[lsnes.git] / keymapper.hpp
blobcb7149942ed7b9ec33834e8e9a7d7ffa2c431150
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.
27 class modifier
29 public:
30 /**
31 * Create modifier.
33 modifier(const std::string& name) throw(std::bad_alloc);
34 /**
35 * Create linked modifier.
37 modifier(const std::string& name, const std::string& linkgroup) throw(std::bad_alloc);
38 /**
39 * Look up a modifier.
41 static modifier& lookup(const std::string& name) throw(std::bad_alloc, std::runtime_error);
42 /**
43 * Get name of modifier.
45 std::string name() const throw(std::bad_alloc);
46 private:
48 modifier(const modifier&);
49 modifier& operator=(const modifier&);
50 std::string modname;
53 /**
54 * Set of modifiers.
56 class modifier_set
58 public:
59 /**
60 * Add a modifier.
62 void add(const modifier& mod, bool really = true) throw(std::bad_alloc);
63 /**
64 * Remove a modifier.
66 void remove(const modifier& mod, bool really = true) throw(std::bad_alloc);
67 /**
68 * Construct set from string.
70 static modifier_set construct(const std::string& modifiers) throw(std::bad_alloc, std::runtime_error);
71 /**
72 * Check modifier against its mask for validity.
74 static bool valid(const modifier_set& set, const modifier_set& mask) throw(std::bad_alloc);
75 /**
76 * Check if this modifier set triggers the action.
78 static bool triggers(const modifier_set& set, const modifier_set& trigger, const modifier_set& mask)
79 throw(std::bad_alloc);
80 /**
81 * Equality.
83 bool operator==(const modifier_set& m) const throw();
85 private:
86 std::set<const modifier*> set;
89 /**
90 * Key or key group.
92 class keygroup
94 public:
95 /**
96 * Key group type.
98 enum type
101 * Disabled.
103 KT_DISABLED,
105 * Singular button.
107 KT_KEY,
109 * Pressure-sensitive button
111 KT_PRESSURE_PM,
112 KT_PRESSURE_MP,
113 KT_PRESSURE_0P,
114 KT_PRESSURE_0M,
115 KT_PRESSURE_P0,
116 KT_PRESSURE_M0,
118 * Axis key pair.
120 KT_AXIS_PAIR,
121 KT_AXIS_PAIR_INVERSE,
123 * Hat.
125 KT_HAT
128 * Create new key group.
130 keygroup(const std::string& name, enum type t) throw(std::bad_alloc);
132 * Change type of key group.
134 void change_type(enum type t);
136 * Change calibration (Axis pairs and pressure buttons only).
138 void change_calibration(short left, short center, short right, double tolerance);
140 * Change state of this key group.
142 * For KT_KEY, value is zero/nonzero.
143 * For KT_PRESSURE_* and KT_AXIS_PAIR*, value is -32768...32767.
144 * For KT_HAT, 1 is up, 2 is right, 4 is down, 8 is left (may be ORed).
146 void set_position(short pos, const modifier_set& modifiers) throw();
148 * Look up key by name.
150 static std::pair<keygroup*, unsigned> lookup(const std::string& name) throw(std::bad_alloc,
151 std::runtime_error);
153 * Look up key name.
155 std::string name() throw(std::bad_alloc);
157 * Keyboard key listener.
159 struct key_listener
162 * Invoked on key.
164 virtual void key_event(const modifier_set& modifiers, keygroup& keygroup, unsigned subkey,
165 bool polarity, const std::string& name) = 0;
168 * Add key listener.
170 void add_key_listener(key_listener& l) throw(std::bad_alloc);
172 * Remove key listener.
174 void remove_key_listener(key_listener& l) throw(std::bad_alloc);
176 * Excelusive key listener.
178 static void set_exclusive_key_listener(key_listener* l) throw();
179 private:
180 unsigned state;
181 enum type ktype;
182 short cal_left;
183 short cal_center;
184 short cal_right;
185 double cal_tolerance;
186 double compensate(short value);
187 double compensate2(double value);
188 void run_listeners(const modifier_set& modifiers, unsigned subkey, bool polarity, bool really, double x);
189 std::list<key_listener*> listeners;
190 std::string keyname;
191 static key_listener* exclusive;
195 * This class handles internals of mapping events from keyboard buttons and pseudo-buttons.
198 class keymapper
200 public:
202 * Binds a key, erroring out if binding would conflict with existing one.
204 * parameter mod: Modifier set to require to be pressed.
205 * parameter modmask: Modifier set to take into account.
206 * parameter keyname: Key to bind the action to.
207 * parameter command: The command to bind.
208 * throws std::bad_alloc: Not enough memory.
209 * throws std::runtime_error: The binding would conflict with existing one or invalid modifier/key.
211 static void bind(std::string mod, std::string modmask, std::string keyname, std::string command)
212 throw(std::bad_alloc, std::runtime_error);
214 * Unbinds a key, erroring out if binding does not exist..
216 * parameter mod: Modifier set to require to be pressed.
217 * parameter modmask: Modifier set to take into account.
218 * parameter keyname: Key to bind the action to.
219 * throws std::bad_alloc: Not enough memory.
220 * throws std::runtime_error: The binding does not exist.
222 static void unbind(std::string mod, std::string modmask, std::string keyname) throw(std::bad_alloc,
223 std::runtime_error);
226 * Dump list of bindigns as message to console.
228 * throws std::bad_alloc: Not enough memory.
230 static void dumpbindings() throw(std::bad_alloc);
233 #endif