2004-03-21 20:01:41 +00:00
|
|
|
/*
|
|
|
|
* 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 CKEYSTATE_H
|
|
|
|
#define CKEYSTATE_H
|
|
|
|
|
|
|
|
#include "IKeyState.h"
|
|
|
|
#include "stdvector.h"
|
|
|
|
|
|
|
|
//! Core key state
|
|
|
|
/*!
|
|
|
|
This class provides key state services. Subclasses must implement a few
|
|
|
|
platform specific methods.
|
|
|
|
*/
|
|
|
|
class CKeyState : public IKeyState {
|
|
|
|
public:
|
|
|
|
CKeyState();
|
|
|
|
virtual ~CKeyState();
|
|
|
|
|
|
|
|
//! @name manipulators
|
|
|
|
//@{
|
|
|
|
|
|
|
|
//! Mark key as being down
|
|
|
|
/*!
|
2004-03-28 14:07:58 +00:00
|
|
|
Sets the state of \p button to down or up.
|
2004-03-21 20:01:41 +00:00
|
|
|
*/
|
2004-03-28 14:07:58 +00:00
|
|
|
void setKeyDown(KeyButton button, bool down);
|
2004-03-21 20:01:41 +00:00
|
|
|
|
|
|
|
//! Mark modifier as being toggled on
|
|
|
|
/*!
|
|
|
|
Sets the state of the keys for the given (single) \p modifier to be
|
|
|
|
toggled on.
|
|
|
|
*/
|
|
|
|
void setToggled(KeyModifierMask modifier);
|
|
|
|
|
|
|
|
//! Post a key event
|
|
|
|
/*!
|
|
|
|
Posts a key event. This may adjust the event or post additional
|
2004-03-26 20:59:26 +00:00
|
|
|
events in some circumstances. If this is overridden it must forward
|
|
|
|
to the superclass.
|
2004-03-21 20:01:41 +00:00
|
|
|
*/
|
2004-03-26 20:59:26 +00:00
|
|
|
virtual void sendKeyEvent(void* target,
|
2004-03-21 20:01:41 +00:00
|
|
|
bool press, bool isAutoRepeat,
|
|
|
|
KeyID key, KeyModifierMask mask,
|
|
|
|
SInt32 count, KeyButton button);
|
|
|
|
|
|
|
|
//@}
|
|
|
|
//! @name accessors
|
|
|
|
//@{
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
// IKeyState overrides
|
|
|
|
virtual void updateKeys();
|
|
|
|
virtual void setHalfDuplexMask(KeyModifierMask);
|
|
|
|
virtual void fakeKeyDown(KeyID id, KeyModifierMask mask,
|
|
|
|
KeyButton button);
|
|
|
|
virtual void fakeKeyRepeat(KeyID id, KeyModifierMask mask,
|
|
|
|
SInt32 count, KeyButton button);
|
|
|
|
virtual void fakeKeyUp(KeyButton button);
|
|
|
|
virtual void fakeToggle(KeyModifierMask modifier);
|
2004-03-26 20:59:26 +00:00
|
|
|
virtual bool fakeCtrlAltDel() = 0;
|
2004-03-21 20:01:41 +00:00
|
|
|
virtual bool isKeyDown(KeyButton) const;
|
|
|
|
virtual KeyModifierMask
|
|
|
|
getActiveModifiers() const;
|
|
|
|
virtual const char* getKeyName(KeyButton) const = 0;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
class Keystroke {
|
|
|
|
public:
|
|
|
|
KeyButton m_key;
|
|
|
|
bool m_press;
|
|
|
|
bool m_repeat;
|
|
|
|
};
|
|
|
|
typedef std::vector<Keystroke> Keystrokes;
|
|
|
|
typedef std::vector<KeyButton> KeyButtons;
|
|
|
|
|
|
|
|
//! @name protocted manipulators
|
|
|
|
//@{
|
|
|
|
|
|
|
|
//! Add keys for modifier
|
|
|
|
/*!
|
|
|
|
Sets the buttons that are mapped to the given (single) \p modifier. For
|
|
|
|
example, if buttons 5 and 23 were mapped to KeyModifierShift (perhaps
|
|
|
|
as left and right shift keys) then the mask would be KeyModifierShift
|
|
|
|
and \c buttons would contain 5 and 23. A modifier with no keys is
|
|
|
|
ignored. Buttons that are zero are ignored.
|
|
|
|
*/
|
|
|
|
void addModifier(KeyModifierMask modifier,
|
|
|
|
const KeyButtons& buttons);
|
|
|
|
|
|
|
|
//! Get key events to change modifier state
|
|
|
|
/*!
|
2004-10-24 18:18:01 +00:00
|
|
|
Retrieves the key events necessary to activate (\p desireActive is true)
|
|
|
|
or deactivate (\p desireActive is false) the modifier given by \p mask
|
|
|
|
by pushing them onto the back of \p keys. \p mask must specify exactly
|
|
|
|
one modifier. \p undo receives the key events necessary to restore the
|
|
|
|
modifier's previous state. They're pushed onto \p undo in the reverse
|
|
|
|
order they should be executed. If \p force is false then \p keys and
|
|
|
|
\p undo are only changed if the modifier is not currently in the
|
|
|
|
desired state. If \p force is true then \p keys and \p undo are always
|
|
|
|
changed. Returns true if the modifier can be adjusted, false otherwise.
|
2004-03-21 20:01:41 +00:00
|
|
|
*/
|
|
|
|
bool mapModifier(Keystrokes& keys, Keystrokes& undo,
|
2004-10-24 18:18:01 +00:00
|
|
|
KeyModifierMask mask, bool desireActive,
|
|
|
|
bool force = false) const;
|
2004-03-21 20:01:41 +00:00
|
|
|
|
|
|
|
//! Update the key state
|
|
|
|
/*!
|
|
|
|
Update the key state to reflect the physical keyboard state and
|
|
|
|
current keyboard mapping. This must call \c setKeyDown, \c setToggled,
|
|
|
|
and \c addModifier to set the current state.
|
|
|
|
*/
|
|
|
|
virtual void doUpdateKeys() = 0;
|
|
|
|
|
|
|
|
//! Fake a key event
|
|
|
|
/*!
|
|
|
|
Synthesize a key event for \p button. If \p press is true then
|
|
|
|
synthesize a key press and, if false, a key release. If
|
|
|
|
\p isAutoRepeat is true then the event is an auto-repeat.
|
|
|
|
*/
|
|
|
|
virtual void doFakeKeyEvent(KeyButton button,
|
|
|
|
bool press, bool isAutoRepeat) = 0;
|
|
|
|
|
|
|
|
//! Map key press/repeat to keystrokes
|
|
|
|
/*!
|
|
|
|
Converts a press/repeat of key \p id with the modifiers as given
|
|
|
|
in \p desiredMask into the keystrokes necessary to synthesize
|
|
|
|
that key event. Returns the platform specific code of the key
|
|
|
|
being pressed, or 0 if the key cannot be mapped or \p isAutoRepeat
|
|
|
|
is true and the key does not auto-repeat.
|
|
|
|
*/
|
|
|
|
virtual KeyButton mapKey(Keystrokes& keys, KeyID id,
|
|
|
|
KeyModifierMask desiredMask,
|
|
|
|
bool isAutoRepeat) const = 0;
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool isHalfDuplex(KeyModifierMask) const;
|
|
|
|
bool isToggle(KeyModifierMask) const;
|
|
|
|
bool isModifierActive(KeyModifierMask) const;
|
|
|
|
UInt32 getIndexForModifier(KeyModifierMask) const;
|
|
|
|
void fakeKeyEvents(const Keystrokes&, UInt32 count);
|
|
|
|
void fakeKeyEvent(KeyButton, bool press, bool isAutoRepeat);
|
|
|
|
void updateKeyState(KeyButton serverID,
|
2004-10-23 19:43:37 +00:00
|
|
|
KeyButton localID, bool press, bool fake);
|
2004-03-21 20:01:41 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
enum {
|
|
|
|
kNumModifiers = 9,
|
|
|
|
kButtonMask = kNumButtons - 1
|
|
|
|
};
|
|
|
|
typedef UInt8 KeyState;
|
|
|
|
enum EKeyState {
|
|
|
|
kDown = 0x01, //!< Key is down
|
|
|
|
kToggled = 0x02 //!< Key is toggled on
|
|
|
|
};
|
|
|
|
|
|
|
|
// modifiers that are half-duplex
|
|
|
|
KeyModifierMask m_halfDuplex;
|
|
|
|
|
|
|
|
// current modifier state
|
|
|
|
KeyModifierMask m_mask;
|
|
|
|
|
|
|
|
// current keyboard state
|
|
|
|
KeyState m_keys[kNumButtons];
|
|
|
|
|
|
|
|
// map from server button ID to local button ID for pressed keys
|
|
|
|
KeyButton m_serverKeyMap[kNumButtons];
|
|
|
|
|
|
|
|
// map button to the modifier mask it represents
|
|
|
|
KeyModifierMask m_keyToMask[kNumButtons];
|
|
|
|
|
|
|
|
// map modifier to buttons with that modifier
|
|
|
|
KeyButtons m_maskToKeys[kNumModifiers];
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|