• Main Page
  • Classes
  • Files
  • File List

CKeyMap.h

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2012 Bolton Software Ltd.
00004  * Copyright (C) 2005 Chris Schoeneman
00005  * 
00006  * This package is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * found in the file COPYING that should have accompanied this file.
00009  * 
00010  * This package is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #ifndef CKEYMAP_H
00020 #define CKEYMAP_H
00021 
00022 #include "KeyTypes.h"
00023 #include "CString.h"
00024 #include "CStringUtil.h"
00025 #include "stdmap.h"
00026 #include "stdset.h"
00027 #include "stdvector.h"
00028 
00030 
00033 class CKeyMap {
00034 public:
00035     CKeyMap();
00036     ~CKeyMap();
00037 
00039 
00047     struct KeyItem {
00048     public:
00049         KeyID           m_id;           
00050         SInt32          m_group;        
00051         KeyButton       m_button;       
00052         KeyModifierMask m_required;     
00053         KeyModifierMask m_sensitive;    
00054         KeyModifierMask m_generates;    
00055         bool            m_dead;         
00056         bool            m_lock;         
00057         UInt32          m_client;       
00058 
00059     public:
00060         bool            operator==(const KeyItem&) const;
00061     };
00062 
00064 
00073     typedef std::vector<KeyItem> KeyItemList;
00074 
00076     class Keystroke {
00077     public:
00078         enum EType {
00079             kButton,                    
00080             kGroup                      
00081         };
00082 
00083         Keystroke(KeyButton, bool press, bool repeat, UInt32 clientData);
00084         Keystroke(SInt32 group, bool absolute, bool restore);
00085 
00086     public:
00087         struct CButton {
00088         public:
00089             KeyButton   m_button;       
00090             bool        m_press;        
00091             bool        m_repeat;       
00092             UInt32      m_client;       
00093         };
00094         struct CGroup {
00095         public:
00096             SInt32      m_group;        
00097             bool        m_absolute;     
00098             bool        m_restore;      
00099         };
00100         union CData {
00101         public:
00102             CButton     m_button;
00103             CGroup      m_group;
00104         };
00105 
00106         EType           m_type;
00107         CData           m_data;
00108     };
00109 
00111     typedef std::vector<Keystroke> Keystrokes;
00112 
00114     typedef std::multimap<KeyModifierMask, KeyItem> ModifierToKeys;
00115 
00117     typedef std::map<KeyButton, const KeyItem*> ButtonToKeyMap;
00118 
00120     typedef void (*ForeachKeyCallback)(KeyID, SInt32 group,
00121                             KeyItem&, void* userData);
00122 
00124 
00125 
00127     virtual void        swap(CKeyMap&);
00128 
00130 
00134     void                addKeyEntry(const KeyItem& item);
00135 
00137 
00146     void                addKeyAliasEntry(KeyID targetID, SInt32 group,
00147                             KeyModifierMask targetRequired,
00148                             KeyModifierMask targetSensitive,
00149                             KeyID sourceID,
00150                             KeyModifierMask sourceRequired,
00151                             KeyModifierMask sourceSensitive);
00152 
00154 
00163     bool                addKeyCombinationEntry(KeyID id, SInt32 group,
00164                             const KeyID* keys, UInt32 numKeys);
00165 
00167 
00171     void                allowGroupSwitchDuringCompose();
00172 
00174 
00179     void                addHalfDuplexButton(KeyButton button);
00180 
00182 
00186     void                clearHalfDuplexModifiers();
00187 
00189 
00193     virtual void        addHalfDuplexModifier(KeyID key);
00194 
00196 
00199     virtual void        finish();
00200 
00202 
00205     virtual void        foreachKey(ForeachKeyCallback cb, void* userData);
00206 
00208 
00209 
00210 
00212 
00219     virtual const KeyItem*  mapKey(Keystrokes& keys, KeyID id, SInt32 group,
00220                             ModifierToKeys& activeModifiers,
00221                             KeyModifierMask& currentState,
00222                             KeyModifierMask desiredMask,
00223                             bool isAutoRepeat) const;
00224 
00226 
00229     SInt32              getNumGroups() const;
00230 
00232 
00235     SInt32              getEffectiveGroup(SInt32 group, SInt32 offset) const;
00236 
00238 
00246     const KeyItemList*  findCompatibleKey(KeyID id, SInt32 group,
00247                             KeyModifierMask required,
00248                             KeyModifierMask sensitive) const;
00249 
00251 
00255     virtual bool        isHalfDuplex(KeyID key, KeyButton button) const;
00256 
00258 
00266     bool                isCommand(KeyModifierMask mask) const;
00267 
00268     // Get the modifiers that indicate a command
00273     KeyModifierMask     getCommandModifiers() const;
00274 
00276 
00279     static void         collectButtons(const ModifierToKeys& modifiers,
00280                             ButtonToKeyMap& keys);
00281 
00283 
00287     static void         initModifierKey(KeyItem& item);
00288 
00290 
00293     static bool         isDeadKey(KeyID key);
00294 
00296 
00300     static KeyID        getDeadKey(KeyID key);
00301 
00303 
00307     static CString      formatKey(KeyID key, KeyModifierMask);
00308 
00310 
00314     static bool         parseKey(const CString&, KeyID&);
00315 
00317 
00323     static bool         parseModifiers(CString&, KeyModifierMask&);
00324 
00326 
00327 private:
00329     enum EKeystroke {
00330         kKeystrokePress,        
00331         kKeystrokeRelease,      
00332         kKeystrokeRepeat,       
00333         kKeystrokeClick,        
00334         kKeystrokeModify,       
00335         kKeystrokeUnmodify      
00336     };
00337         
00338     // A list of ways to synthesize a KeyID
00339     typedef std::vector<KeyItemList> KeyEntryList;
00340 
00341     // computes the number of groups
00342     SInt32              findNumGroups() const;
00343 
00344     // computes the map of modifiers to the keys that generate the modifiers
00345     void                setModifierKeys();
00346 
00347     // maps a command key.  a command key is a keyboard shortcut and we're
00348     // trying to synthesize a button press with an exact sets of modifiers,
00349     // not trying to synthesize a character.  so we just need to find the
00350     // right button and synthesize the requested modifiers without regard
00351     // to what character they would synthesize.  we disallow multikey
00352     // entries since they don't make sense as hotkeys.
00353     const KeyItem*      mapCommandKey(Keystrokes& keys,
00354                             KeyID id, SInt32 group,
00355                             ModifierToKeys& activeModifiers,
00356                             KeyModifierMask& currentState,
00357                             KeyModifierMask desiredMask,
00358                             bool isAutoRepeat) const;
00359 
00360     // maps a character key.  a character key is trying to synthesize a
00361     // particular KeyID and isn't entirely concerned with the modifiers
00362     // used to do it.
00363     const KeyItem*      mapCharacterKey(Keystrokes& keys,
00364                             KeyID id, SInt32 group,
00365                             ModifierToKeys& activeModifiers,
00366                             KeyModifierMask& currentState,
00367                             KeyModifierMask desiredMask,
00368                             bool isAutoRepeat) const;
00369 
00370     // maps a modifier key
00371     const KeyItem*      mapModifierKey(Keystrokes& keys,
00372                             KeyID id, SInt32 group,
00373                             ModifierToKeys& activeModifiers,
00374                             KeyModifierMask& currentState,
00375                             KeyModifierMask desiredMask,
00376                             bool isAutoRepeat) const;
00377 
00378     // returns the index into \p entryList of the KeyItemList requiring
00379     // the fewest modifier changes between \p currentState and
00380     // \p desiredState.
00381     SInt32              findBestKey(const KeyEntryList& entryList,
00382                             KeyModifierMask currentState,
00383                             KeyModifierMask desiredState) const;
00384 
00385     // gets the \c KeyItem used to synthesize the modifier who's bit is
00386     // given by \p modifierBit in group \p group and does not synthesize
00387     // the key \p button.
00388     const KeyItem*      keyForModifier(KeyButton button, SInt32 group,
00389                             SInt32 modifierBit) const;
00390 
00391     // fills \p keystrokes with the keys to synthesize the key in
00392     // \p keyItem taking the modifiers into account.  returns \c true
00393     // iff successful and sets \p currentState to the
00394     // resulting modifier state.
00395     bool                keysForKeyItem(const KeyItem& keyItem,
00396                             SInt32& group,
00397                             ModifierToKeys& activeModifiers,
00398                             KeyModifierMask& currentState,
00399                             KeyModifierMask desiredState,
00400                             KeyModifierMask overrideModifiers,
00401                             bool isAutoRepeat,
00402                             Keystrokes& keystrokes) const;
00403 
00404     // fills \p keystrokes with the keys to synthesize the modifiers
00405     // in \p desiredModifiers from the active modifiers listed in
00406     // \p activeModifiers not including the key in \p keyItem.
00407     // returns \c true iff successful.
00408     bool                keysToRestoreModifiers(const KeyItem& keyItem,
00409                             SInt32 group,
00410                             ModifierToKeys& activeModifiers,
00411                             KeyModifierMask& currentState,
00412                             const ModifierToKeys& desiredModifiers,
00413                             Keystrokes& keystrokes) const;
00414 
00415     // fills \p keystrokes and \p undo with the keys to change the
00416     // current modifier state in \p currentState to match the state in
00417     // \p requiredState for each modifier indicated in \p sensitiveMask.
00418     // returns \c true iff successful and sets \p currentState to the
00419     // resulting modifier state.
00420     bool                keysForModifierState(KeyButton button, SInt32 group,
00421                             ModifierToKeys& activeModifiers,
00422                             KeyModifierMask& currentState,
00423                             KeyModifierMask requiredState,
00424                             KeyModifierMask sensitiveMask,
00425                             KeyModifierMask notRequiredMask,
00426                             Keystrokes& keystrokes) const;
00427 
00428     // Adds keystrokes to synthesize key \p keyItem in mode \p type to
00429     // \p keystrokes and to undo the synthesis to \p undo.
00430     void                addKeystrokes(EKeystroke type,
00431                             const KeyItem& keyItem,
00432                             ModifierToKeys& activeModifiers,
00433                             KeyModifierMask& currentState,
00434                             Keystrokes& keystrokes) const;
00435 
00436     // Returns the number of modifiers indicated in \p state.
00437     static SInt32       getNumModifiers(KeyModifierMask state);
00438 
00439     // Initialize key name/id maps
00440     static void         initKeyNameMaps();
00441 
00442     // not implemented
00443     CKeyMap(const CKeyMap&);
00444     CKeyMap&            operator=(const CKeyMap&);
00445 
00446 private:
00447     // Ways to synthesize a KeyID over multiple keyboard groups
00448     typedef std::vector<KeyEntryList> KeyGroupTable;
00449 
00450     // Table of KeyID to ways to synthesize that KeyID
00451     typedef std::map<KeyID, KeyGroupTable> KeyIDMap;
00452 
00453     // List of KeyItems that generate a particular modifier
00454     typedef std::vector<const KeyItem*> ModifierKeyItemList;
00455 
00456     // Map a modifier to the KeyItems that synthesize that modifier
00457     typedef std::vector<ModifierKeyItemList> ModifierToKeyTable;
00458 
00459     // A set of keys
00460     typedef std::set<KeyID> KeySet;
00461 
00462     // A set of buttons
00463     typedef std::set<KeyButton> KeyButtonSet;
00464 
00465     // Key maps for parsing/formatting
00466     typedef std::map<CString, KeyID,
00467                             CStringUtil::CaselessCmp> CNameToKeyMap;
00468     typedef std::map<CString, KeyModifierMask,
00469                             CStringUtil::CaselessCmp> CNameToModifierMap;
00470     typedef std::map<KeyID, CString> CKeyToNameMap;
00471     typedef std::map<KeyModifierMask, CString> CModifierToNameMap;
00472 
00473     // KeyID info
00474     KeyIDMap            m_keyIDMap;
00475     SInt32              m_numGroups;
00476     ModifierToKeyTable  m_modifierKeys;
00477 
00478     // composition info
00479     bool                m_composeAcrossGroups;
00480 
00481     // half-duplex info
00482     KeyButtonSet        m_halfDuplex;           // half-duplex set by synergy
00483     KeySet              m_halfDuplexMods;       // half-duplex set by user
00484 
00485     // dummy KeyItem for changing modifiers
00486     KeyItem             m_modifierKeyItem;
00487 
00488     // parsing/formatting tables
00489     static CNameToKeyMap*       s_nameToKeyMap;
00490     static CNameToModifierMap*  s_nameToModifierMap;
00491     static CKeyToNameMap*       s_keyToNameMap;
00492     static CModifierToNameMap*  s_modifierToNameMap;
00493 };
00494 
00495 #endif

Generated on Wed May 22 2013 00:00:05 for Synergy by  doxygen 1.7.1