barrier/lib/platform/COSXKeyState.h
crs 9f6c8f937a Made OS X key mapping dynamic based on current key layout. It
now includes full support for dead keys and non-ascii glyph keys.
2004-10-24 18:15:33 +00:00

160 lines
5.2 KiB
C++

/*
* 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 <Carbon/Carbon.h>
//! OS X key state
/*!
A key state for OS X.
*/
class COSXKeyState : public CKeyState {
public:
typedef std::vector<KeyID> 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:
typedef std::vector<std::pair<KeyButton, KeyModifierMask> > CKeySequence;
typedef std::map<KeyID, CKeySequence> CKeyIDMap;
typedef std::map<UInt32, KeyID> 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