1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10 # include "stringtool.h"
16 /// a scan code with flags
23 BREAK = KEYBOARD_INPUT_DATA::BREAK, /// key release flag
24 E0 = KEYBOARD_INPUT_DATA::E0, /// extended key flag
25 E1 = KEYBOARD_INPUT_DATA::E1, /// extended key flag
26 E0E1 = KEYBOARD_INPUT_DATA::E0E1, /// extended key flag
35 ScanCode() : m_scan(0), m_flags(0) { }
37 ScanCode(USHORT i_scan, USHORT i_flags)
38 : m_scan(i_scan), m_flags(i_flags) { }
40 bool operator==(const ScanCode &i_sc) const
42 return (m_scan == i_sc.m_scan &&
43 (E0E1 & m_flags) == (E0E1 & i_sc.m_flags));
46 bool operator!=(const ScanCode &i_sc) const { return !(*this == i_sc); }
57 MAX_SCAN_CODES_SIZE = 4,
62 typedef std::vector<tstringi> Names;
65 /// if this key pressed physically
67 /// if this key pressed on Win32
68 bool m_isPressedOnWin32;
69 /// if this key pressed by assign
70 bool m_isPressedByAssign;
75 /// key scan code length
76 size_t m_scanCodesSize;
78 ScanCode m_scanCodes[MAX_SCAN_CODES_SIZE];
84 m_isPressedOnWin32(false),
85 m_isPressedByAssign(false),
90 Key(const tstringi &i_name)
92 m_isPressedOnWin32(false),
93 m_isPressedByAssign(false),
97 addScanCode(ScanCode());
100 /// get key name (first name)
101 const tstringi &getName() const { return m_names.front(); }
104 const ScanCode *getScanCodes() const { return m_scanCodes; }
106 size_t getScanCodesSize() const { return m_scanCodesSize; }
108 /// add a name of key
109 void addName(const tstringi &i_name);
112 void addScanCode(const ScanCode &i_sc);
118 bool operator==(const tstringi &i_name) const;
120 bool operator!=(const tstringi &i_name) const
121 { return !(*this == i_name); }
123 /// is the scan code of this key ?
124 bool isSameScanCode(const Key &i_key) const;
126 /// is the i_key's scan code the prefix of this key's scan code ?
127 bool isPrefixScanCode(const Key &i_key) const;
130 friend tostream &operator<<(tostream &i_ost, const Key &i_key);
133 bool operator<(const Key &i_key) const
134 { return getName() < i_key.getName(); }
142 typedef u_int64 MODIFIERS;
144 MODIFIERS m_modifiers;
146 MODIFIERS m_dontcares;
154 Type_Shift = Type_begin, /// <BASIC_MODIFIER>
155 Type_Alt, /// <BASIC_MODIFIER>
156 Type_Control, /// <BASIC_MODIFIER>
157 Type_Windows, /// <BASIC_MODIFIER>
160 Type_Up = Type_BASIC, /// <KEYSEQ_MODIFIER>
161 Type_Down, /// <KEYSEQ_MODIFIER>
164 Type_Repeat = Type_KEYSEQ, /// <ASSIGN_MODIFIER>
165 Type_ImeLock, /// <ASSIGN_MODIFIER>
166 Type_ImeComp, /// <ASSIGN_MODIFIER>
167 Type_NumLock, /// <ASSIGN_MODIFIER>
168 Type_CapsLock, /// <ASSIGN_MODIFIER>
169 Type_ScrollLock, /// <ASSIGN_MODIFIER>
170 Type_KanaLock, /// <ASSIGN_MODIFIER>
171 Type_Maximized, /// <ASSIGN_MODIFIER>
172 Type_Minimized, /// <ASSIGN_MODIFIER>
173 Type_MdiMaximized, /// <ASSIGN_MODIFIER>
174 Type_MdiMinimized, /// <ASSIGN_MODIFIER>
175 Type_Touchpad, /// <ASSIGN_MODIFIER>
176 Type_TouchpadSticky, /// <ASSIGN_MODIFIER>
177 Type_Mod0, /// <ASSIGN_MODIFIER>
178 Type_Mod1, /// <ASSIGN_MODIFIER>
179 Type_Mod2, /// <ASSIGN_MODIFIER>
180 Type_Mod3, /// <ASSIGN_MODIFIER>
181 Type_Mod4, /// <ASSIGN_MODIFIER>
182 Type_Mod5, /// <ASSIGN_MODIFIER>
183 Type_Mod6, /// <ASSIGN_MODIFIER>
184 Type_Mod7, /// <ASSIGN_MODIFIER>
185 Type_Mod8, /// <ASSIGN_MODIFIER>
186 Type_Mod9, /// <ASSIGN_MODIFIER>
187 Type_Lock0, /// <ASSIGN_MODIFIER>
188 Type_Lock1, /// <ASSIGN_MODIFIER>
189 Type_Lock2, /// <ASSIGN_MODIFIER>
190 Type_Lock3, /// <ASSIGN_MODIFIER>
191 Type_Lock4, /// <ASSIGN_MODIFIER>
192 Type_Lock5, /// <ASSIGN_MODIFIER>
193 Type_Lock6, /// <ASSIGN_MODIFIER>
194 Type_Lock7, /// <ASSIGN_MODIFIER>
195 Type_Lock8, /// <ASSIGN_MODIFIER>
196 Type_Lock9, /// <ASSIGN_MODIFIER>
199 Type_end = Type_ASSIGN ///
206 Modifier &on(Type i_type) { return press(i_type); }
208 Modifier &off(Type i_type) { return release(i_type); }
210 Modifier &press(Type i_type)
211 { m_modifiers |= ((MODIFIERS(1)) << i_type); return care(i_type); }
213 Modifier &release(Type i_type)
214 { m_modifiers &= ~((MODIFIERS(1)) << i_type); return care(i_type); }
216 Modifier &care(Type i_type)
217 { m_dontcares &= ~((MODIFIERS(1)) << i_type); return *this; }
219 Modifier &dontcare(Type i_type)
220 { m_dontcares |= ((MODIFIERS(1)) << i_type); return *this; }
221 /// set all modifiers to dontcare
222 Modifier &dontcare() { m_dontcares = ~MODIFIERS(0); return *this; }
225 Modifier &on(Type i_type, bool i_isOn) { return press(i_type, i_isOn); }
227 Modifier &press(Type i_type, bool i_isPressed)
228 { return i_isPressed ? press(i_type) : release(i_type); }
230 Modifier &care(Type i_type, bool i_doCare)
231 { return i_doCare ? care(i_type) : dontcare(i_type); }
234 bool operator==(const Modifier &i_m) const
235 { return m_modifiers == i_m.m_modifiers && m_dontcares == i_m.m_dontcares; }
237 /// add m's modifiers where this dontcare
238 void add(const Modifier &i_m);
239 //Modifier &operator+=(const Modifier &i_m);
241 /** does match. (except dontcare modifiers) (is the m included in the *this
243 bool doesMatch(const Modifier &i_m) const
244 { return ((m_modifiers | m_dontcares) == (i_m.m_modifiers | m_dontcares)); }
247 bool isOn(Type i_type) const { return isPressed(i_type); }
249 bool isPressed(Type i_type) const
250 { return !!(m_modifiers & ((MODIFIERS(1)) << i_type)); }
252 bool isDontcare(Type i_type) const
253 { return !!(m_dontcares & ((MODIFIERS(1)) << i_type)); }
256 friend tostream &operator<<(tostream &i_ost, const Modifier &i_m);
259 bool operator<(const Modifier &i_m) const
261 return m_modifiers < i_m.m_modifiers ||
262 (m_modifiers == i_m.m_modifiers && m_dontcares < i_m.m_dontcares);
268 tostream &operator<<(tostream &i_ost, Modifier::Type i_type);
275 Modifier m_modifier; ///
280 ModifiedKey() : m_key(NULL) { }
282 ModifiedKey(Key *i_key) : m_key(i_key) { }
284 ModifiedKey(const Modifier &i_modifier, Key *i_key)
285 : m_modifier(i_modifier), m_key(i_key) { }
287 bool operator==(const ModifiedKey &i_mk) const
288 { return m_modifier == i_mk.m_modifier && m_key == i_mk.m_key; }
290 bool operator!=(const ModifiedKey &i_mk) const
291 { return !operator==(i_mk); }
294 friend tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk);
297 bool operator<(const ModifiedKey &i_mk) const
299 return *m_key < *i_mk.m_key ||
300 (!(*i_mk.m_key < *m_key) && m_modifier < i_mk.m_modifier);
309 /// keyboard modifiers (pointer into Keys)
310 typedef std::list<Key *> Mods;
313 /** keyboard keys (hashed by first scan code).
314 Keys must be *list* of Key.
315 Because *pointers* into Keys exist anywhere in this program, the address
316 of Key's elements must be fixed. */
318 HASHED_KEYS_SIZE = 128, ///
320 typedef std::list<Key> Keys; ///
321 typedef std::map<tstringi, Key *> Aliases; /// key name aliases
326 ModifiedKey m_mkeyFrom;
327 ModifiedKey m_mkeyTo;
329 Substitute(const ModifiedKey &i_mkeyFrom,
330 const ModifiedKey &i_mkeyTo)
331 : m_mkeyFrom(i_mkeyFrom), m_mkeyTo(i_mkeyTo)
335 typedef std::list<Substitute> Substitutes; /// substitutes
338 Keys m_hashedKeys[HASHED_KEYS_SIZE]; ///
339 Aliases m_aliases; ///
340 Substitutes m_substitutes; ///
341 Key m_syncKey; /// key used to synchronize
345 Mods m_mods[Modifier::Type_BASIC];
354 size_t m_hashedKeysSize;
363 KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize);
367 void operator++() { next(); }
372 Keys &getKeys(const Key &i_key);
376 void addKey(const Key &i_key);
378 /// add a key name alias
379 void addAlias(const tstringi &i_aliasName, Key *i_key);
382 void addSubstitute(const ModifiedKey &i_mkeyFrom,
383 const ModifiedKey &i_mkeyTo);
386 Key *getSyncKey() { return &m_syncKey; }
388 /// add a modifier key
389 void addModifier(Modifier::Type i_mt, Key * i_key);
392 Key *searchKey(const Key &i_key);
394 /// search a key (of which the key's scan code is the prefix)
395 Key *searchPrefixKey(const Key &i_key);
397 /// search a key by name
398 Key *searchKey(const tstringi &i_name);
400 /// search a key by non-alias name
401 Key *searchKeyByNonAliasName(const tstringi &i_name);
403 /// search a substitute
404 ModifiedKey searchSubstitute(const ModifiedKey &i_mkey);
407 Mods &getModifiers(Modifier::Type i_mt) { return m_mods[i_mt]; }
410 KeyIterator getKeyIterator()
411 { return KeyIterator(&m_hashedKeys[0], HASHED_KEYS_SIZE); }
415 #endif // !_KEYBOARD_H