Fix some compilation errors on Mac OS X
[lsnes.git] / include / library / keyboard.hpp
blob0beff5c4179bfc62bb1a3d225e529c12c92a56a8
1 #ifndef _library__keyboard__hpp__included__
2 #define _library__keyboard__hpp__included__
4 #include <map>
5 #include <set>
6 #include <string>
7 #include <vector>
8 #include <list>
9 #include <stdexcept>
11 namespace keyboard
13 class modifier;
14 class key;
15 class key_axis;
16 class key_mouse;
17 class event_listener;
19 /**
20 * A group of modifiers and keys.
22 * Instances of this class allow registering, unregistering and looking up modifiers and keys.
24 class keyboard
26 public:
27 /**
28 * Create a new instance.
30 keyboard() throw(std::bad_alloc);
31 /**
32 * Destroy an instance.
34 * The keys and modifiers in instance are not freed.
36 ~keyboard() throw();
37 /**
38 * Lookup modifier by name.
40 * Parameter name: The name of the modifier.
41 * Returns: The modifier.
42 * Throws std::runtime_error: No such modifier.
44 modifier& lookup_modifier(const std::string& name) throw(std::runtime_error);
45 /**
46 * Try lookup modifier by name.
48 * Parameter name: The name of the modifier.
49 * Returns: The modifier, or NULL if not found.
51 modifier* try_lookup_modifier(const std::string& name) throw();
52 /**
53 * Look up all modifiers.
55 * Returns: The set of modifiers.
57 std::list<modifier*> all_modifiers() throw(std::bad_alloc);
58 /**
59 * Register a modifier.
61 * Parameter name: The name of the modifier.
62 * Parameter mod: The modifier.
64 void do_register(const std::string& name, modifier& mod) throw(std::bad_alloc);
65 /**
66 * Unregister a modifier.
68 * Parameter name: The name of the modifier.
70 void do_unregister(const std::string& name, modifier& mod) throw();
71 /**
72 * Lookup key by name.
74 * Parameter name: The name of the key.
75 * Returns: The key.
76 * Throws std::runtime_error: No such key.
78 key& lookup_key(const std::string& name) throw(std::runtime_error);
79 /**
80 * Try lookup key by name.
82 * Parameter name: The name of the key.
83 * Returns: The key, or NULL if not found.
85 key* try_lookup_key(const std::string& name) throw();
86 /**
87 * Look up all keys.
89 * Returns: The set of keys.
91 std::list<key*> all_keys() throw(std::bad_alloc);
92 /**
93 * Register a key.
95 * Parameter name: The name of the key.
96 * Parameter mod: The key.
98 void do_register(const std::string& name, key& mod) throw(std::bad_alloc);
99 /**
100 * Unregister a key.
102 * Parameter name: The name of the key.
104 void do_unregister(const std::string& name, key& mod) throw();
106 * Set exclusive listener for all keys at once.
108 void set_exclusive(event_listener* listener) throw();
110 * Set current key.
112 void set_current_key(key* key) throw();
114 * Get current key.
116 key* get_current_key() throw();
117 private:
118 keyboard(const keyboard&);
119 keyboard& operator=(const keyboard&);
120 key* current_key;
124 * A modifier or group of modifiers.
126 class modifier
128 public:
130 * Create a (group of) modifiers.
132 * Parameter keyb: The keyboard these will be on.
133 * Parameter _name: The name of the modifier.
135 modifier(keyboard& keyb, const std::string& _name) throw(std::bad_alloc)
136 : kbd(keyb), name(_name)
138 keyb.do_register(name, *this);
141 * Create a linked modifier in group.
143 * Parameter keyb: The keyboard these will be on.
144 * Parameter _name: The name of the modifier.
145 * Parameter _link: The name of the modifier group this is in.
147 modifier(keyboard& keyb, const std::string& _name, const std::string& _link) throw(std::bad_alloc)
148 : kbd(keyb), name(_name), link(_link)
150 keyb.do_register(name, *this);
153 * Destructor.
155 ~modifier() throw()
157 kbd.do_unregister(name, *this);
160 * Get associated keyboard.
162 keyboard& get_keyboard() const throw() { return kbd; }
164 * Get name of the modifier.
166 const std::string& get_name() const throw() { return name; }
168 * Get linked name of the modifier.
170 * Returns: The linked name, or "" if none.
172 const std::string& get_link_name() const throw() { return link; }
174 * Get the linked modifier.
176 * Returns: The linked modifier, or NULL if none (or not initialized yet).
178 modifier* get_link() { return kbd.try_lookup_modifier(link); }
179 private:
180 keyboard& kbd;
181 std::string name;
182 std::string link;
186 * A set of modifier keys.
188 class modifier_set
190 public:
192 * Add a modifier into the set.
194 * parameter mod: The modifier to add.
195 * parameter really: If true, actually add the key. If false, do nothing.
196 * throws std::bad_alloc: Not enough memory.
198 void add(modifier& mod, bool really = true) throw(std::bad_alloc);
200 * Remove a modifier from the set.
202 * parameter mod: The modifier to remove.
203 * parameter really: If true, actually remove the key. If false, do nothing.
204 * throws std::bad_alloc: Not enough memory.
206 void remove(modifier& mod, bool really = true) throw(std::bad_alloc);
208 * Construct modifier set from comma-separated string.
210 * parameter kbd: The keyboard to take the modifiers from.
211 * parameter modifiers: The modifiers as string
212 * returns: The constructed modifier set.
213 * throws std::bad_alloc: Not enough memory.
214 * throws std::runtime_error: Illegal modifier or wrong syntax.
216 static modifier_set construct(keyboard& kbd, const std::string& modifiers) throw(std::bad_alloc,
217 std::runtime_error);
219 * Check modifier against its mask for validity.
221 * This method checks that:
222 * - for each modifier in set, either that or its linkage group is in mask.
223 * - Both modifier and its linkage group isn't in either set or mask.
225 * parameter mask: The mask to check against.
226 * returns: True if set is valid, false if not.
227 * throws std::bad_alloc: Not enough memory.
229 bool valid(modifier_set& mask) throw(std::bad_alloc);
231 * Check if this modifier set triggers the action.
233 * Modifier set triggers another if for each modifier or linkage group in mask:
234 * - Modifier appears in both set and trigger.
235 * - At least one modifier with this linkage group appears in both set and trigger.
236 * - Modifiers with this linkage group do not appear in either set nor trigger.
239 bool triggers(const modifier_set& trigger, const modifier_set& mask) throw(std::bad_alloc);
241 * Stringify.
243 operator std::string() const throw(std::bad_alloc);
245 * Equality check.
247 * parameter m: Another set.
248 * returns: True if two sets are equal, false if not.
250 bool operator==(const modifier_set& m) const throw();
252 * Less than check.
254 bool operator<(const modifier_set& m) const throw();
255 private:
256 friend std::ostream& operator<<(std::ostream& os, const modifier_set& m);
257 std::set<modifier*> set;
261 * Debugging print. Prints textual version of set into stream.
263 * parameter os: The stream to print to.
264 * parameter m: The modifier set to print.
265 * returns: reference to os.
267 std::ostream& operator<<(std::ostream& os, const modifier_set& m);
270 * Type of key.
272 enum keytype
275 * A simple key (pressed/released)
277 KBD_KEYTYPE_KEY,
279 * A joystick axis (pair of opposite directions or pressure-sensitive button).
281 KBD_KEYTYPE_AXIS,
283 * A joystick hat (directional control or a dpad).
285 KBD_KEYTYPE_HAT,
287 * A mouse axis.
289 KBD_KEYTYPE_MOUSE
293 * Joystick axis calibration structure.
295 struct axis_calibration
298 * Mode: -1 => Disabled, 0 => Pressure-sentive button, 1 => Axis.
300 int mode;
304 * Mouse axis calibration structure.
306 struct mouse_calibration
309 * The offset from left of screen area to left of game area.
311 int32_t offset;
313 * Translate from screen coordinate to game coordinate.
315 int32_t get_calibrated_value(int32_t x) const throw();
319 * Superclass of key event data.
321 class event
323 public:
325 * Create a new event.
327 * Parameter _chngmask: The change mask.
328 * Parameter _type: Type of the event.
330 event(uint32_t _chngmask, keytype _type) throw()
332 chngmask = _chngmask;
333 type = _type;
336 * Destructor.
338 virtual ~event() throw();
340 * Get analog state. The format is dependent on key type.
342 virtual int32_t get_state() const throw() = 0;
344 * Get key change mask.
346 * Returns: A bitmask. Bit 2*n is the state of subkey n. Bit 2*n+1 is set if subkey changed state, else clear.
348 uint32_t get_change_mask() const throw() { return chngmask; }
350 * Get type of event.
352 keytype get_type() const throw() { return type; }
353 private:
354 uint32_t chngmask;
355 keytype type;
359 * A simple key event.
361 class event_key : public event
363 public:
365 * Construct a new key event.
367 * Parameter chngmask: The change mask.
369 event_key(uint32_t chngmask);
371 * Destructor.
373 ~event_key() throw();
375 * Get analog state.
377 * Returns: 1 if pressed, 0 if released.
379 int32_t get_state() const throw();
380 private:
381 int32_t state;
385 * An axis event.
387 class event_axis : public event
389 public:
391 * Construct a new axis event.
393 * Parameter state: The analog state.
394 * Parameter chngmask: The change mask.
395 * Parameter cal: The calibration structure.
397 event_axis(int32_t state, uint32_t chngmask);
399 * Destructor.
401 ~event_axis() throw();
403 * Get analog state.
405 * Returns: Analog position of axis, -32768...32767 (0...32767 for pressure-sensitive buttons).
407 int32_t get_state() const throw();
408 private:
409 int32_t state;
410 axis_calibration cal;
414 * A hat event.
416 class event_hat : public event
418 public:
420 * Construct a new hat event.
422 * Parameter chngmask: The change mask to use.
424 event_hat(uint32_t chngmask);
426 * Destructor.
428 ~event_hat() throw();
430 * Get analog state.
432 * Returns: Bitmask: 1 => Up, 2 => Right, 4 => Down, 8 => Left.
434 int32_t get_state() const throw();
438 * A mouse event.
440 class event_mouse : public event
442 public:
444 * Construct a new mouse event.
446 * Parameter state: The game-relative position to use.
447 * Parameter cal: The calibration structure.
449 event_mouse(int32_t state, const mouse_calibration& cal);
451 * Destructor.
453 ~event_mouse() throw();
455 * Get analog state.
457 * Returns: Position of mouse relative to game area (with right/down positive).
459 int32_t get_state() const throw();
461 * Get calibration data.
463 mouse_calibration get_calibration() { return cal; }
464 private:
465 int32_t state;
466 mouse_calibration cal;
470 * A keyboard event listener.
472 class event_listener
474 public:
476 * Destructor.
478 virtual ~event_listener() throw();
480 * Receive a key event.
482 * Parameter mods: Modifiers currently active.
483 * Parameter key: The key this event is about.
484 * Parameter event: The event.
486 virtual void on_key_event(modifier_set& mods, key& key, event& event) = 0;
490 * A (compound) key on keyboard.
492 class key
494 public:
496 * Constructor.
498 * Parameter keyb: The keyboard this is on.
499 * Parameter name: The base name of the key.
500 * Parameter clazz: The class of the key.
501 * Parameter type: The type of key.
503 key(keyboard& keyb, const std::string& name, const std::string& clazz, keytype type)
504 throw(std::bad_alloc);
506 * Destructor.
508 virtual ~key() throw();
510 * Get class.
512 const std::string& get_class() { return clazz; }
514 * Get name.
516 const std::string& get_name() { return name; }
518 * Get keyboard this is on.
520 keyboard& get_keyboard() { return kbd; }
522 * Get key type.
524 keytype get_type() const throw() { return type; }
526 * Add listener.
528 * Parameter listener: The listener.
529 * Parameter analog: If true, also pass analog events.
531 void add_listener(event_listener& listener, bool analog) throw(std::bad_alloc);
533 * Remove listener.
535 * Parameter listener: The listener.
537 void remove_listener(event_listener& listener) throw();
539 * Set exclusive listener.
541 * Parameter listener: The listener. NULL to ungrab key.
543 void set_exclusive(event_listener* listener) throw();
545 * Set analog state.
547 * Parameter mods: The current modifiers.
548 * Parameter state: The new state. The format is dependent on key type.
550 virtual void set_state(modifier_set mods, int32_t state) throw() = 0;
552 * Get analog state. The format is dependent on key type.
554 virtual int32_t get_state() const throw() = 0;
556 * Get digital state. The format is dependent on key type.
558 virtual int32_t get_state_digital() const throw() = 0;
560 * Get the subkey suffixes.
562 virtual std::vector<std::string> get_subkeys() throw(std::bad_alloc) = 0;
564 * Dynamic cast to axis type.
566 key_axis* cast_axis() throw();
568 * Dynamic cast to mouse type.
570 key_mouse* cast_mouse() throw();
571 protected:
573 * Call all event listeners on this key.
575 * Parameter mods: The current modifiers.
576 * Parameter event: The event to pass.
578 void call_listeners(modifier_set& mods, event& event);
579 private:
580 key(key&);
581 key& operator=(key&);
582 keyboard& kbd;
583 std::string clazz;
584 std::string name;
585 std::set<event_listener*> digital_listeners;
586 std::set<event_listener*> analog_listeners;
587 event_listener* exclusive_listener;
588 keytype type;
592 * A simple key on keyboard.
594 class key_key : public key
596 public:
598 * Constructor.
600 * Parameter keyb: The keyboard this is on.
601 * Parameter name: The base name of the key.
602 * Parameter clazz: The class of the key.
604 key_key(keyboard& keyb, const std::string& name, const std::string& clazz) throw(std::bad_alloc);
606 * Destructor.
608 ~key_key() throw();
610 * Set analog state.
612 * Parameter mods: The current modifiers.
613 * Parameter state: The new state. 1 for pressed, 0 for released.
615 void set_state(modifier_set mods, int32_t state) throw();
617 * Get analog state. 1 for pressed, 0 for released.
619 int32_t get_state() const throw();
621 * Get digital state. 1 for pressed, 0 for released.
623 int32_t get_state_digital() const throw();
625 * Get the subkey suffixes.
627 std::vector<std::string> get_subkeys() throw(std::bad_alloc);
628 private:
629 key_key(key_key&);
630 key_key& operator=(key_key&);
631 int32_t state;
635 * A hat on keyboard.
637 class key_hat : public key
639 public:
641 * Constructor.
643 * Parameter keyb: The keyboard this is on.
644 * Parameter name: The base name of the key.
645 * Parameter clazz: The class of the key.
647 key_hat(keyboard& keyb, const std::string& name, const std::string& clazz) throw(std::bad_alloc);
649 * Destructor.
651 ~key_hat() throw();
653 * Set analog state.
655 * Parameter mods: The current modifiers.
656 * Parameter state: The new state. 1 => up, 2 => right, 4 => down, 8 => left.
658 void set_state(modifier_set mods, int32_t state) throw();
660 * Get analog state. 1 => up, 2 => right, 4 => down, 8 => left.
662 int32_t get_state() const throw();
664 * Get digital state. 1 => up, 2 => right, 4 => down, 8 => left.
666 int32_t get_state_digital() const throw();
668 * Get the subkey suffixes.
670 std::vector<std::string> get_subkeys() throw(std::bad_alloc);
671 private:
672 key_hat(key_hat&);
673 key_hat& operator=(key_hat&);
674 int32_t state;
678 * An axis on keyboard.
680 class key_axis : public key
682 public:
684 * Constructor.
686 * Parameter keyb: The keyboard this is on.
687 * Parameter name: The base name of the key.
688 * Parameter clazz: The class of the key.
689 * Parameter mode: Initial mode: -1 => disabled, 0 => axis, 1 => pressure
691 key_axis(keyboard& keyb, const std::string& name, const std::string& clazz, int mode)
692 throw(std::bad_alloc);
694 * Destructor.
696 ~key_axis() throw();
698 * Set analog state.
700 * Parameter mods: The current modifiers.
701 * Parameter state: The new state. Uncalibrated analog position.
703 void set_state(modifier_set mods, int32_t state) throw();
705 * Get analog state. -32767...32767 for axes, 0...32767 for pressure-sensitive buttons.
707 int32_t get_state() const throw();
709 * Get digital state. -1 => left, 0 => center/unpressed, 1 => Right/pressed.
711 int32_t get_state_digital() const throw();
713 * Get the subkey suffixes.
715 std::vector<std::string> get_subkeys() throw(std::bad_alloc);
717 * Get mode.
719 int get_mode() const throw();
721 * Set mode.
723 void set_mode(int mode, double tolerance) throw();
724 private:
725 key_axis(key_axis&);
726 key_axis& operator=(key_axis&);
727 int32_t rawstate;
728 int digitalstate;
729 double last_tolerance;
730 int _mode;
734 * A mouse axis on keyboard.
736 class key_mouse : public key
738 public:
740 * Constructor.
742 * Parameter keyb: The keyboard this is on.
743 * Parameter name: The base name of the key.
744 * Parameter clazz: The class of the key.
745 * Parameter cal: Initial calibration.
747 key_mouse(keyboard& keyb, const std::string& name, const std::string& clazz,
748 mouse_calibration cal) throw(std::bad_alloc);
750 * Destructor.
752 ~key_mouse() throw();
754 * Set analog state.
756 * Parameter mods: The current modifiers.
757 * Parameter state: The new state. Screen-relative analog position.
759 void set_state(modifier_set mods, int32_t state) throw();
761 * Get analog state. Game-relative analog position.
763 int32_t get_state() const throw();
765 * Get digital state. Always returns 0.
767 int32_t get_state_digital() const throw();
769 * Get the subkey suffixes. Returns empty list.
771 std::vector<std::string> get_subkeys() throw(std::bad_alloc);
773 * Get calibration.
775 mouse_calibration get_calibration() const throw();
777 * Set calibration.
779 void set_calibration(mouse_calibration cal) throw();
780 private:
781 key_mouse(key_mouse&);
782 key_mouse& operator=(key_mouse&);
783 int32_t rawstate;
784 mouse_calibration cal;
787 #endif