1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
5 #include "keyboard.h"
\r
10 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
14 // add a name or an alias of key
\r
15 void Key::addName(const tstringi &i_name)
\r
17 m_names.push_back(i_name);
\r
22 void Key::addScanCode(const ScanCode &i_sc)
\r
24 ASSERT(m_scanCodesSize < MAX_SCAN_CODES_SIZE);
\r
25 m_scanCodes[m_scanCodesSize ++] = i_sc;
\r
30 Key &Key::initialize()
\r
33 m_isPressed = false;
\r
34 m_isPressedOnWin32 = false;
\r
35 m_isPressedByAssign = false;
\r
36 m_scanCodesSize = 0;
\r
42 bool Key::operator==(const tstringi &i_name) const
\r
44 return std::find(m_names.begin(), m_names.end(), i_name) != m_names.end();
\r
48 // is the scan code of this key ?
\r
49 bool Key::isSameScanCode(const Key &i_key) const
\r
51 if (m_scanCodesSize != i_key.m_scanCodesSize)
\r
53 return isPrefixScanCode(i_key);
\r
57 // is the key's scan code the prefix of this key's scan code ?
\r
58 bool Key::isPrefixScanCode(const Key &i_key) const
\r
60 for (size_t i = 0; i < i_key.m_scanCodesSize; ++ i)
\r
61 if (m_scanCodes[i] != i_key.m_scanCodes[i])
\r
68 tostream &operator<<(tostream &i_ost, const Key &i_mk)
\r
70 return i_ost << i_mk.getName();
\r
74 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
78 Modifier::Modifier()
\r
82 ASSERT(Type_end <= (sizeof(MODIFIERS) * 8));
\r
83 static const Type defaultDontCare[] = {
\r
84 Type_Up, Type_Down, Type_Repeat,
\r
85 Type_ImeLock, Type_ImeComp, Type_NumLock, Type_CapsLock, Type_ScrollLock,
\r
87 Type_Maximized, Type_Minimized, Type_MdiMaximized, Type_MdiMinimized,
\r
88 Type_Touchpad, Type_TouchpadSticky,
\r
89 Type_Lock0, Type_Lock1, Type_Lock2, Type_Lock3, Type_Lock4,
\r
90 Type_Lock5, Type_Lock6, Type_Lock7, Type_Lock8, Type_Lock9,
\r
92 for (size_t i = 0; i < NUMBER_OF(defaultDontCare); ++ i)
\r
93 dontcare(defaultDontCare[i]);
\r
97 // add m's modifiers where this dontcare
\r
98 void Modifier::add(const Modifier &i_m)
\r
100 for (int i = 0; i < Type_end; ++ i) {
\r
101 if (isDontcare(static_cast<Modifier::Type>(i)))
\r
102 if (!i_m.isDontcare(static_cast<Modifier::Type>(i)))
\r
103 if (i_m.isPressed(static_cast<Modifier::Type>(i)))
\r
104 press(static_cast<Modifier::Type>(i));
\r
106 release(static_cast<Modifier::Type>(i));
\r
111 tostream &operator<<(tostream &i_ost, const Modifier &i_m)
\r
114 Modifier::Type m_mt;
\r
115 const _TCHAR *m_symbol;
\r
118 const static Mods mods[] = {
\r
119 { Modifier::Type_Up, _T("U-") }, { Modifier::Type_Down, _T("D-") },
\r
120 { Modifier::Type_Shift, _T("S-") }, { Modifier::Type_Alt, _T("A-") },
\r
121 { Modifier::Type_Control, _T("C-") }, { Modifier::Type_Windows, _T("W-") },
\r
122 { Modifier::Type_Repeat, _T("R-") },
\r
123 { Modifier::Type_ImeLock, _T("IL-") },
\r
124 { Modifier::Type_ImeComp, _T("IC-") },
\r
125 { Modifier::Type_ImeComp, _T("I-") },
\r
126 { Modifier::Type_NumLock, _T("NL-") },
\r
127 { Modifier::Type_CapsLock, _T("CL-") },
\r
128 { Modifier::Type_ScrollLock, _T("SL-") },
\r
129 { Modifier::Type_KanaLock, _T("KL-") },
\r
130 { Modifier::Type_Maximized, _T("MAX-") },
\r
131 { Modifier::Type_Minimized, _T("MIN-") },
\r
132 { Modifier::Type_MdiMaximized, _T("MMAX-") },
\r
133 { Modifier::Type_MdiMinimized, _T("MMIN-") },
\r
134 { Modifier::Type_Touchpad, _T("T-") },
\r
135 { Modifier::Type_TouchpadSticky, _T("TS-") },
\r
136 { Modifier::Type_Mod0, _T("M0-") }, { Modifier::Type_Mod1, _T("M1-") },
\r
137 { Modifier::Type_Mod2, _T("M2-") }, { Modifier::Type_Mod3, _T("M3-") },
\r
138 { Modifier::Type_Mod4, _T("M4-") }, { Modifier::Type_Mod5, _T("M5-") },
\r
139 { Modifier::Type_Mod6, _T("M6-") }, { Modifier::Type_Mod7, _T("M7-") },
\r
140 { Modifier::Type_Mod8, _T("M8-") }, { Modifier::Type_Mod9, _T("M9-") },
\r
141 { Modifier::Type_Lock0, _T("L0-") }, { Modifier::Type_Lock1, _T("L1-") },
\r
142 { Modifier::Type_Lock2, _T("L2-") }, { Modifier::Type_Lock3, _T("L3-") },
\r
143 { Modifier::Type_Lock4, _T("L4-") }, { Modifier::Type_Lock5, _T("L5-") },
\r
144 { Modifier::Type_Lock6, _T("L6-") }, { Modifier::Type_Lock7, _T("L7-") },
\r
145 { Modifier::Type_Lock8, _T("L8-") }, { Modifier::Type_Lock9, _T("L9-") },
\r
148 for (size_t i = 0; i < NUMBER_OF(mods); ++ i)
\r
149 if (!i_m.isDontcare(mods[i].m_mt) && i_m.isPressed(mods[i].m_mt))
\r
150 i_ost << mods[i].m_symbol;
\r
152 else if (!i_m.isDontcare(mods[i].m_mt) && i_m.isPressed(mods[i].m_mt))
\r
153 i_ost << _T("~") << mods[i].m_symbol;
\r
155 i_ost << _T("*") << mods[i].m_symbol;
\r
163 tostream &operator<<(tostream &i_ost, Modifier::Type i_type)
\r
165 const _TCHAR *modNames[] = {
\r
181 _T("MdiMaximized"),
\r
182 _T("MdiMinimized"),
\r
184 _T("TouchpadSticky"),
\r
207 int i = static_cast<int>(i_type);
\r
208 if (0 <= i && i < NUMBER_OF(modNames))
\r
209 i_ost << modNames[i];
\r
215 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
220 tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk)
\r
223 i_ost << i_mk.m_modifier << *i_mk.m_key;
\r
228 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
229 // Keyboard::KeyIterator
\r
232 Keyboard::KeyIterator::KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize)
\r
233 : m_hashedKeys(i_hashedKeys),
\r
234 m_hashedKeysSize(i_hashedKeysSize),
\r
235 m_i((*m_hashedKeys).begin())
\r
237 if ((*m_hashedKeys).empty()) {
\r
239 -- m_hashedKeysSize;
\r
241 } while (0 < m_hashedKeysSize && (*m_hashedKeys).empty());
\r
242 if (0 < m_hashedKeysSize)
\r
243 m_i = (*m_hashedKeys).begin();
\r
248 void Keyboard::KeyIterator::next()
\r
250 if (m_hashedKeysSize == 0)
\r
253 if (m_i == (*m_hashedKeys).end()) {
\r
255 -- m_hashedKeysSize;
\r
257 } while (0 < m_hashedKeysSize && (*m_hashedKeys).empty());
\r
258 if (0 < m_hashedKeysSize)
\r
259 m_i = (*m_hashedKeys).begin();
\r
264 Key *Keyboard::KeyIterator::operator *()
\r
266 if (m_hashedKeysSize == 0)
\r
272 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\r
276 Keyboard::Keys &Keyboard::getKeys(const Key &i_key)
\r
278 ASSERT(1 <= i_key.getScanCodesSize());
\r
279 return m_hashedKeys[i_key.getScanCodes()->m_scan % HASHED_KEYS_SIZE];
\r
284 void Keyboard::addKey(const Key &i_key)
\r
286 getKeys(i_key).push_front(i_key);
\r
290 // add a key name alias
\r
291 void Keyboard::addAlias(const tstringi &i_aliasName, Key *i_key)
\r
293 m_aliases.insert(Aliases::value_type(i_aliasName, i_key));
\r
297 void Keyboard::addSubstitute(const ModifiedKey &i_mkeyFrom,
\r
298 const ModifiedKey &i_mkeyTo)
\r
300 m_substitutes.push_front(Substitute(i_mkeyFrom, i_mkeyTo));
\r
304 // add a modifier key
\r
305 void Keyboard::addModifier(Modifier::Type i_mt, Key *i_key)
\r
307 ASSERT((int)i_mt < (int)Modifier::Type_BASIC);
\r
308 if (std::find(m_mods[i_mt].begin(), m_mods[i_mt].end(), i_key)
\r
309 != m_mods[i_mt].end())
\r
310 return; // already added
\r
311 m_mods[i_mt].push_back(i_key);
\r
316 Key *Keyboard::searchKey(const Key &i_key)
\r
318 Keys &keys = getKeys(i_key);
\r
319 for (Keys::iterator i = keys.begin(); i != keys.end(); ++ i)
\r
320 if ((*i).isSameScanCode(i_key))
\r
326 // search a key (of which the key's scan code is the prefix)
\r
327 Key *Keyboard::searchPrefixKey(const Key &i_key)
\r
329 Keys &keys = getKeys(i_key);
\r
330 for (Keys::iterator i = keys.begin(); i != keys.end(); ++ i)
\r
331 if ((*i).isPrefixScanCode(i_key))
\r
337 // search a key by name
\r
338 Key *Keyboard::searchKey(const tstringi &i_name)
\r
340 Aliases::iterator i = m_aliases.find(i_name);
\r
341 if (i != m_aliases.end())
\r
342 return (*i).second;
\r
343 return searchKeyByNonAliasName(i_name);
\r
347 // search a key by non-alias name
\r
348 Key *Keyboard::searchKeyByNonAliasName(const tstringi &i_name)
\r
350 for (int j = 0; j < HASHED_KEYS_SIZE; ++ j) {
\r
351 Keys &keys = m_hashedKeys[j];
\r
352 Keys::iterator i = std::find(keys.begin(), keys.end(), i_name);
\r
353 if (i != keys.end())
\r
359 /// search a substitute
\r
360 ModifiedKey Keyboard::searchSubstitute(const ModifiedKey &i_mkey)
\r
362 for (Substitutes::const_iterator
\r
363 i = m_substitutes.begin(); i != m_substitutes.end(); ++ i)
\r
364 if (i->m_mkeyFrom.m_key == i_mkey.m_key &&
\r
365 i->m_mkeyFrom.m_modifier.doesMatch(i_mkey.m_modifier))
\r
366 return i->m_mkeyTo;
\r
367 return ModifiedKey(); // not found (.m_mkey is NULL)
\r