Save bitmaps as PNG
[lsnes.git] / include / library / keymapper.hpp
blobb8df5c6c460cb09580bb0ed3000782b0dea8214e
1 #ifndef _library__keymapper__hpp__included__
2 #define _library__keymapper__hpp__included__
4 #include "commands.hpp"
5 #include <set>
6 #include <list>
7 #include <stdexcept>
8 #include <string>
9 #include "keyboard.hpp"
11 class inverse_bind;
12 class controller_key;
14 std::pair<keyboard_key*, unsigned> keymapper_lookup_subkey(keyboard& kbd, const std::string& name, bool axis)
15 throw(std::bad_alloc, std::runtime_error);
17 /**
18 * Key specifier
20 struct key_specifier
22 /**
23 * Create a new key specifier (invalid).
25 key_specifier() throw(std::bad_alloc);
26 /**
27 * Create a new key specifier from keyspec.
29 * Parameter keyspec: The key specifier.
31 key_specifier(const std::string& keyspec) throw(std::bad_alloc, std::runtime_error);
32 /**
33 * Get the key specifier as a keyspec.
35 operator std::string() throw(std::bad_alloc);
36 /**
37 * Is valid?
39 operator bool() throw();
40 /**
41 * Is not valid?
43 bool operator!() throw();
44 /**
45 * Clear the keyspec.
47 void clear() throw();
48 /**
49 * Compare for equality.
51 bool operator==(const key_specifier& keyspec);
52 /**
53 * Compare for not-equality.
55 bool operator!=(const key_specifier& keyspec);
56 /**
57 * The modifier.
59 std::string mod;
60 /**
61 * The mask.
63 std::string mask;
64 /**
65 * The key itself.
67 std::string key;
71 /**
72 * Keyboard mapper. Maps keyboard keys into commands.
74 class keyboard_mapper : public keyboard_event_listener
76 public:
77 /**
78 * Create new keyboard mapper.
80 keyboard_mapper(keyboard& kbd, command_group& domain) throw(std::bad_alloc);
81 /**
82 * Destroy a keyboard mapper.
84 ~keyboard_mapper() throw();
85 /**
86 * Binds a key, erroring out if binding would conflict with existing one.
88 * parameter mod: Modifier set to require to be pressed.
89 * parameter modmask: Modifier set to take into account.
90 * parameter keyname: Key to bind the action to.
91 * parameter command: The command to bind.
92 * throws std::bad_alloc: Not enough memory.
93 * throws std::runtime_error: The binding would conflict with existing one or invalid modifier/key.
95 void bind(std::string mod, std::string modmask, std::string keyname, std::string command)
96 throw(std::bad_alloc, std::runtime_error);
97 /**
98 * Unbinds a key, erroring out if binding does not exist.
100 * parameter mod: Modifier set to require to be pressed.
101 * parameter modmask: Modifier set to take into account.
102 * parameter keyname: Key to bind the action to.
103 * throws std::bad_alloc: Not enough memory.
104 * throws std::runtime_error: The binding does not exist.
106 void unbind(std::string mod, std::string modmask, std::string keyname) throw(std::bad_alloc,
107 std::runtime_error);
109 * Get keys bound.
111 * Returns: The set of keyspecs that are bound.
113 std::list<key_specifier> get_bindings() throw(std::bad_alloc);
115 * Get command for key.
117 std::string get(const key_specifier& keyspec) throw(std::bad_alloc);
119 * Bind command for key.
121 * Parameter keyspec: The key specifier to bind to.
122 * Parameter cmd: The command to bind. If "", the key is unbound.
124 void set(const key_specifier& keyspec, const std::string& cmd) throw(std::bad_alloc, std::runtime_error);
126 * Get set of inverse binds.
128 * Returns: The set of all inverses.
130 std::set<inverse_bind*> get_inverses() throw(std::bad_alloc);
132 * Find inverse bind by command.
134 * Parameter command: The command.
135 * Returns: The inverse bind, or NULL if none.
137 inverse_bind* get_inverse(const std::string& command) throw(std::bad_alloc);
139 * Get set of controller keys.
141 * Returns: The set of all controller keys.
143 std::set<controller_key*> get_controller_keys() throw(std::bad_alloc);
145 * Get specific controller key.
147 controller_key* get_controllerkey(const std::string& command) throw(std::bad_alloc);
149 * Get list of controller keys for specific keyboard key.
151 std::list<controller_key*> get_controllerkeys_kbdkey(keyboard_key* kbdkey) throw(std::bad_alloc);
153 * Proxy for inverse bind registrations.
155 struct _inverse_proxy
157 _inverse_proxy(keyboard_mapper& mapper) : _mapper(mapper) {}
158 void do_register(const std::string& name, inverse_bind& ibind)
160 _mapper.do_register_inverse(name, ibind);
162 void do_unregister(const std::string& name)
164 _mapper.do_unregister_inverse(name);
166 private:
167 keyboard_mapper& _mapper;
168 } inverse_proxy;
170 * Proxy for controller key registrations.
172 struct _controllerkey_proxy
174 _controllerkey_proxy(keyboard_mapper& mapper) : _mapper(mapper) {}
175 void do_register(const std::string& name, controller_key& ckey)
177 _mapper.do_register_ckey(name, ckey);
179 void do_unregister(const std::string& name)
181 _mapper.do_unregister_ckey(name);
183 private:
184 keyboard_mapper& _mapper;
185 } controllerkey_proxy;
187 * Register inverse bind.
189 void do_register_inverse(const std::string& name, inverse_bind& bind) throw(std::bad_alloc);
191 * Unregister inverse bind.
193 void do_unregister_inverse(const std::string& name) throw(std::bad_alloc);
195 * Register controller key.
197 void do_register_ckey(const std::string& name, controller_key& ckey) throw(std::bad_alloc);
199 * Unregister inverse bind.
201 void do_unregister_ckey(const std::string& name) throw(std::bad_alloc);
203 * Get keyboard.
205 keyboard& get_keyboard() throw();
207 * Get command group to run commands in..
209 command_group& get_command_group() throw();
211 * Fixup command based on polarity.
213 * Parameter cmd: The raw command.
214 * Parameter polarity: Polarity (true is rising edge, false is falling edge).
215 * Returns: The fixed command, or "" if nothing should be run.
217 static std::string fixup_command_polarity(std::string cmd, bool polarity) throw(std::bad_alloc);
218 private:
219 struct triplet
221 triplet(keyboard_modifier_set mod, keyboard_modifier_set mask, keyboard_key& key, unsigned subkey);
222 triplet(keyboard_key& key, unsigned subkey);
223 triplet(keyboard& k, const key_specifier& spec);
224 bool operator<(const struct triplet& a) const;
225 bool operator==(const struct triplet& a) const;
226 bool operator<=(const struct triplet& a) const { return !(a > *this); }
227 bool operator!=(const struct triplet& a) const { return !(a == *this); }
228 bool operator>=(const struct triplet& a) const { return !(a < *this); }
229 bool operator>(const struct triplet& a) const { return (a < *this); }
230 key_specifier as_keyspec() const throw(std::bad_alloc);
231 bool index;
232 keyboard_modifier_set mod;
233 keyboard_modifier_set mask;
234 keyboard_key* key;
235 unsigned subkey;
237 void change_command(const key_specifier& spec, const std::string& old, const std::string& newc);
238 void on_key_event(keyboard_modifier_set& mods, keyboard_key& key, keyboard_event& event);
239 void on_key_event_subkey(keyboard_modifier_set& mods, keyboard_key& key, unsigned skey, bool polarity);
240 keyboard_mapper(const keyboard_mapper&);
241 keyboard_mapper& operator=(const keyboard_mapper&);
242 std::map<std::string, inverse_bind*> ibinds;
243 std::map<std::string, controller_key*> ckeys;
244 std::map<triplet, std::string> bindings;
245 std::set<keyboard_key*> listening;
246 keyboard& kbd;
247 command_group& domain;
248 mutex_class mutex;
252 * Inverse bind. Can map up to 2 keys to some command (and follows forward binds).
254 class inverse_bind
256 public:
258 * Create inverse bind.
260 * Parameter mapper: The keyboard mapper to follow.
261 * Parameter command: Command this is for.
262 * Parameter name: Name of inverse key.
264 inverse_bind(keyboard_mapper& mapper, const std::string& command, const std::string& name)
265 throw(std::bad_alloc);
267 * Destructor.
269 ~inverse_bind() throw();
271 * Get keyspec.
273 * Parameter index: Index of the keyspec to get.
274 * Returns: The keyspec.
276 key_specifier get(unsigned index) throw(std::bad_alloc);
278 * Clear key (subsequent keys fill the gap).
280 * Parameter index: Index of key to clear.
282 void clear(unsigned index) throw(std::bad_alloc);
284 * Add key to set.
286 * Parameter keyspec: The new keyspec.
288 void append(const key_specifier& keyspec) throw(std::bad_alloc);
290 * Get name for command.
292 * Returns: The name.
294 std::string getname() throw(std::bad_alloc);
295 private:
296 friend class keyboard_mapper;
297 inverse_bind(const inverse_bind&);
298 inverse_bind& operator=(const inverse_bind&);
299 void addkey(const key_specifier& keyspec);
300 keyboard_mapper& mapper;
301 std::string cmd;
302 std::string oname;
303 std::vector<key_specifier> specs;
304 mutex_class mutex;
308 * A controller key.
310 * Can overlap with any other bind.
312 class controller_key : public keyboard_event_listener
314 public:
316 * Create a new controller key.
318 * Parameter mapper: The keyboard mapper to follow.
319 * Parameter command: Command to run.
320 * Parameter name: Name of controller key.
321 * Parameter axis: If true, create a axis-type key.
323 controller_key(keyboard_mapper& mapper, const std::string& command, const std::string& name,
324 bool axis = false) throw(std::bad_alloc);
326 * Destructor.
328 ~controller_key() throw();
330 * Get the trigger key.
332 std::pair<keyboard_key*, unsigned> get(unsigned index) throw();
334 * Get the trigger key.
336 std::string get_string(unsigned index) throw(std::bad_alloc);
338 * Set the trigger key (appends).
340 void append(keyboard_key* key, unsigned subkey) throw();
342 * Set the trigger key (appends).
344 void append(const std::string& key) throw(std::bad_alloc, std::runtime_error);
346 * Remove the trigger key.
348 void remove(keyboard_key* key, unsigned subkey) throw();
350 * Get the command.
352 const std::string& get_command() const throw() { return cmd; }
354 * Get the name.
356 const std::string& get_name() const throw() { return oname; }
358 * Is axis-type?
360 bool is_axis() const throw() { return axis; }
361 private:
362 void on_key_event(keyboard_modifier_set& mods, keyboard_key& key, keyboard_event& event);
363 keyboard_mapper& mapper;
364 std::string cmd;
365 std::string oname;
366 std::vector<std::pair<keyboard_key*, unsigned>> keys;
367 bool axis;
368 mutex_class mutex;
371 #endif