/* * synergy -- mouse and keyboard sharing utility * Copyright (C) 2004 Chris Schoeneman * * This package is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * found in the file COPYING that should have accompanied this file. * * This package is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef COSXKEYSTATE_H #define COSXKEYSTATE_H #include "CKeyState.h" #include "stdmap.h" #include "stdvector.h" #include //! OS X key state /*! A key state for OS X. */ class COSXKeyState : public CKeyState { public: typedef std::vector CKeyIDs; COSXKeyState(); virtual ~COSXKeyState(); //! Map key event to keys /*! Converts a key event into a sequence of KeyIDs and the shadow modifier state to a modifier mask. The KeyIDs list, in order, the characters generated by the key press/release. It returns the id of the button that was pressed or released, or 0 if the button doesn't map to a known KeyID. */ KeyButton mapKeyFromEvent(CKeyIDs& ids, KeyModifierMask* maskOut, EventRef event) const; //! Handle modifier key change /*! Determines which modifier keys have changed and updates the modifier state and sends key events as appropriate. */ void handleModifierKeys(void* target, KeyModifierMask oldMask, KeyModifierMask newMask); // IKeyState overrides virtual void setHalfDuplexMask(KeyModifierMask); virtual bool fakeCtrlAltDel(); virtual const char* getKeyName(KeyButton) const; virtual void sendKeyEvent(void* target, bool press, bool isAutoRepeat, KeyID key, KeyModifierMask mask, SInt32 count, KeyButton button); protected: // IKeyState overrides virtual void doUpdateKeys(); virtual void doFakeKeyEvent(KeyButton button, bool press, bool isAutoRepeat); virtual KeyButton mapKey(Keystrokes& keys, KeyID id, KeyModifierMask desiredMask, bool isAutoRepeat) const; private: struct CKeyEventInfo { public: KeyButton m_button; KeyModifierMask m_requiredMask; KeyModifierMask m_requiredState; }; typedef std::vector CKeySequence; typedef std::map CKeyIDMap; typedef std::map CVirtualKeyMap; KeyButton addKeystrokes(Keystrokes& keys, KeyButton keyButton, KeyModifierMask desiredMask, KeyModifierMask requiredMask, bool isAutoRepeat) const; bool adjustModifiers(Keystrokes& keys, Keystrokes& undo, KeyModifierMask desiredMask, KeyModifierMask requiredMask) const; void addKeyButton(KeyButtons& keys, KeyID id) const; void handleModifierKey(void* target, KeyID id, bool down); // Check if the keyboard layout has changed and call doUpdateKeys // if so. void checkKeyboardLayout(); // Switch to a new keyboard layout. void setKeyboardLayout(SInt16 keyboardLayoutID); // Insert KeyID to key sequences for non-printing characters, like // delete, home, up arrow, etc. and the virtual key to KeyID mapping. void fillSpecialKeys(CKeyIDMap& keyMap, CVirtualKeyMap& virtualKeyMap) const; // Convert the KCHR resource to a KeyID to key sequence map. the // map maps each KeyID to the sequence of keys (with modifiers) // that would have to be synthesized to generate the KeyID character. // Returns false iff no KCHR resource was found. bool fillKCHRKeysMap(CKeyIDMap& keyMap) const; // Convert the uchr resource to a KeyID to key sequence map. the // map maps each KeyID to the sequence of keys (with modifiers) // that would have to be synthesized to generate the KeyID character. // Returns false iff no uchr resource was found. bool filluchrKeysMap(CKeyIDMap& keyMap) const; // Maps an OS X virtual key id to a KeyButton. This simply remaps // the ids so we don't use KeyButton 0. static KeyButton mapVirtualKeyToKeyButton(UInt32 keyCode); // Maps a KeyButton to an OS X key code. This is the inverse of // mapVirtualKeyToKeyButton. static UInt32 mapKeyButtonToVirtualKey(KeyButton keyButton); // Convert a character in the current script to the equivalent KeyID. static KeyID charToKeyID(UInt8); // Convert a unicode character to the equivalent KeyID. static KeyID unicharToKeyID(UniChar); // Choose the modifier mask with the fewest modifiers for character // mapping table i. static KeyModifierMask maskForTable(UInt8 i, UInt8* tableSelectors); private: // OS X uses a physical key if 0 for the 'A' key. synergy reserves // KeyButton 0 so we offset all OS X physical key ids by this much // when used as a KeyButton and by minus this much to map a KeyButton // to a physical button. enum { KeyButtonOffset = 1 }; // KCHR resource header struct CKCHRResource { public: SInt16 m_version; UInt8 m_tableSelectionIndex[256]; SInt16 m_numTables; UInt8 m_characterTables[1][128]; }; SInt16 m_keyboardLayoutID; mutable UInt32 m_deadKeyState; Handle m_KCHRHandle; Handle m_uchrHandle; CKCHRResource* m_KCHRResource; UCKeyboardLayout* m_uchrResource; CKeyIDMap m_keyMap; CVirtualKeyMap m_virtualKeyMap; }; #endif