CKeyMap.h

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2005 Chris Schoeneman
00004  * 
00005  * This package is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * found in the file COPYING that should have accompanied this file.
00008  * 
00009  * This package is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #ifndef CKEYMAP_H
00016 #define CKEYMAP_H
00017 
00018 #include "KeyTypes.h"
00019 #include "CString.h"
00020 #include "CStringUtil.h"
00021 #include "stdmap.h"
00022 #include "stdset.h"
00023 #include "stdvector.h"
00024 
00026 
00029 class CKeyMap {
00030 public:
00031     CKeyMap();
00032     ~CKeyMap();
00033 
00035 
00043     struct KeyItem {
00044     public:
00045         KeyID           m_id;           
00046         SInt32          m_group;        
00047         KeyButton       m_button;       
00048         KeyModifierMask m_required;     
00049         KeyModifierMask m_sensitive;    
00050         KeyModifierMask m_generates;    
00051         bool            m_dead;         
00052         bool            m_lock;         
00053         UInt32          m_client;       
00054 
00055     public:
00056         bool            operator==(const KeyItem&) const;
00057     };
00058 
00060 
00069     typedef std::vector<KeyItem> KeyItemList;
00070 
00072     class Keystroke {
00073     public:
00074         enum EType {
00075             kButton,                    
00076             kGroup                      
00077         };
00078 
00079         Keystroke(KeyButton, bool press, bool repeat, UInt32 clientData);
00080         Keystroke(SInt32 group, bool absolute, bool restore);
00081 
00082     public:
00083         struct CButton {
00084         public:
00085             KeyButton   m_button;       
00086             bool        m_press;        
00087             bool        m_repeat;       
00088             UInt32      m_client;       
00089         };
00090         struct CGroup {
00091         public:
00092             SInt32      m_group;        
00093             bool        m_absolute;     
00094             bool        m_restore;      
00095         };
00096         union CData {
00097         public:
00098             CButton     m_button;
00099             CGroup      m_group;
00100         };
00101 
00102         EType           m_type;
00103         CData           m_data;
00104     };
00105 
00107     typedef std::vector<Keystroke> Keystrokes;
00108 
00110     typedef std::multimap<KeyModifierMask, KeyItem> ModifierToKeys;
00111 
00113     typedef std::map<KeyButton, const KeyItem*> ButtonToKeyMap;
00114 
00116     typedef void (*ForeachKeyCallback)(KeyID, SInt32 group,
00117                             KeyItem&, void* userData);
00118 
00120 
00121 
00123     void                swap(CKeyMap&);
00124 
00126 
00130     void                addKeyEntry(const KeyItem& item);
00131 
00133 
00142     void                addKeyAliasEntry(KeyID targetID, SInt32 group,
00143                             KeyModifierMask targetRequired,
00144                             KeyModifierMask targetSensitive,
00145                             KeyID sourceID,
00146                             KeyModifierMask sourceRequired,
00147                             KeyModifierMask sourceSensitive);
00148 
00150 
00159     bool                addKeyCombinationEntry(KeyID id, SInt32 group,
00160                             const KeyID* keys, UInt32 numKeys);
00161 
00163 
00167     void                allowGroupSwitchDuringCompose();
00168 
00170 
00175     void                addHalfDuplexButton(KeyButton button);
00176 
00178 
00182     void                clearHalfDuplexModifiers();
00183 
00185 
00189     void                addHalfDuplexModifier(KeyID key);
00190 
00192 
00195     void                finish();
00196 
00198 
00201     void                foreachKey(ForeachKeyCallback cb, void* userData);
00202 
00204 
00205 
00206 
00208 
00215     const KeyItem*      mapKey(Keystrokes& keys, KeyID id, SInt32 group,
00216                             ModifierToKeys& activeModifiers,
00217                             KeyModifierMask& currentState,
00218                             KeyModifierMask desiredMask,
00219                             bool isAutoRepeat) const;
00220 
00222 
00225     SInt32              getNumGroups() const;
00226 
00228 
00231     SInt32              getEffectiveGroup(SInt32 group, SInt32 offset) const;
00232 
00234 
00242     const KeyItemList*  findCompatibleKey(KeyID id, SInt32 group,
00243                             KeyModifierMask required,
00244                             KeyModifierMask sensitive) const;
00245 
00247 
00251     bool                isHalfDuplex(KeyID key, KeyButton button) const;
00252 
00254 
00262     bool                isCommand(KeyModifierMask mask) const;
00263 
00264     // Get the modifiers that indicate a command
00269     KeyModifierMask     getCommandModifiers() const;
00270 
00272 
00275     static void         collectButtons(const ModifierToKeys& modifiers,
00276                             ButtonToKeyMap& keys);
00277 
00279 
00283     static void         initModifierKey(KeyItem& item);
00284 
00286 
00289     static bool         isDeadKey(KeyID key);
00290 
00292 
00296     static KeyID        getDeadKey(KeyID key);
00297 
00299 
00303     static CString      formatKey(KeyID key, KeyModifierMask);
00304 
00306 
00310     static bool         parseKey(const CString&, KeyID&);
00311 
00313 
00319     static bool         parseModifiers(CString&, KeyModifierMask&);
00320 
00322 
00323 private:
00325     enum EKeystroke {
00326         kKeystrokePress,        
00327         kKeystrokeRelease,      
00328         kKeystrokeRepeat,       
00329         kKeystrokeClick,        
00330         kKeystrokeModify,       
00331         kKeystrokeUnmodify      
00332     };
00333         
00334     // A list of ways to synthesize a KeyID
00335     typedef std::vector<KeyItemList> KeyEntryList;
00336 
00337     // computes the number of groups
00338     SInt32              findNumGroups() const;
00339 
00340     // computes the map of modifiers to the keys that generate the modifiers
00341     void                setModifierKeys();
00342 
00343     // maps a command key.  a command key is a keyboard shortcut and we're
00344     // trying to synthesize a button press with an exact sets of modifiers,
00345     // not trying to synthesize a character.  so we just need to find the
00346     // right button and synthesize the requested modifiers without regard
00347     // to what character they would synthesize.  we disallow multikey
00348     // entries since they don't make sense as hotkeys.
00349     const KeyItem*      mapCommandKey(Keystrokes& keys,
00350                             KeyID id, SInt32 group,
00351                             ModifierToKeys& activeModifiers,
00352                             KeyModifierMask& currentState,
00353                             KeyModifierMask desiredMask,
00354                             bool isAutoRepeat) const;
00355 
00356     // maps a character key.  a character key is trying to synthesize a
00357     // particular KeyID and isn't entirely concerned with the modifiers
00358     // used to do it.
00359     const KeyItem*      mapCharacterKey(Keystrokes& keys,
00360                             KeyID id, SInt32 group,
00361                             ModifierToKeys& activeModifiers,
00362                             KeyModifierMask& currentState,
00363                             KeyModifierMask desiredMask,
00364                             bool isAutoRepeat) const;
00365 
00366     // maps a modifier key
00367     const KeyItem*      mapModifierKey(Keystrokes& keys,
00368                             KeyID id, SInt32 group,
00369                             ModifierToKeys& activeModifiers,
00370                             KeyModifierMask& currentState,
00371                             KeyModifierMask desiredMask,
00372                             bool isAutoRepeat) const;
00373 
00374     // returns the index into \p entryList of the KeyItemList requiring
00375     // the fewest modifier changes between \p currentState and
00376     // \p desiredState.
00377     SInt32              findBestKey(const KeyEntryList& entryList,
00378                             KeyModifierMask currentState,
00379                             KeyModifierMask desiredState) const;
00380 
00381     // gets the \c KeyItem used to synthesize the modifier who's bit is
00382     // given by \p modifierBit in group \p group and does not synthesize
00383     // the key \p button.
00384     const KeyItem*      keyForModifier(KeyButton button, SInt32 group,
00385                             SInt32 modifierBit) const;
00386 
00387     // fills \p keystrokes with the keys to synthesize the key in
00388     // \p keyItem taking the modifiers into account.  returns \c true
00389     // iff successful and sets \p currentState to the
00390     // resulting modifier state.
00391     bool                keysForKeyItem(const KeyItem& keyItem,
00392                             SInt32& group,
00393                             ModifierToKeys& activeModifiers,
00394                             KeyModifierMask& currentState,
00395                             KeyModifierMask desiredState,
00396                             KeyModifierMask overrideModifiers,
00397                             bool isAutoRepeat,
00398                             Keystrokes& keystrokes) const;
00399 
00400     // fills \p keystrokes with the keys to synthesize the modifiers
00401     // in \p desiredModifiers from the active modifiers listed in
00402     // \p activeModifiers not including the key in \p keyItem.
00403     // returns \c true iff successful.
00404     bool                keysToRestoreModifiers(const KeyItem& keyItem,
00405                             SInt32 group,
00406                             ModifierToKeys& activeModifiers,
00407                             KeyModifierMask& currentState,
00408                             const ModifierToKeys& desiredModifiers,
00409                             Keystrokes& keystrokes) const;
00410 
00411     // fills \p keystrokes and \p undo with the keys to change the
00412     // current modifier state in \p currentState to match the state in
00413     // \p requiredState for each modifier indicated in \p sensitiveMask.
00414     // returns \c true iff successful and sets \p currentState to the
00415     // resulting modifier state.
00416     bool                keysForModifierState(KeyButton button, SInt32 group,
00417                             ModifierToKeys& activeModifiers,
00418                             KeyModifierMask& currentState,
00419                             KeyModifierMask requiredState,
00420                             KeyModifierMask sensitiveMask,
00421                             KeyModifierMask notRequiredMask,
00422                             Keystrokes& keystrokes) const;
00423 
00424     // Adds keystrokes to synthesize key \p keyItem in mode \p type to
00425     // \p keystrokes and to undo the synthesis to \p undo.
00426     void                addKeystrokes(EKeystroke type,
00427                             const KeyItem& keyItem,
00428                             ModifierToKeys& activeModifiers,
00429                             KeyModifierMask& currentState,
00430                             Keystrokes& keystrokes) const;
00431 
00432     // Returns the number of modifiers indicated in \p state.
00433     static SInt32       getNumModifiers(KeyModifierMask state);
00434 
00435     // Initialize key name/id maps
00436     static void         initKeyNameMaps();
00437 
00438     // not implemented
00439     CKeyMap(const CKeyMap&);
00440     CKeyMap&            operator=(const CKeyMap&);
00441 
00442 private:
00443     // Ways to synthesize a KeyID over multiple keyboard groups
00444     typedef std::vector<KeyEntryList> KeyGroupTable;
00445 
00446     // Table of KeyID to ways to synthesize that KeyID
00447     typedef std::map<KeyID, KeyGroupTable> KeyIDMap;
00448 
00449     // List of KeyItems that generate a particular modifier
00450     typedef std::vector<const KeyItem*> ModifierKeyItemList;
00451 
00452     // Map a modifier to the KeyItems that synthesize that modifier
00453     typedef std::vector<ModifierKeyItemList> ModifierToKeyTable;
00454 
00455     // A set of keys
00456     typedef std::set<KeyID> KeySet;
00457 
00458     // A set of buttons
00459     typedef std::set<KeyButton> KeyButtonSet;
00460 
00461     // Key maps for parsing/formatting
00462     typedef std::map<CString, KeyID,
00463                             CStringUtil::CaselessCmp> CNameToKeyMap;
00464     typedef std::map<CString, KeyModifierMask,
00465                             CStringUtil::CaselessCmp> CNameToModifierMap;
00466     typedef std::map<KeyID, CString> CKeyToNameMap;
00467     typedef std::map<KeyModifierMask, CString> CModifierToNameMap;
00468 
00469     // KeyID info
00470     KeyIDMap            m_keyIDMap;
00471     SInt32              m_numGroups;
00472     ModifierToKeyTable  m_modifierKeys;
00473 
00474     // composition info
00475     bool                m_composeAcrossGroups;
00476 
00477     // half-duplex info
00478     KeyButtonSet        m_halfDuplex;           // half-duplex set by synergy
00479     KeySet              m_halfDuplexMods;       // half-duplex set by user
00480 
00481     // dummy KeyItem for changing modifiers
00482     KeyItem             m_modifierKeyItem;
00483 
00484     // parsing/formatting tables
00485     static CNameToKeyMap*       s_nameToKeyMap;
00486     static CNameToModifierMap*  s_nameToModifierMap;
00487     static CKeyToNameMap*       s_keyToNameMap;
00488     static CModifierToNameMap*  s_modifierToNameMap;
00489 };
00490 
00491 #endif

Generated on Fri Nov 6 00:18:45 2009 for synergy-plus by  doxygen 1.4.7