OSDN Git Service

append dependency to mayu-common.mak
[yamy/yamy.git] / keyboard.h
1 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 // keyboard.h
3
4
5 #ifndef _KEYBOARD_H
6 #  define _KEYBOARD_H
7
8 #  include "misc.h"
9 #  include "driver.h"
10 #  include "stringtool.h"
11 #  include <vector>
12 #  include <list>
13 #  include <map>
14
15
16 /// a scan code with flags
17 class ScanCode
18 {
19 public:
20   ///
21   enum
22   {
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
27   };
28
29 public:
30   USHORT m_scan;                                ///
31   USHORT m_flags;                               ///
32
33 public:
34   ///
35   ScanCode() : m_scan(0), m_flags(0) { }
36   ///
37   ScanCode(USHORT i_scan, USHORT i_flags)
38     : m_scan(i_scan), m_flags(i_flags) { }
39   ///
40   bool operator==(const ScanCode &i_sc) const
41   {
42     return (m_scan == i_sc.m_scan &&
43             (E0E1 & m_flags) == (E0E1 & i_sc.m_flags));
44   }
45   ///
46   bool operator!=(const ScanCode &i_sc) const { return !(*this == i_sc); }
47 };
48
49
50 /// a key
51 class Key
52 {
53 public:
54   enum
55   {
56     ///
57     MAX_SCAN_CODES_SIZE = 4,
58   };
59
60 private:
61   ///
62   typedef std::vector<tstringi> Names;
63
64 public:
65   /// if this key pressed physically
66   bool m_isPressed;
67   /// if this key pressed on Win32
68   bool m_isPressedOnWin32;
69   /// if this key pressed by assign
70   bool m_isPressedByAssign;
71
72 private:
73   /// key name
74   Names m_names;
75   /// key scan code length
76   size_t m_scanCodesSize;
77   /// key scan code
78   ScanCode m_scanCodes[MAX_SCAN_CODES_SIZE];
79
80 public:
81   ///
82   Key()
83     : m_isPressed(false),
84       m_isPressedOnWin32(false),
85       m_isPressedByAssign(false),
86       m_scanCodesSize(0)
87   { }
88
89   /// for Event::* only
90   Key(const tstringi &i_name)
91     : m_isPressed(false),
92       m_isPressedOnWin32(false),
93       m_isPressedByAssign(false),
94       m_scanCodesSize(0)
95   {
96     addName(i_name);
97     addScanCode(ScanCode());
98   }
99
100   /// get key name (first name)
101   const tstringi &getName() const { return m_names.front(); }
102
103   /// get scan codes
104   const ScanCode *getScanCodes() const { return m_scanCodes; }
105   ///
106   size_t getScanCodesSize() const { return m_scanCodesSize; }
107   
108   /// add a name of key
109   void addName(const tstringi &i_name);
110   
111   /// add a scan code
112   void addScanCode(const ScanCode &i_sc);
113   
114   /// initializer
115   Key &initialize();
116   
117   /// equation by name
118   bool operator==(const tstringi &i_name) const;
119   ///
120   bool operator!=(const tstringi &i_name) const
121   { return !(*this == i_name); }
122   
123   /// is the scan code of this key ?
124   bool isSameScanCode(const Key &i_key) const;
125   
126   /// is the i_key's scan code the prefix of this key's scan code ?
127   bool isPrefixScanCode(const Key &i_key) const;
128   
129   /// stream output
130   friend tostream &operator<<(tostream &i_ost, const Key &i_key);
131   
132   /// < 
133   bool operator<(const Key &i_key) const
134   { return getName() < i_key.getName(); }
135 };
136
137
138 ///
139 class Modifier
140 {
141   ///
142   typedef u_int64 MODIFIERS;
143   ///
144   MODIFIERS m_modifiers;
145   ///
146   MODIFIERS m_dontcares;
147   
148 public:
149   ///
150   enum Type
151   {
152     Type_begin = 0,                             ///
153
154     Type_Shift = Type_begin,                    /// &lt;BASIC_MODIFIER&gt;
155     Type_Alt,                                   /// &lt;BASIC_MODIFIER&gt;
156     Type_Control,                               /// &lt;BASIC_MODIFIER&gt;
157     Type_Windows,                               /// &lt;BASIC_MODIFIER&gt;
158     Type_BASIC,                                 ///
159     
160     Type_Up = Type_BASIC,                       /// &lt;KEYSEQ_MODIFIER&gt;
161     Type_Down,                                  /// &lt;KEYSEQ_MODIFIER&gt;
162     Type_KEYSEQ,                                ///
163
164     Type_Repeat = Type_KEYSEQ,                  /// &lt;ASSIGN_MODIFIER&gt;
165     Type_ImeLock,                               /// &lt;ASSIGN_MODIFIER&gt;
166     Type_ImeComp,                               /// &lt;ASSIGN_MODIFIER&gt;
167     Type_NumLock,                               /// &lt;ASSIGN_MODIFIER&gt;
168     Type_CapsLock,                              /// &lt;ASSIGN_MODIFIER&gt;
169     Type_ScrollLock,                            /// &lt;ASSIGN_MODIFIER&gt;
170     Type_KanaLock,                              /// &lt;ASSIGN_MODIFIER&gt;
171     Type_Maximized,                             /// &lt;ASSIGN_MODIFIER&gt;
172     Type_Minimized,                             /// &lt;ASSIGN_MODIFIER&gt;
173     Type_MdiMaximized,                          /// &lt;ASSIGN_MODIFIER&gt;
174     Type_MdiMinimized,                          /// &lt;ASSIGN_MODIFIER&gt;
175     Type_Touchpad,                              /// &lt;ASSIGN_MODIFIER&gt;
176     Type_TouchpadSticky,                        /// &lt;ASSIGN_MODIFIER&gt;
177     Type_Mod0,                                  /// &lt;ASSIGN_MODIFIER&gt;
178     Type_Mod1,                                  /// &lt;ASSIGN_MODIFIER&gt;
179     Type_Mod2,                                  /// &lt;ASSIGN_MODIFIER&gt;
180     Type_Mod3,                                  /// &lt;ASSIGN_MODIFIER&gt;
181     Type_Mod4,                                  /// &lt;ASSIGN_MODIFIER&gt;
182     Type_Mod5,                                  /// &lt;ASSIGN_MODIFIER&gt;
183     Type_Mod6,                                  /// &lt;ASSIGN_MODIFIER&gt;
184     Type_Mod7,                                  /// &lt;ASSIGN_MODIFIER&gt;
185     Type_Mod8,                                  /// &lt;ASSIGN_MODIFIER&gt;
186     Type_Mod9,                                  /// &lt;ASSIGN_MODIFIER&gt;
187     Type_Lock0,                                 /// &lt;ASSIGN_MODIFIER&gt;
188     Type_Lock1,                                 /// &lt;ASSIGN_MODIFIER&gt;
189     Type_Lock2,                                 /// &lt;ASSIGN_MODIFIER&gt;
190     Type_Lock3,                                 /// &lt;ASSIGN_MODIFIER&gt;
191     Type_Lock4,                                 /// &lt;ASSIGN_MODIFIER&gt;
192     Type_Lock5,                                 /// &lt;ASSIGN_MODIFIER&gt;
193     Type_Lock6,                                 /// &lt;ASSIGN_MODIFIER&gt;
194     Type_Lock7,                                 /// &lt;ASSIGN_MODIFIER&gt;
195     Type_Lock8,                                 /// &lt;ASSIGN_MODIFIER&gt;
196     Type_Lock9,                                 /// &lt;ASSIGN_MODIFIER&gt;
197     Type_ASSIGN,                                ///
198
199     Type_end = Type_ASSIGN                      ///
200   };
201   
202 public:
203   ///
204   Modifier();
205   ///
206   Modifier &on(Type i_type) { return press(i_type); }
207   ///
208   Modifier &off(Type i_type) { return release(i_type); }
209   ///
210   Modifier &press(Type i_type)
211   { m_modifiers |= ((MODIFIERS(1)) << i_type); return care(i_type); }
212   ///
213   Modifier &release(Type i_type)
214   { m_modifiers &= ~((MODIFIERS(1)) << i_type); return care(i_type); }
215   ///
216   Modifier &care(Type i_type)
217   { m_dontcares &= ~((MODIFIERS(1)) << i_type); return *this; }
218   ///
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; }
223
224   ///
225   Modifier &on(Type i_type, bool i_isOn) { return press(i_type, i_isOn); }
226   ///
227   Modifier &press(Type i_type, bool i_isPressed)
228   { return i_isPressed ? press(i_type) : release(i_type); }
229   ///
230   Modifier &care(Type i_type, bool i_doCare)
231   { return i_doCare ? care(i_type) : dontcare(i_type); }
232   
233   ///
234   bool operator==(const Modifier &i_m) const
235   { return m_modifiers == i_m.m_modifiers && m_dontcares == i_m.m_dontcares; }
236
237   /// add m's modifiers where this dontcare
238   void add(const Modifier &i_m);
239   //Modifier &operator+=(const Modifier &i_m);
240
241   /** does match. (except dontcare modifiers) (is the m included in the *this
242       set ?) */
243   bool doesMatch(const Modifier &i_m) const
244   { return ((m_modifiers | m_dontcares) == (i_m.m_modifiers | m_dontcares)); }
245   
246   ///
247   bool isOn(Type i_type) const { return isPressed(i_type); }
248   ///
249   bool isPressed(Type i_type) const
250   { return !!(m_modifiers & ((MODIFIERS(1)) << i_type)); }
251   ///
252   bool isDontcare(Type i_type) const
253   { return !!(m_dontcares & ((MODIFIERS(1)) << i_type)); }
254
255   /// stream output
256   friend tostream &operator<<(tostream &i_ost, const Modifier &i_m);
257   
258   /// < 
259   bool operator<(const Modifier &i_m) const
260   {
261     return m_modifiers < i_m.m_modifiers ||
262       (m_modifiers == i_m.m_modifiers && m_dontcares < i_m.m_dontcares);
263   }
264 };
265
266
267 /// stream output
268 tostream &operator<<(tostream &i_ost, Modifier::Type i_type);
269
270
271 ///
272 class ModifiedKey
273 {
274 public:
275   Modifier m_modifier;  ///
276   Key *m_key;           ///
277   
278 public:
279   ///
280   ModifiedKey() : m_key(NULL) { }
281   ///
282   ModifiedKey(Key *i_key) : m_key(i_key) { }
283   ///
284   ModifiedKey(const Modifier &i_modifier, Key *i_key)
285     : m_modifier(i_modifier), m_key(i_key) { }
286   ///
287   bool operator==(const ModifiedKey &i_mk) const
288   { return m_modifier == i_mk.m_modifier && m_key == i_mk.m_key; }
289   ///
290   bool operator!=(const ModifiedKey &i_mk) const
291   { return !operator==(i_mk); }
292   
293   /// stream output
294   friend tostream &operator<<(tostream &i_ost, const ModifiedKey &i_mk);
295
296   /// < 
297   bool operator<(const ModifiedKey &i_mk) const
298   {
299     return *m_key < *i_mk.m_key ||
300       (!(*i_mk.m_key < *m_key) && m_modifier < i_mk.m_modifier);
301   }
302 };
303
304
305 ///
306 class Keyboard
307 {
308 public:
309   /// keyboard modifiers (pointer into Keys)
310   typedef std::list<Key *> Mods;
311
312 private:
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.  */
317   enum {
318     HASHED_KEYS_SIZE = 128,                     ///
319   };
320   typedef std::list<Key> Keys;                  ///
321   typedef std::map<tstringi, Key *> Aliases;    /// key name aliases
322   ///
323   class Substitute
324   {
325   public:
326     ModifiedKey m_mkeyFrom;
327     ModifiedKey m_mkeyTo;
328   public:
329     Substitute(const ModifiedKey &i_mkeyFrom,
330                const ModifiedKey &i_mkeyTo)
331       : m_mkeyFrom(i_mkeyFrom), m_mkeyTo(i_mkeyTo)
332     {
333     }
334   };
335   typedef std::list<Substitute> Substitutes;    /// substitutes
336
337 private:
338   Keys m_hashedKeys[HASHED_KEYS_SIZE];          ///
339   Aliases m_aliases;                            ///
340   Substitutes m_substitutes;                    /// 
341   Key m_syncKey;                                /// key used to synchronize
342   
343 private:
344   ///
345   Mods m_mods[Modifier::Type_BASIC];
346
347 public:
348   ///
349   class KeyIterator
350   {
351     ///
352     Keys *m_hashedKeys;
353     ///
354     size_t m_hashedKeysSize;
355     ///
356     Keys::iterator m_i;
357     
358     ///
359     void next();
360     
361   public:
362     ///
363     KeyIterator(Keys *i_hashedKeys, size_t i_hashedKeysSize);
364     ///
365     Key *operator *();
366     ///
367     void operator++() { next(); }
368   };
369   
370 private:
371   ///
372   Keys &getKeys(const Key &i_key);
373
374 public:
375   /// add a key
376   void addKey(const Key &i_key);
377
378   /// add a key name alias
379   void addAlias(const tstringi &i_aliasName, Key *i_key);
380   
381   /// add substitute
382   void addSubstitute(const ModifiedKey &i_mkeyFrom,
383                      const ModifiedKey &i_mkeyTo);
384   
385   /// get a sync key
386   Key *getSyncKey() { return &m_syncKey; }
387   
388   /// add a modifier key
389   void addModifier(Modifier::Type i_mt, Key * i_key);
390   
391   /// search a key
392   Key *searchKey(const Key &i_key);
393   
394   /// search a key (of which the key's scan code is the prefix)
395   Key *searchPrefixKey(const Key &i_key);
396   
397   /// search a key by name
398   Key *searchKey(const tstringi &i_name);
399
400   /// search a key by non-alias name
401   Key *searchKeyByNonAliasName(const tstringi &i_name);
402
403   /// search a substitute
404   ModifiedKey searchSubstitute(const ModifiedKey &i_mkey);
405
406   /// get modifiers
407   Mods &getModifiers(Modifier::Type i_mt) { return m_mods[i_mt]; }
408
409   /// get key iterator
410   KeyIterator getKeyIterator()
411   { return KeyIterator(&m_hashedKeys[0], HASHED_KEYS_SIZE); }
412 };
413
414
415 #endif // !_KEYBOARD_H