-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// keyboard.h
-
-
-#ifndef _KEYBOARD_H
-# define _KEYBOARD_H
-
-# include "misc.h"
-# include "driver.h"
-# include "stringtool.h"
-# include <vector>
-# include <list>
-# include <map>
-
-
-/// a scan code with flags
-class ScanCode
-{
-public:
- ///
- enum
- {
- BREAK = KEYBOARD_INPUT_DATA::BREAK, /// key release flag
- E0 = KEYBOARD_INPUT_DATA::E0, /// extended key flag
- E1 = KEYBOARD_INPUT_DATA::E1, /// extended key flag
- E0E1 = KEYBOARD_INPUT_DATA::E0E1, /// extended key flag
- };
-
-public:
- USHORT m_scan; ///
- USHORT m_flags; ///
-
-public:
- ///
- ScanCode() : m_scan(0), m_flags(0) { }
- ///
- ScanCode(USHORT i_scan, USHORT i_flags)
- : m_scan(i_scan), m_flags(i_flags) { }
- ///
- bool operator==(const ScanCode &i_sc) const
- {
- return (m_scan == i_sc.m_scan &&
- (E0E1 & m_flags) == (E0E1 & i_sc.m_flags));
- }
- ///
- bool operator!=(const ScanCode &i_sc) const { return !(*this == i_sc); }
-};
-
-
-/// a key
-class Key
-{
-public:
- enum
- {
- ///
- MAX_SCAN_CODES_SIZE = 4,
- };
-
-private:
- ///
- typedef std::vector<tstringi> Names;
-
-public:
- /// if this key pressed physically
- bool m_isPressed;
- /// if this key pressed on Win32
- bool m_isPressedOnWin32;
- /// if this key pressed by assign
- bool m_isPressedByAssign;
-
-private:
- /// key name
- Names m_names;
- /// key scan code length
- size_t m_scanCodesSize;
- /// key scan code
- ScanCode m_scanCodes[MAX_SCAN_CODES_SIZE];
-
-public:
- ///
- Key()
- : m_isPressed(false),
- m_isPressedOnWin32(false),
- m_isPressedByAssign(false),
- m_scanCodesSize(0)
- { }
-
- /// for Event::* only
- Key(const tstringi &i_name)
- : m_isPressed(false),
- m_isPressedOnWin32(false),
- m_isPressedByAssign(false),
- m_scanCodesSize(0)
- {
- addName(i_name);
- addScanCode(ScanCode());
- }
-
- /// get key name (first name)
- const tstringi &getName() const { return m_names.front(); }
-
- /// get scan codes
- const ScanCode *getScanCodes() const { return m_scanCodes; }
- ///
- size_t getScanCodesSize() const { return m_scanCodesSize; }
-
- /// add a name of key
- void addName(const tstringi &i_name);
-
- /// add a scan code
- void addScanCode(const ScanCode &i_sc);
-
- /// initializer
- Key &initialize();
-
- /// equation by name
- bool operator==(const tstringi &i_name) const;
- ///
- bool operator!=(const tstringi &i_name) const
- { return !(*this == i_name); }
-
- /// is the scan code of this key ?
- bool isSameScanCode(const Key &i_key) const;
-
- /// is the i_key's scan code the prefix of this key's scan code ?
- bool isPrefixScanCode(const Key &i_key) const;
-
- /// stream output
- friend tostream &operator<<(tostream &i_ost, const Key &i_key);
-
- /// <
- bool operator<(const Key &i_key) const
- { return getName() < i_key.getName(); }
-};
-
-
-///
-class Modifier
-{
- ///
- typedef u_int64 MODIFIERS;
- ///
- MODIFIERS m_modifiers;
- ///
- MODIFIERS m_dontcares;
-
-public:
- ///
- enum Type
- {
- Type_begin = 0, ///
-
- Type_Shift = Type_begin, /// <BASIC_MODIFIER>
- Type_Alt, /// <BASIC_MODIFIER>
- Type_Control, /// <BASIC_MODIFIER>
- Type_Windows, /// <BASIC_MODIFIER>
- Type_BASIC, ///
-
- Type_Up = Type_BASIC, /// <KEYSEQ_MODIFIER>
- Type_Down, /// <KEYSEQ_MODIFIER>
- Type_KEYSEQ, ///
-
- Type_Repeat = Type_KEYSEQ, /// <ASSIGN_MODIFIER>
- Type_ImeLock, /// <ASSIGN_MODIFIER>
- Type_ImeComp, /// <ASSIGN_MODIFIER>
- Type_NumLock, /// <ASSIGN_MODIFIER>
- Type_CapsLock, /// <ASSIGN_MODIFIER>
- Type_ScrollLock, /// <ASSIGN_MODIFIER>
- Type_KanaLock, /// <ASSIGN_MODIFIER>
- Type_Maximized, /// <ASSIGN_MODIFIER>
- Type_Minimized, /// <ASSIGN_MODIFIER>
- Type_MdiMaximized, /// <ASSIGN_MODIFIER>
- Type_MdiMinimized, /// <ASSIGN_MODIFIER>
- Type_Touchpad, /// <ASSIGN_MODIFIER>
- Type_TouchpadSticky, /// <ASSIGN_MODIFIER>
- Type_Mod0, /// <ASSIGN_MODIFIER>
- Type_Mod1, /// <ASSIGN_MODIFIER>
- Type_Mod2, /// <ASSIGN_MODIFIER>
- Type_Mod3, /// <ASSIGN_MODIFIER>
- Type_Mod4, /// <ASSIGN_MODIFIER>
- Type_Mod5, /// <ASSIGN_MODIFIER>
- Type_Mod6, /// <ASSIGN_MODIFIER>
- Type_Mod7, /// <ASSIGN_MODIFIER>
- Type_Mod8, /// <ASSIGN_MODIFIER>
- Type_Mod9, /// <ASSIGN_MODIFIER>
- Type_Lock0, /// <ASSIGN_MODIFIER>
- Type_Lock1, /// <ASSIGN_MODIFIER>
- Type_Lock2, /// <ASSIGN_MODIFIER>
- Type_Lock3, /// <ASSIGN_MODIFIER>
- Type_Lock4, /// <ASSIGN_MODIFIER>
- Type_Lock5, /// <ASSIGN_MODIFIER>
- Type_Lock6, /// <ASSIGN_MODIFIER>
- Type_Lock7, /// <ASSIGN_MODIFIER>
- Type_Lock8, /// <ASSIGN_MODIFIER>
- Type_Lock9, /// <ASSIGN_MODIFIER>
- Type_ASSIGN, ///
-
- Type_end = Type_ASSIGN ///
- };
-
-public:
- ///
- Modifier();
- ///
- Modifier &on(Type i_type) { return press(i_type); }
- ///
- Modifier &off(Type i_type) { return release(i_type); }
- ///
- Modifier &press(Type i_type)
- { m_modifiers |= ((MODIFIERS(1)) << i_type); return care(i_type); }
- ///
- Modifier &release(Type i_type)
- { m_modifiers &= ~((MODIFIERS(1)) << i_type); return care(i_type); }
- ///
- Modifier &care(Type i_type)
- { m_dontcares &= ~((MODIFIERS(1)) << i_type); return *this; }
- ///
- Modifier &dontcare(Type i_type)
- { m_dontcares |= ((MODIFIERS(1)) << i_type); return *this; }
- /// set all modifiers to dontcare
- Modifier &dontcare() { m_dontcares = ~MODIFIERS(0); return *this; }
-
- ///
- Modifier &on(Type i_type, bool i_isOn) { return press(i_type, i_isOn); }
- ///
- Modifier &press(Type i_type, bool i_isPressed)
- { return i_isPressed ? press(i_type) : release(i_type); }
- ///
- Modifier &care(Type i_type, bool i_doCare)
- { return i_doCare ? care(i_type) : dontcare(i_type); }
-
- ///
- bool operator==(const Modifier &i_m) const
- { return m_modifiers == i_m.m_modifiers && m_dontcares == i_m.m_dontcares; }
-
- /// add m's modifiers where this dontcare
- void add(const Modifier &i_m);
- //Modifier &operator+=(const Modifier &i_m);
-
- /** does match. (except dontcare modifiers) (is the m included in the *this
- set ?) */
- bool doesMatch(const Modifier &i_m) const
- { return ((m_modifiers | m_dontcares) == (i_m.m_modifiers | m_dontcares)); }
-
- ///
- bool isOn(Type i_type) const { return isPressed(i_type); }
- ///
- bool isPressed(Type i_type) const
- { return !!(m_modifiers & ((MODIFIERS(1)) << i_type)); }
- ///
- bool isDontcare(Type i_type) const
- { return !!(m_dontcares & ((MODIFIERS(1)) << i_type)); }
-
- /// stream output
- friend tostream &operator<<(tostream &i_ost, const Modifier &i_m);
-
- /// <
- bool operator<(const Modifier &i_m) const
- {
- return m_modifiers < i_m.m_modifiers ||
- (m_modifiers == i_m.m_modifiers && m_dontcares < i_m.m_dontcares);
- }
-};
-
-
-/// stream output
-tostream &operator<<(tostream &i_ost, Modifier::Type i_type);
-
-
-///
-class ModifiedKey
-{
-public:
- Modifier m_modifier; ///
- Key *m_key; ///
-
-public:
- ///
- ModifiedKey() : m_key(NULL) { }
- ///
- ModifiedKey(Key *i_key) : m_key(i_key) { }
- ///
- ModifiedKey(const Modifier &i_modifier, Key *i_key)
- : m_modifier(i_modifier), m_key(i_key) { }
- ///
- bool operator==(const ModifiedKey &i_mk) const
- { return m_modifier == i_mk.m_modifier && m_key == i_mk.m_key; }
- ///
- bool operator!=(const ModifiedKey &i_mk) const
- { return !operator==(i_mk); }
-
- /// stream output
- friend tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk);
-
- /// <
- bool operator<(const ModifiedKey &i_mk) const
- {
- return *m_key < *i_mk.m_key ||
- (!(*i_mk.m_key < *m_key) && m_modifier < i_mk.m_modifier);
- }
-};
-
-
-///
-class Keyboard
-{
-public:
- /// keyboard modifiers (pointer into Keys)
- typedef std::list<Key *> Mods;
-
-private:
- /** keyboard keys (hashed by first scan code).
- Keys must be *list* of Key.
- Because *pointers* into Keys exist anywhere in this program, the address
- of Key's elements must be fixed. */
- enum {
- HASHED_KEYS_SIZE = 128, ///
- };
- typedef std::list<Key> Keys; ///
- typedef std::map<tstringi, Key *> Aliases; /// key name aliases
- ///
- class Substitute
- {
- public:
- ModifiedKey m_mkeyFrom;
- ModifiedKey m_mkeyTo;
- public:
- Substitute(const ModifiedKey &i_mkeyFrom,
- const ModifiedKey &i_mkeyTo)
- : m_mkeyFrom(i_mkeyFrom), m_mkeyTo(i_mkeyTo)
- {
- }
- };
- typedef std::list<Substitute> Substitutes; /// substitutes
-
-private:
- Keys m_hashedKeys[HASHED_KEYS_SIZE]; ///
- Aliases m_aliases; ///
- Substitutes m_substitutes; ///
- Key m_syncKey; /// key used to synchronize
-
-private:
- ///
- Mods m_mods[Modifier::Type_BASIC];
-
-public:
- ///
- class KeyIterator
- {
- ///
- Keys *m_hashedKeys;
- ///
- size_t m_hashedKeysSize;
- ///
- Keys::iterator m_i;
-
- ///
- void next();
-
- public:
- ///
- KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize);
- ///
- Key *operator *();
- ///
- void operator++() { next(); }
- };
-
-private:
- ///
- Keys &getKeys(const Key &i_key);
-
-public:
- /// add a key
- void addKey(const Key &i_key);
-
- /// add a key name alias
- void addAlias(const tstringi &i_aliasName, Key *i_key);
-
- /// add substitute
- void addSubstitute(const ModifiedKey &i_mkeyFrom,
- const ModifiedKey &i_mkeyTo);
-
- /// get a sync key
- Key *getSyncKey() { return &m_syncKey; }
-
- /// add a modifier key
- void addModifier(Modifier::Type i_mt, Key * i_key);
-
- /// search a key
- Key *searchKey(const Key &i_key);
-
- /// search a key (of which the key's scan code is the prefix)
- Key *searchPrefixKey(const Key &i_key);
-
- /// search a key by name
- Key *searchKey(const tstringi &i_name);
-
- /// search a key by non-alias name
- Key *searchKeyByNonAliasName(const tstringi &i_name);
-
- /// search a substitute
- ModifiedKey searchSubstitute(const ModifiedKey &i_mkey);
-
- /// get modifiers
- Mods &getModifiers(Modifier::Type i_mt) { return m_mods[i_mt]; }
-
- /// get key iterator
- KeyIterator getKeyIterator()
- { return KeyIterator(&m_hashedKeys[0], HASHED_KEYS_SIZE); }
-};
-
-
-#endif // !_KEYBOARD_H
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r
+// keyboard.h\r
+\r
+\r
+#ifndef _KEYBOARD_H\r
+# define _KEYBOARD_H\r
+\r
+# include "misc.h"\r
+# include "driver.h"\r
+# include "stringtool.h"\r
+# include <vector>\r
+# include <list>\r
+# include <map>\r
+\r
+\r
+/// a scan code with flags\r
+class ScanCode\r
+{\r
+public:\r
+ ///\r
+ enum {\r
+ BREAK = KEYBOARD_INPUT_DATA::BREAK, /// key release flag\r
+ E0 = KEYBOARD_INPUT_DATA::E0, /// extended key flag\r
+ E1 = KEYBOARD_INPUT_DATA::E1, /// extended key flag\r
+ E0E1 = KEYBOARD_INPUT_DATA::E0E1, /// extended key flag\r
+ };\r
+\r
+public:\r
+ USHORT m_scan; ///\r
+ USHORT m_flags; ///\r
+\r
+public:\r
+ ///\r
+ ScanCode() : m_scan(0), m_flags(0) { }\r
+ ///\r
+ ScanCode(USHORT i_scan, USHORT i_flags)\r
+ : m_scan(i_scan), m_flags(i_flags) { }\r
+ ///\r
+ bool operator==(const ScanCode &i_sc) const {\r
+ return (m_scan == i_sc.m_scan &&\r
+ (E0E1 & m_flags) == (E0E1 & i_sc.m_flags));\r
+ }\r
+ ///\r
+ bool operator!=(const ScanCode &i_sc) const {\r
+ return !(*this == i_sc);\r
+ }\r
+};\r
+\r
+\r
+/// a key\r
+class Key\r
+{\r
+public:\r
+ enum {\r
+ ///\r
+ MAX_SCAN_CODES_SIZE = 4,\r
+ };\r
+\r
+private:\r
+ ///\r
+ typedef std::vector<tstringi> Names;\r
+\r
+public:\r
+ /// if this key pressed physically\r
+ bool m_isPressed;\r
+ /// if this key pressed on Win32\r
+ bool m_isPressedOnWin32;\r
+ /// if this key pressed by assign\r
+ bool m_isPressedByAssign;\r
+\r
+private:\r
+ /// key name\r
+ Names m_names;\r
+ /// key scan code length\r
+ size_t m_scanCodesSize;\r
+ /// key scan code\r
+ ScanCode m_scanCodes[MAX_SCAN_CODES_SIZE];\r
+\r
+public:\r
+ ///\r
+ Key()\r
+ : m_isPressed(false),\r
+ m_isPressedOnWin32(false),\r
+ m_isPressedByAssign(false),\r
+ m_scanCodesSize(0) { }\r
+\r
+ /// for Event::* only\r
+ Key(const tstringi &i_name)\r
+ : m_isPressed(false),\r
+ m_isPressedOnWin32(false),\r
+ m_isPressedByAssign(false),\r
+ m_scanCodesSize(0) {\r
+ addName(i_name);\r
+ addScanCode(ScanCode());\r
+ }\r
+\r
+ /// get key name (first name)\r
+ const tstringi &getName() const {\r
+ return m_names.front();\r
+ }\r
+\r
+ /// get scan codes\r
+ const ScanCode *getScanCodes() const {\r
+ return m_scanCodes;\r
+ }\r
+ ///\r
+ size_t getScanCodesSize() const {\r
+ return m_scanCodesSize;\r
+ }\r
+\r
+ /// add a name of key\r
+ void addName(const tstringi &i_name);\r
+\r
+ /// add a scan code\r
+ void addScanCode(const ScanCode &i_sc);\r
+\r
+ /// initializer\r
+ Key &initialize();\r
+\r
+ /// equation by name\r
+ bool operator==(const tstringi &i_name) const;\r
+ ///\r
+ bool operator!=(const tstringi &i_name) const {\r
+ return !(*this == i_name);\r
+ }\r
+\r
+ /// is the scan code of this key ?\r
+ bool isSameScanCode(const Key &i_key) const;\r
+\r
+ /// is the i_key's scan code the prefix of this key's scan code ?\r
+ bool isPrefixScanCode(const Key &i_key) const;\r
+\r
+ /// stream output\r
+ friend tostream &operator<<(tostream &i_ost, const Key &i_key);\r
+\r
+ /// <\r
+ bool operator<(const Key &i_key) const {\r
+ return getName() < i_key.getName();\r
+ }\r
+};\r
+\r
+\r
+///\r
+class Modifier\r
+{\r
+ ///\r
+ typedef u_int64 MODIFIERS;\r
+ ///\r
+ MODIFIERS m_modifiers;\r
+ ///\r
+ MODIFIERS m_dontcares;\r
+\r
+public:\r
+ ///\r
+ enum Type {\r
+ Type_begin = 0, ///\r
+\r
+ Type_Shift = Type_begin, /// <BASIC_MODIFIER>\r
+ Type_Alt, /// <BASIC_MODIFIER>\r
+ Type_Control, /// <BASIC_MODIFIER>\r
+ Type_Windows, /// <BASIC_MODIFIER>\r
+ Type_BASIC, ///\r
+\r
+ Type_Up = Type_BASIC, /// <KEYSEQ_MODIFIER>\r
+ Type_Down, /// <KEYSEQ_MODIFIER>\r
+ Type_KEYSEQ, ///\r
+\r
+ Type_Repeat = Type_KEYSEQ, /// <ASSIGN_MODIFIER>\r
+ Type_ImeLock, /// <ASSIGN_MODIFIER>\r
+ Type_ImeComp, /// <ASSIGN_MODIFIER>\r
+ Type_NumLock, /// <ASSIGN_MODIFIER>\r
+ Type_CapsLock, /// <ASSIGN_MODIFIER>\r
+ Type_ScrollLock, /// <ASSIGN_MODIFIER>\r
+ Type_KanaLock, /// <ASSIGN_MODIFIER>\r
+ Type_Maximized, /// <ASSIGN_MODIFIER>\r
+ Type_Minimized, /// <ASSIGN_MODIFIER>\r
+ Type_MdiMaximized, /// <ASSIGN_MODIFIER>\r
+ Type_MdiMinimized, /// <ASSIGN_MODIFIER>\r
+ Type_Touchpad, /// <ASSIGN_MODIFIER>\r
+ Type_TouchpadSticky, /// <ASSIGN_MODIFIER>\r
+ Type_Mod0, /// <ASSIGN_MODIFIER>\r
+ Type_Mod1, /// <ASSIGN_MODIFIER>\r
+ Type_Mod2, /// <ASSIGN_MODIFIER>\r
+ Type_Mod3, /// <ASSIGN_MODIFIER>\r
+ Type_Mod4, /// <ASSIGN_MODIFIER>\r
+ Type_Mod5, /// <ASSIGN_MODIFIER>\r
+ Type_Mod6, /// <ASSIGN_MODIFIER>\r
+ Type_Mod7, /// <ASSIGN_MODIFIER>\r
+ Type_Mod8, /// <ASSIGN_MODIFIER>\r
+ Type_Mod9, /// <ASSIGN_MODIFIER>\r
+ Type_Lock0, /// <ASSIGN_MODIFIER>\r
+ Type_Lock1, /// <ASSIGN_MODIFIER>\r
+ Type_Lock2, /// <ASSIGN_MODIFIER>\r
+ Type_Lock3, /// <ASSIGN_MODIFIER>\r
+ Type_Lock4, /// <ASSIGN_MODIFIER>\r
+ Type_Lock5, /// <ASSIGN_MODIFIER>\r
+ Type_Lock6, /// <ASSIGN_MODIFIER>\r
+ Type_Lock7, /// <ASSIGN_MODIFIER>\r
+ Type_Lock8, /// <ASSIGN_MODIFIER>\r
+ Type_Lock9, /// <ASSIGN_MODIFIER>\r
+ Type_ASSIGN, ///\r
+\r
+ Type_end = Type_ASSIGN ///\r
+ };\r
+\r
+public:\r
+ ///\r
+ Modifier();\r
+ ///\r
+ Modifier &on(Type i_type) {\r
+ return press(i_type);\r
+ }\r
+ ///\r
+ Modifier &off(Type i_type) {\r
+ return release(i_type);\r
+ }\r
+ ///\r
+ Modifier &press(Type i_type) {\r
+ m_modifiers |= ((MODIFIERS(1)) << i_type);\r
+ return care(i_type);\r
+ }\r
+ ///\r
+ Modifier &release(Type i_type) {\r
+ m_modifiers &= ~((MODIFIERS(1)) << i_type);\r
+ return care(i_type);\r
+ }\r
+ ///\r
+ Modifier &care(Type i_type) {\r
+ m_dontcares &= ~((MODIFIERS(1)) << i_type);\r
+ return *this;\r
+ }\r
+ ///\r
+ Modifier &dontcare(Type i_type) {\r
+ m_dontcares |= ((MODIFIERS(1)) << i_type);\r
+ return *this;\r
+ }\r
+ /// set all modifiers to dontcare\r
+ Modifier &dontcare() {\r
+ m_dontcares = ~MODIFIERS(0);\r
+ return *this;\r
+ }\r
+\r
+ ///\r
+ Modifier &on(Type i_type, bool i_isOn) {\r
+ return press(i_type, i_isOn);\r
+ }\r
+ ///\r
+ Modifier &press(Type i_type, bool i_isPressed) {\r
+ return i_isPressed ? press(i_type) : release(i_type);\r
+ }\r
+ ///\r
+ Modifier &care(Type i_type, bool i_doCare) {\r
+ return i_doCare ? care(i_type) : dontcare(i_type);\r
+ }\r
+\r
+ ///\r
+ bool operator==(const Modifier &i_m) const {\r
+ return m_modifiers == i_m.m_modifiers && m_dontcares == i_m.m_dontcares;\r
+ }\r
+\r
+ /// add m's modifiers where this dontcare\r
+ void add(const Modifier &i_m);\r
+ //Modifier &operator+=(const Modifier &i_m);\r
+\r
+ /** does match. (except dontcare modifiers) (is the m included in the *this\r
+ set ?) */\r
+ bool doesMatch(const Modifier &i_m) const {\r
+ return ((m_modifiers | m_dontcares) == (i_m.m_modifiers | m_dontcares));\r
+ }\r
+\r
+ ///\r
+ bool isOn(Type i_type) const {\r
+ return isPressed(i_type);\r
+ }\r
+ ///\r
+ bool isPressed(Type i_type) const {\r
+ return !!(m_modifiers & ((MODIFIERS(1)) << i_type));\r
+ }\r
+ ///\r
+ bool isDontcare(Type i_type) const {\r
+ return !!(m_dontcares & ((MODIFIERS(1)) << i_type));\r
+ }\r
+\r
+ /// stream output\r
+ friend tostream &operator<<(tostream &i_ost, const Modifier &i_m);\r
+\r
+ /// <\r
+ bool operator<(const Modifier &i_m) const {\r
+ return m_modifiers < i_m.m_modifiers ||\r
+ (m_modifiers == i_m.m_modifiers && m_dontcares < i_m.m_dontcares);\r
+ }\r
+};\r
+\r
+\r
+/// stream output\r
+tostream &operator<<(tostream &i_ost, Modifier::Type i_type);\r
+\r
+\r
+///\r
+class ModifiedKey\r
+{\r
+public:\r
+ Modifier m_modifier; ///\r
+ Key *m_key; ///\r
+\r
+public:\r
+ ///\r
+ ModifiedKey() : m_key(NULL) { }\r
+ ///\r
+ ModifiedKey(Key *i_key) : m_key(i_key) { }\r
+ ///\r
+ ModifiedKey(const Modifier &i_modifier, Key *i_key)\r
+ : m_modifier(i_modifier), m_key(i_key) { }\r
+ ///\r
+ bool operator==(const ModifiedKey &i_mk) const {\r
+ return m_modifier == i_mk.m_modifier && m_key == i_mk.m_key;\r
+ }\r
+ ///\r
+ bool operator!=(const ModifiedKey &i_mk) const {\r
+ return !operator==(i_mk);\r
+ }\r
+\r
+ /// stream output\r
+ friend tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk);\r
+\r
+ /// <\r
+ bool operator<(const ModifiedKey &i_mk) const {\r
+ return *m_key < *i_mk.m_key ||\r
+ (!(*i_mk.m_key < *m_key) && m_modifier < i_mk.m_modifier);\r
+ }\r
+};\r
+\r
+\r
+///\r
+class Keyboard\r
+{\r
+public:\r
+ /// keyboard modifiers (pointer into Keys)\r
+ typedef std::list<Key *> Mods;\r
+\r
+private:\r
+ /** keyboard keys (hashed by first scan code).\r
+ Keys must be *list* of Key.\r
+ Because *pointers* into Keys exist anywhere in this program, the address\r
+ of Key's elements must be fixed. */\r
+ enum {\r
+ HASHED_KEYS_SIZE = 128, ///\r
+ };\r
+ typedef std::list<Key> Keys; ///\r
+ typedef std::map<tstringi, Key *> Aliases; /// key name aliases\r
+ ///\r
+ class Substitute\r
+ {\r
+ public:\r
+ ModifiedKey m_mkeyFrom;\r
+ ModifiedKey m_mkeyTo;\r
+ public:\r
+ Substitute(const ModifiedKey &i_mkeyFrom,\r
+ const ModifiedKey &i_mkeyTo)\r
+ : m_mkeyFrom(i_mkeyFrom), m_mkeyTo(i_mkeyTo) {\r
+ }\r
+ };\r
+ typedef std::list<Substitute> Substitutes; /// substitutes\r
+\r
+private:\r
+ Keys m_hashedKeys[HASHED_KEYS_SIZE]; ///\r
+ Aliases m_aliases; ///\r
+ Substitutes m_substitutes; ///\r
+ Key m_syncKey; /// key used to synchronize\r
+\r
+private:\r
+ ///\r
+ Mods m_mods[Modifier::Type_BASIC];\r
+\r
+public:\r
+ ///\r
+ class KeyIterator\r
+ {\r
+ ///\r
+ Keys *m_hashedKeys;\r
+ ///\r
+ size_t m_hashedKeysSize;\r
+ ///\r
+ Keys::iterator m_i;\r
+\r
+ ///\r
+ void next();\r
+\r
+ public:\r
+ ///\r
+ KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize);\r
+ ///\r
+ Key *operator *();\r
+ ///\r
+ void operator++() {\r
+ next();\r
+ }\r
+ };\r
+\r
+private:\r
+ ///\r
+ Keys &getKeys(const Key &i_key);\r
+\r
+public:\r
+ /// add a key\r
+ void addKey(const Key &i_key);\r
+\r
+ /// add a key name alias\r
+ void addAlias(const tstringi &i_aliasName, Key *i_key);\r
+\r
+ /// add substitute\r
+ void addSubstitute(const ModifiedKey &i_mkeyFrom,\r
+ const ModifiedKey &i_mkeyTo);\r
+\r
+ /// get a sync key\r
+ Key *getSyncKey() {\r
+ return &m_syncKey;\r
+ }\r
+\r
+ /// add a modifier key\r
+ void addModifier(Modifier::Type i_mt, Key * i_key);\r
+\r
+ /// search a key\r
+ Key *searchKey(const Key &i_key);\r
+\r
+ /// search a key (of which the key's scan code is the prefix)\r
+ Key *searchPrefixKey(const Key &i_key);\r
+\r
+ /// search a key by name\r
+ Key *searchKey(const tstringi &i_name);\r
+\r
+ /// search a key by non-alias name\r
+ Key *searchKeyByNonAliasName(const tstringi &i_name);\r
+\r
+ /// search a substitute\r
+ ModifiedKey searchSubstitute(const ModifiedKey &i_mkey);\r
+\r
+ /// get modifiers\r
+ Mods &getModifiers(Modifier::Type i_mt) {\r
+ return m_mods[i_mt];\r
+ }\r
+\r
+ /// get key iterator\r
+ KeyIterator getKeyIterator() {\r
+ return KeyIterator(&m_hashedKeys[0], HASHED_KEYS_SIZE);\r
+ }\r
+};\r
+\r
+\r
+#endif // !_KEYBOARD_H\r