2012-06-10 16:50:54 +00:00
|
|
|
/*
|
|
|
|
* synergy -- mouse and keyboard sharing utility
|
2014-11-02 12:12:05 +00:00
|
|
|
* Copyright (C) 2012 Synergy Si Ltd.
|
2012-09-04 02:09:56 +00:00
|
|
|
* Copyright (C) 2003 Chris Schoeneman
|
2012-06-10 16:50:54 +00:00
|
|
|
*
|
|
|
|
* This package is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
2015-05-03 02:33:52 +00:00
|
|
|
* found in the file LICENSE that should have accompanied this file.
|
2012-06-10 16:50:54 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2014-02-28 12:36:45 +00:00
|
|
|
#pragma once
|
|
|
|
|
2014-02-28 12:55:14 +00:00
|
|
|
#include "synergy/KeyState.h"
|
2014-02-28 12:36:45 +00:00
|
|
|
#include "common/stdmap.h"
|
|
|
|
#include "common/stdvector.h"
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
#if X_DISPLAY_MISSING
|
|
|
|
# error X11 is required to build synergy
|
|
|
|
#else
|
|
|
|
# include <X11/Xlib.h>
|
|
|
|
# if HAVE_X11_EXTENSIONS_XTEST_H
|
|
|
|
# include <X11/extensions/XTest.h>
|
|
|
|
# else
|
|
|
|
# error The XTest extension is required to build synergy
|
|
|
|
# endif
|
|
|
|
# if HAVE_XKB_EXTENSION
|
|
|
|
# include <X11/extensions/XKBstr.h>
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2013-06-29 22:02:04 +00:00
|
|
|
class IEventQueue;
|
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
//! X Windows key state
|
|
|
|
/*!
|
|
|
|
A key state for X Windows.
|
|
|
|
*/
|
2014-11-12 11:28:41 +00:00
|
|
|
class XWindowsKeyState : public KeyState {
|
2012-06-10 16:50:54 +00:00
|
|
|
public:
|
2014-11-11 13:51:47 +00:00
|
|
|
typedef std::vector<int> KeycodeList;
|
2012-06-10 16:50:54 +00:00
|
|
|
enum {
|
|
|
|
kGroupPoll = -1,
|
|
|
|
kGroupPollAndSet = -2
|
|
|
|
};
|
|
|
|
|
2014-11-12 11:28:41 +00:00
|
|
|
XWindowsKeyState(Display*, bool useXKB, IEventQueue* events);
|
|
|
|
XWindowsKeyState(Display*, bool useXKB,
|
2014-11-11 13:51:47 +00:00
|
|
|
IEventQueue* events, synergy::KeyMap& keyMap);
|
2014-11-12 11:28:41 +00:00
|
|
|
~XWindowsKeyState();
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
//! @name modifiers
|
|
|
|
//@{
|
|
|
|
|
|
|
|
//! Set active group
|
|
|
|
/*!
|
|
|
|
Sets the active group to \p group. This is the group returned by
|
|
|
|
\c pollActiveGroup(). If \p group is \c kGroupPoll then
|
|
|
|
\c pollActiveGroup() will really poll, but that's a slow operation
|
|
|
|
on X11. If \p group is \c kGroupPollAndSet then this will poll the
|
|
|
|
active group now and use it for future calls to \c pollActiveGroup().
|
|
|
|
*/
|
|
|
|
void setActiveGroup(SInt32 group);
|
|
|
|
|
|
|
|
//! Set the auto-repeat state
|
|
|
|
/*!
|
|
|
|
Sets the auto-repeat state.
|
|
|
|
*/
|
|
|
|
void setAutoRepeat(const XKeyboardState&);
|
|
|
|
|
|
|
|
//@}
|
|
|
|
//! @name accessors
|
|
|
|
//@{
|
|
|
|
|
|
|
|
//! Convert X modifier mask to synergy mask
|
|
|
|
/*!
|
|
|
|
Returns the synergy modifier mask corresponding to the X modifier
|
|
|
|
mask in \p state.
|
|
|
|
*/
|
|
|
|
KeyModifierMask mapModifiersFromX(unsigned int state) const;
|
|
|
|
|
|
|
|
//! Convert synergy modifier mask to X mask
|
|
|
|
/*!
|
|
|
|
Converts the synergy modifier mask to the corresponding X modifier
|
|
|
|
mask. Returns \c true if successful and \c false if any modifier
|
|
|
|
could not be converted.
|
|
|
|
*/
|
|
|
|
bool mapModifiersToX(KeyModifierMask, unsigned int&) const;
|
|
|
|
|
|
|
|
//! Convert synergy key to all corresponding X keycodes
|
|
|
|
/*!
|
|
|
|
Converts the synergy key \p key to all of the keycodes that map to
|
|
|
|
that key.
|
|
|
|
*/
|
|
|
|
void mapKeyToKeycodes(KeyID key,
|
2014-11-11 13:51:47 +00:00
|
|
|
KeycodeList& keycodes) const;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
//@}
|
|
|
|
|
|
|
|
// IKeyState overrides
|
|
|
|
virtual bool fakeCtrlAltDel();
|
|
|
|
virtual KeyModifierMask
|
|
|
|
pollActiveModifiers() const;
|
|
|
|
virtual SInt32 pollActiveGroup() const;
|
|
|
|
virtual void pollPressedKeys(KeyButtonSet& pressedKeys) const;
|
|
|
|
|
|
|
|
protected:
|
2014-11-11 13:51:47 +00:00
|
|
|
// KeyState overrides
|
|
|
|
virtual void getKeyMap(synergy::KeyMap& keyMap);
|
2012-06-10 16:50:54 +00:00
|
|
|
virtual void fakeKey(const Keystroke& keystroke);
|
|
|
|
|
|
|
|
private:
|
|
|
|
void init(Display* display, bool useXKB);
|
2014-11-11 13:51:47 +00:00
|
|
|
void updateKeysymMap(synergy::KeyMap&);
|
|
|
|
void updateKeysymMapXKB(synergy::KeyMap&);
|
2012-06-10 16:50:54 +00:00
|
|
|
bool hasModifiersXKB() const;
|
|
|
|
int getEffectiveGroup(KeyCode, int group) const;
|
|
|
|
UInt32 getGroupFromState(unsigned int state) const;
|
|
|
|
|
|
|
|
static void remapKeyModifiers(KeyID, SInt32,
|
2014-11-11 13:51:47 +00:00
|
|
|
synergy::KeyMap::KeyItem&, void*);
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
struct XKBModifierInfo {
|
|
|
|
public:
|
|
|
|
unsigned char m_level;
|
|
|
|
UInt32 m_mask;
|
|
|
|
bool m_lock;
|
|
|
|
};
|
|
|
|
|
2014-02-28 15:36:51 +00:00
|
|
|
#ifdef TEST_ENV
|
|
|
|
public: // yuck
|
|
|
|
#endif
|
2012-06-10 16:50:54 +00:00
|
|
|
typedef std::vector<KeyModifierMask> KeyModifierMaskList;
|
2014-02-28 15:36:51 +00:00
|
|
|
|
|
|
|
private:
|
2012-06-10 16:50:54 +00:00
|
|
|
typedef std::map<KeyModifierMask, unsigned int> KeyModifierToXMask;
|
|
|
|
typedef std::multimap<KeyID, KeyCode> KeyToKeyCodeMap;
|
|
|
|
typedef std::map<KeyCode, unsigned int> NonXKBModifierMap;
|
|
|
|
typedef std::map<UInt32, XKBModifierInfo> XKBModifierMap;
|
|
|
|
|
|
|
|
Display* m_display;
|
|
|
|
#if HAVE_XKB_EXTENSION
|
|
|
|
XkbDescPtr m_xkb;
|
|
|
|
#endif
|
|
|
|
SInt32 m_group;
|
|
|
|
XKBModifierMap m_lastGoodXKBModifiers;
|
|
|
|
NonXKBModifierMap m_lastGoodNonXKBModifiers;
|
|
|
|
|
|
|
|
// X modifier (bit number) to synergy modifier (mask) mapping
|
|
|
|
KeyModifierMaskList m_modifierFromX;
|
|
|
|
|
|
|
|
// synergy modifier (mask) to X modifier (mask)
|
|
|
|
KeyModifierToXMask m_modifierToX;
|
|
|
|
|
|
|
|
// map KeyID to all keycodes that can synthesize that KeyID
|
|
|
|
KeyToKeyCodeMap m_keyCodeFromKey;
|
|
|
|
|
|
|
|
// autorepeat state
|
|
|
|
XKeyboardState m_keyboardState;
|
2014-02-28 15:36:51 +00:00
|
|
|
|
|
|
|
#ifdef TEST_ENV
|
|
|
|
public:
|
|
|
|
SInt32 group() const { return m_group; }
|
|
|
|
void group(const SInt32& group) { m_group = group; }
|
|
|
|
KeyModifierMaskList modifierFromX() const { return m_modifierFromX; }
|
|
|
|
#endif
|
2012-06-10 16:50:54 +00:00
|
|
|
};
|