Changed how key state is tracked on X11. Now updating key state

on every key press and release so we don't have to updateKeys()
in isLockedToScreen().  However, if any key appears to be down
we still call updateKeys() to double check that it's really down.
If not we note the spurious lock and don't lock to the screen.
This commit is contained in:
crs 2004-03-14 17:55:53 +00:00
parent 6f19fcfe39
commit 20ba10bfa8
11 changed files with 382 additions and 310 deletions

View File

@ -173,21 +173,21 @@ CXWindowsKeyMapper::update(Display* display, IKeyState* keyState)
// transfer to our state // transfer to our state
for (UInt32 i = 0, j = 0; i < 32; j += 8, ++i) { for (UInt32 i = 0, j = 0; i < 32; j += 8, ++i) {
if ((keys[i] & 0x01) != 0) if ((keys[i] & 0x01) != 0)
keyState->setKeyDown(j + 0); keyState->setKeyDown(j + 0, true);
if ((keys[i] & 0x02) != 0) if ((keys[i] & 0x02) != 0)
keyState->setKeyDown(j + 1); keyState->setKeyDown(j + 1, true);
if ((keys[i] & 0x04) != 0) if ((keys[i] & 0x04) != 0)
keyState->setKeyDown(j + 2); keyState->setKeyDown(j + 2, true);
if ((keys[i] & 0x08) != 0) if ((keys[i] & 0x08) != 0)
keyState->setKeyDown(j + 3); keyState->setKeyDown(j + 3, true);
if ((keys[i] & 0x10) != 0) if ((keys[i] & 0x10) != 0)
keyState->setKeyDown(j + 4); keyState->setKeyDown(j + 4, true);
if ((keys[i] & 0x20) != 0) if ((keys[i] & 0x20) != 0)
keyState->setKeyDown(j + 5); keyState->setKeyDown(j + 5, true);
if ((keys[i] & 0x40) != 0) if ((keys[i] & 0x40) != 0)
keyState->setKeyDown(j + 6); keyState->setKeyDown(j + 6, true);
if ((keys[i] & 0x80) != 0) if ((keys[i] & 0x80) != 0)
keyState->setKeyDown(j + 7); keyState->setKeyDown(j + 7, true);
} }
// set toggle modifier states // set toggle modifier states

View File

@ -184,8 +184,8 @@ CXWindowsScreen::CXWindowsScreen(bool isPrimary) :
// install event handlers // install event handlers
EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(), EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(),
new TMethodEventJob<CXWindowsScreen>(this, new TMethodEventJob<IPlatformScreen>(this,
&CXWindowsScreen::handleSystemEvent)); &IPlatformScreen::handleSystemEvent));
// install the platform event queue // install the platform event queue
EVENTQUEUE->adoptBuffer(new CXWindowsEventQueueBuffer(m_display, m_window)); EVENTQUEUE->adoptBuffer(new CXWindowsEventQueueBuffer(m_display, m_window));
@ -244,6 +244,9 @@ CXWindowsScreen::enable()
// warp the mouse to the cursor center // warp the mouse to the cursor center
fakeMouseMove(m_xCenter, m_yCenter); fakeMouseMove(m_xCenter, m_yCenter);
} }
else {
m_keyState->updateKeys();
}
} }
void void
@ -544,6 +547,21 @@ CXWindowsScreen::isAnyMouseButtonDown() const
return false; return false;
} }
KeyModifierMask
CXWindowsScreen::getActiveModifiers() const
{
// query the pointer to get the modifier state
Window root, window;
int xRoot, yRoot, xWindow, yWindow;
unsigned int state;
if (XQueryPointer(m_display, m_root, &root, &window,
&xRoot, &yRoot, &xWindow, &yWindow, &state)) {
return m_keyMapper.mapModifier(state);
}
return 0;
}
void void
CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const
{ {
@ -841,12 +859,49 @@ CXWindowsScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id)
sendEvent(type, info); sendEvent(type, info);
} }
Bool
CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg)
{
CKeyEventFilter* filter = reinterpret_cast<CKeyEventFilter*>(arg);
return (xevent->type == filter->m_event &&
xevent->xkey.window == filter->m_window &&
xevent->xkey.time == filter->m_time &&
xevent->xkey.keycode == filter->m_keycode) ? True : False;
}
void void
CXWindowsScreen::handleSystemEvent(const CEvent& event, void*) CXWindowsScreen::handleSystemEvent(const CEvent& event, void*)
{ {
XEvent* xevent = reinterpret_cast<XEvent*>(event.getData()); XEvent* xevent = reinterpret_cast<XEvent*>(event.getData());
assert(xevent != NULL); assert(xevent != NULL);
// update key state
bool isRepeat = false;
if (m_isPrimary) {
if (xevent->type == KeyRelease) {
// check if this is a key repeat by getting the next
// KeyPress event that has the same key and time as
// this release event, if any. first prepare the
// filter info.
CKeyEventFilter filter;
filter.m_event = KeyPress;
filter.m_window = xevent->xkey.window;
filter.m_time = xevent->xkey.time;
filter.m_keycode = xevent->xkey.keycode;
XEvent xevent2;
isRepeat = (XCheckIfEvent(m_display, &xevent2,
&CXWindowsScreen::findKeyEvent,
(XPointer)&filter) == True);
}
if (xevent->type == KeyPress || xevent->type == KeyRelease) {
if (!isRepeat) {
m_keyState->setKeyDown(xevent->xkey.keycode,
xevent->type == KeyPress);
}
}
}
// let input methods try to handle event first // let input methods try to handle event first
if (m_ic != NULL) { if (m_ic != NULL) {
// XFilterEvent() may eat the event and generate a new KeyPress // XFilterEvent() may eat the event and generate a new KeyPress
@ -977,7 +1032,7 @@ CXWindowsScreen::handleSystemEvent(const CEvent& event, void*)
case KeyRelease: case KeyRelease:
if (m_isPrimary) { if (m_isPrimary) {
onKeyRelease(xevent->xkey); onKeyRelease(xevent->xkey, isRepeat);
} }
return; return;
@ -1037,41 +1092,12 @@ CXWindowsScreen::onKeyPress(XKeyEvent& xkey)
} }
} }
Bool
CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg)
{
CKeyEventFilter* filter = reinterpret_cast<CKeyEventFilter*>(arg);
return (xevent->type == filter->m_event &&
xevent->xkey.window == filter->m_window &&
xevent->xkey.time == filter->m_time &&
xevent->xkey.keycode == filter->m_keycode) ? True : False;
}
void void
CXWindowsScreen::onKeyRelease(XKeyEvent& xkey) CXWindowsScreen::onKeyRelease(XKeyEvent& xkey, bool isRepeat)
{ {
const KeyModifierMask mask = m_keyMapper.mapModifier(xkey.state); const KeyModifierMask mask = m_keyMapper.mapModifier(xkey.state);
KeyID key = mapKeyFromX(&xkey); KeyID key = mapKeyFromX(&xkey);
if (key != kKeyNone) { if (key != kKeyNone) {
// check if this is a key repeat by getting the next
// KeyPress event that has the same key and time as
// this release event, if any. first prepare the
// filter info.
CKeyEventFilter filter;
filter.m_event = KeyPress;
filter.m_window = xkey.window;
filter.m_time = xkey.time;
filter.m_keycode = xkey.keycode;
// now check for event
bool hasPress;
{
XEvent xevent2;
hasPress = (XCheckIfEvent(m_display, &xevent2,
&CXWindowsScreen::findKeyEvent,
(XPointer)&filter) == True);
}
// check for ctrl+alt+del emulation // check for ctrl+alt+del emulation
if ((key == kKeyPause || key == kKeyBreak) && if ((key == kKeyPause || key == kKeyBreak) &&
(mask & (KeyModifierControl | KeyModifierAlt)) == (mask & (KeyModifierControl | KeyModifierAlt)) ==
@ -1079,11 +1105,11 @@ CXWindowsScreen::onKeyRelease(XKeyEvent& xkey)
// pretend it's ctrl+alt+del and ignore autorepeat // pretend it's ctrl+alt+del and ignore autorepeat
LOG((CLOG_DEBUG "emulate ctrl+alt+del")); LOG((CLOG_DEBUG "emulate ctrl+alt+del"));
key = kKeyDelete; key = kKeyDelete;
hasPress = false; isRepeat = false;
} }
KeyButton keycode = static_cast<KeyButton>(xkey.keycode); KeyButton keycode = static_cast<KeyButton>(xkey.keycode);
if (!hasPress) { if (!isRepeat) {
// no press event follows so it's a plain release // no press event follows so it's a plain release
LOG((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", keycode, xkey.state)); LOG((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", keycode, xkey.state));
KeyModifierMask keyMask = m_keyState->getMaskForKey(keycode); KeyModifierMask keyMask = m_keyState->getMaskForKey(keycode);

View File

@ -67,6 +67,7 @@ public:
virtual void warpCursor(SInt32 x, SInt32 y); virtual void warpCursor(SInt32 x, SInt32 y);
virtual SInt32 getJumpZoneSize() const; virtual SInt32 getJumpZoneSize() const;
virtual bool isAnyMouseButtonDown() const; virtual bool isAnyMouseButtonDown() const;
virtual KeyModifierMask getActiveModifiers() const;
virtual void getCursorCenter(SInt32& x, SInt32& y) const; virtual void getCursorCenter(SInt32& x, SInt32& y) const;
virtual const char* getKeyName(KeyButton) const; virtual const char* getKeyName(KeyButton) const;
@ -123,7 +124,7 @@ private:
bool grabMouseAndKeyboard(); bool grabMouseAndKeyboard();
void onKeyPress(XKeyEvent&); void onKeyPress(XKeyEvent&);
void onKeyRelease(XKeyEvent&); void onKeyRelease(XKeyEvent&, bool isRepeat);
void onMousePress(const XButtonEvent&); void onMousePress(const XButtonEvent&);
void onMouseRelease(const XButtonEvent&); void onMouseRelease(const XButtonEvent&);
void onMouseMove(const XMotionEvent&); void onMouseMove(const XMotionEvent&);

View File

@ -394,21 +394,22 @@ CScreen::isLockedToScreen() const
return true; return true;
} }
// we don't keep primary key state up to date so get the
// current state.
const_cast<CScreen*>(this)->updateKeys();
// check for scroll lock toggled on
if (isModifierActive(KeyModifierScrollLock)) {
LOG((CLOG_DEBUG "locked by scroll lock"));
return true;
}
// check for any pressed key // check for any pressed key
KeyButton key = isAnyKeyDown(); KeyButton key = isAnyKeyDown();
if (key != 0) { if (key != 0) {
LOG((CLOG_DEBUG "locked by %s", m_screen->getKeyName(key))); // double check current state of the keys. this shouldn't
return true; // be necessary but we don't seem to get some key release
// events sometimes. this is an emergency backup so the
// client doesn't get stuck on the screen.
const_cast<CScreen*>(this)->updateKeys();
KeyButton key2 = isAnyKeyDown();
if (key2 != 0) {
LOG((CLOG_DEBUG "locked by %s", m_screen->getKeyName(key2)));
return true;
}
else {
LOG((CLOG_DEBUG "spuriously locked by %s", m_screen->getKeyName(key)));
}
} }
// not locked // not locked
@ -476,6 +477,7 @@ CScreen::updateKeys()
void void
CScreen::releaseKeys() CScreen::releaseKeys()
{ {
LOG((CLOG_INFO "releaseKeys")); // FIXME
// release keys that we've synthesized a press for and only those // release keys that we've synthesized a press for and only those
// keys. we don't want to synthesize a release on a key the user // keys. we don't want to synthesize a release on a key the user
// is still physically pressing. // is still physically pressing.
@ -489,9 +491,16 @@ CScreen::releaseKeys()
} }
void void
CScreen::setKeyDown(KeyButton key) CScreen::setKeyDown(KeyButton key, bool down)
{ {
m_keys[key & 0xffu] |= kDown; if (!isHalfDuplex(getMaskForKey(key))) {
if (down) {
m_keys[key & 0xffu] |= kDown;
}
else {
m_keys[key & 0xffu] &= ~kDown;
}
}
} }
void void
@ -614,11 +623,11 @@ KeyModifierMask
CScreen::getActiveModifiers() const CScreen::getActiveModifiers() const
{ {
if (m_isPrimary) { if (m_isPrimary) {
// we don't keep primary key state up to date so get the return m_screen->getActiveModifiers();
// current state. }
const_cast<CScreen*>(this)->updateKeys(); else {
return m_mask;
} }
return m_mask;
} }
bool bool

View File

@ -187,10 +187,9 @@ public:
//! Get screen lock state //! Get screen lock state
/*! /*!
Returns true if there's any reason that the user should not be Returns true if there's any reason that the user should not be
allowed to leave the screen. Active toggle keys (excluding the allowed to leave the screen (usually because a button or key is
scroll lock key) are not be counted as reasons to lock to the pressed). If this method returns true it logs a message as to
screen. If this method returns true it logs a message on why at why at the CLOG_DEBUG level.
the CLOG_DEBUG level.
*/ */
bool isLockedToScreen() const; bool isLockedToScreen() const;
@ -221,7 +220,7 @@ public:
// IKeyState overrides // IKeyState overrides
virtual void updateKeys(); virtual void updateKeys();
virtual void releaseKeys(); virtual void releaseKeys();
virtual void setKeyDown(KeyButton key); virtual void setKeyDown(KeyButton key, bool);
virtual void setToggled(KeyModifierMask); virtual void setToggled(KeyModifierMask);
virtual void addModifier(KeyModifierMask, KeyButtons&); virtual void addModifier(KeyModifierMask, KeyButtons&);
virtual void setToggleState(KeyModifierMask); virtual void setToggleState(KeyModifierMask);

View File

@ -51,9 +51,9 @@ public:
//! Mark key as being down //! Mark key as being down
/*! /*!
Sets the state of \c key to down. Sets the state of \c key to down or up.
*/ */
virtual void setKeyDown(KeyButton key) = 0; virtual void setKeyDown(KeyButton key, bool down) = 0;
//! Mark modifier as being toggled on //! Mark modifier as being toggled on
/*! /*!

View File

@ -1,157 +0,0 @@
/*
* 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.
*/
#include "IPlatformScreen.h"
//
// IPlatformScreen
//
CEvent::Type IPlatformScreen::s_keyDownEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_keyUpEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_keyRepeatEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_buttonDownEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_buttonUpEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_motionPrimaryEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_motionSecondaryEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_wheelEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_ssActivatedEvent = CEvent::kUnknown;
CEvent::Type IPlatformScreen::s_ssDeactivatedEvent = CEvent::kUnknown;
CEvent::Type
IPlatformScreen::getKeyDownEvent()
{
return CEvent::registerTypeOnce(s_keyDownEvent,
"IPlatformScreen::keyDown");
}
CEvent::Type
IPlatformScreen::getKeyUpEvent()
{
return CEvent::registerTypeOnce(s_keyUpEvent,
"IPlatformScreen::keyUp");
}
CEvent::Type
IPlatformScreen::getKeyRepeatEvent()
{
return CEvent::registerTypeOnce(s_keyRepeatEvent,
"IPlatformScreen::keyRepeat");
}
CEvent::Type
IPlatformScreen::getButtonDownEvent()
{
return CEvent::registerTypeOnce(s_buttonDownEvent,
"IPlatformScreen::buttonDown");
}
CEvent::Type
IPlatformScreen::getButtonUpEvent()
{
return CEvent::registerTypeOnce(s_buttonUpEvent,
"IPlatformScreen::buttonUp");
}
CEvent::Type
IPlatformScreen::getMotionOnPrimaryEvent()
{
return CEvent::registerTypeOnce(s_motionPrimaryEvent,
"IPlatformScreen::motionPrimary");
}
CEvent::Type
IPlatformScreen::getMotionOnSecondaryEvent()
{
return CEvent::registerTypeOnce(s_motionSecondaryEvent,
"IPlatformScreen::motionSecondary");
}
CEvent::Type
IPlatformScreen::getWheelEvent()
{
return CEvent::registerTypeOnce(s_wheelEvent,
"IPlatformScreen::wheel");
}
CEvent::Type
IPlatformScreen::getScreensaverActivatedEvent()
{
return CEvent::registerTypeOnce(s_ssActivatedEvent,
"IPlatformScreen::screensaverActivated");
}
CEvent::Type
IPlatformScreen::getScreensaverDeactivatedEvent()
{
return CEvent::registerTypeOnce(s_ssDeactivatedEvent,
"IPlatformScreen::screensaverDeactivated");
}
//
// IPlatformScreen::CKeyInfo
//
IPlatformScreen::CKeyInfo*
IPlatformScreen::CKeyInfo::alloc(KeyID id,
KeyModifierMask mask, KeyButton button, SInt32 count)
{
CKeyInfo* info = (CKeyInfo*)malloc(sizeof(CKeyInfo));
info->m_key = id;
info->m_mask = mask;
info->m_button = button;
info->m_count = count;
return info;
}
//
// IPlatformScreen::CButtonInfo
//
IPlatformScreen::CButtonInfo*
IPlatformScreen::CButtonInfo::alloc(ButtonID id)
{
CButtonInfo* info = (CButtonInfo*)malloc(sizeof(CButtonInfo));
info->m_button = id;
return info;
}
//
// IPlatformScreen::CMotionInfo
//
IPlatformScreen::CMotionInfo*
IPlatformScreen::CMotionInfo::alloc(SInt32 x, SInt32 y)
{
CMotionInfo* info = (CMotionInfo*)malloc(sizeof(CMotionInfo));
info->m_x = x;
info->m_y = y;
return info;
}
//
// IPlatformScreen::CWheelInfo
//
IPlatformScreen::CWheelInfo*
IPlatformScreen::CWheelInfo::alloc(SInt32 wheel)
{
CWheelInfo* info = (CWheelInfo*)malloc(sizeof(CWheelInfo));
info->m_wheel = wheel;
return info;
}

View File

@ -20,7 +20,6 @@
#include "ISecondaryScreen.h" #include "ISecondaryScreen.h"
#include "ClipboardTypes.h" #include "ClipboardTypes.h"
#include "OptionTypes.h" #include "OptionTypes.h"
#include "CEvent.h"
class IClipboard; class IClipboard;
class IKeyState; class IKeyState;
@ -29,51 +28,11 @@ class IKeyState;
/*! /*!
This interface defines the methods common to all platform dependent This interface defines the methods common to all platform dependent
screen implementations that are used by both primary and secondary screen implementations that are used by both primary and secondary
screens. A platform screen is expected to post the events defined screens.
in \c IScreen when appropriate. It should also post events defined
in \c IPlatformScreen if acting as the primary screen. The target
on the events should be the value returned by \c getEventTarget().
*/ */
class IPlatformScreen : public IScreen, class IPlatformScreen : public IScreen,
public IPrimaryScreen, public ISecondaryScreen { public IPrimaryScreen, public ISecondaryScreen {
public: public:
//! Key event data
class CKeyInfo {
public:
static CKeyInfo* alloc(KeyID, KeyModifierMask, KeyButton, SInt32 count);
public:
KeyID m_key;
KeyModifierMask m_mask;
KeyButton m_button;
SInt32 m_count;
};
//! Button event data
class CButtonInfo {
public:
static CButtonInfo* alloc(ButtonID);
public:
ButtonID m_button;
};
//! Motion event data
class CMotionInfo {
public:
static CMotionInfo* alloc(SInt32 x, SInt32 y);
public:
SInt32 m_x;
SInt32 m_y;
};
//! Wheel motion event data
class CWheelInfo {
public:
static CWheelInfo* alloc(SInt32);
public:
SInt32 m_wheel;
};
//! @name manipulators //! @name manipulators
//@{ //@{
@ -167,7 +126,8 @@ public:
//! Get keyboard state //! Get keyboard state
/*! /*!
Put the current keyboard state into the IKeyState passed to \c open(). Put the current keyboard state into the IKeyState passed to
\c setKeyState().
*/ */
virtual void updateKeys() = 0; virtual void updateKeys() = 0;
@ -187,34 +147,6 @@ public:
*/ */
virtual bool isPrimary() const = 0; virtual bool isPrimary() const = 0;
//! Get key down event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyDownEvent();
//! Get key up event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyUpEvent();
//! Get key repeat event type. Event data is CKeyInfo*.
static CEvent::Type getKeyRepeatEvent();
//! Get button down event type. Event data is CButtonInfo*.
static CEvent::Type getButtonDownEvent();
//! Get button up event type. Event data is CButtonInfo*.
static CEvent::Type getButtonUpEvent();
//! Get mouse motion on the primary screen event type
/*!
Event data is CMotionInfo* and the values are an absolute position.
*/
static CEvent::Type getMotionOnPrimaryEvent();
//! Get mouse motion on a secondary screen event type
/*!
Event data is CMotionInfo* and the values are motion deltas not
absolute coordinates.
*/
static CEvent::Type getMotionOnSecondaryEvent();
//! Get mouse wheel event type. Event data is CWheelInfo*.
static CEvent::Type getWheelEvent();
//! Get screensaver activated event type
static CEvent::Type getScreensaverActivatedEvent();
//! Get screensaver deactivated event type
static CEvent::Type getScreensaverDeactivatedEvent();
//@} //@}
// IScreen overrides // IScreen overrides
@ -229,6 +161,7 @@ public:
virtual void warpCursor(SInt32 x, SInt32 y) = 0; virtual void warpCursor(SInt32 x, SInt32 y) = 0;
virtual SInt32 getJumpZoneSize() const = 0; virtual SInt32 getJumpZoneSize() const = 0;
virtual bool isAnyMouseButtonDown() const = 0; virtual bool isAnyMouseButtonDown() const = 0;
virtual KeyModifierMask getActiveModifiers() const = 0;
virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0; virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0;
virtual const char* getKeyName(KeyButton) const = 0; virtual const char* getKeyName(KeyButton) const = 0;
@ -243,17 +176,32 @@ public:
KeyModifierMask desiredMask, KeyModifierMask desiredMask,
bool isAutoRepeat) const = 0; bool isAutoRepeat) const = 0;
private: protected:
static CEvent::Type s_keyDownEvent; //! Handle system event
static CEvent::Type s_keyUpEvent; /*!
static CEvent::Type s_keyRepeatEvent; A platform screen is expected to install a handler for system
static CEvent::Type s_buttonDownEvent; events in its c'tor like so:
static CEvent::Type s_buttonUpEvent; \code
static CEvent::Type s_motionPrimaryEvent; EVENTQUEUE->adoptHandler(CEvent::kSystem,
static CEvent::Type s_motionSecondaryEvent; IEventQueue::getSystemTarget(),
static CEvent::Type s_wheelEvent; new TMethodEventJob<IPlatformScreen>(this,
static CEvent::Type s_ssActivatedEvent; &IPlatformScreen::handleSystemEvent));
static CEvent::Type s_ssDeactivatedEvent; \endcode
It should remove the handler in its d'tor. Override the
\c handleSystemEvent() method to process system events.
It should post the events \c IScreen as appropriate.
A primary screen has further responsibilities. It should post
the events in \c IPrimaryScreen as appropriate. It should also
call \c setKeyDown() on the \c IKeyState passed to \c setKeyState()
whenever a key is pressed or released (but not for key repeats).
And it should call \c updateKeys() on the \c IKeyState if necessary
when the keyboard mapping changes.
The target of all events should be the value returned by
\c getEventTarget().
*/
virtual void handleSystemEvent(const CEvent& event, void*) = 0;
}; };
#endif #endif

View File

@ -0,0 +1,157 @@
/*
* 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.
*/
#include "IPrimaryScreen.h"
//
// IPrimaryScreen
//
CEvent::Type IPrimaryScreen::s_keyDownEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_keyUpEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_keyRepeatEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_buttonDownEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_buttonUpEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_motionPrimaryEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_motionSecondaryEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_wheelEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_ssActivatedEvent = CEvent::kUnknown;
CEvent::Type IPrimaryScreen::s_ssDeactivatedEvent = CEvent::kUnknown;
CEvent::Type
IPrimaryScreen::getKeyDownEvent()
{
return CEvent::registerTypeOnce(s_keyDownEvent,
"IPrimaryScreen::keyDown");
}
CEvent::Type
IPrimaryScreen::getKeyUpEvent()
{
return CEvent::registerTypeOnce(s_keyUpEvent,
"IPrimaryScreen::keyUp");
}
CEvent::Type
IPrimaryScreen::getKeyRepeatEvent()
{
return CEvent::registerTypeOnce(s_keyRepeatEvent,
"IPrimaryScreen::keyRepeat");
}
CEvent::Type
IPrimaryScreen::getButtonDownEvent()
{
return CEvent::registerTypeOnce(s_buttonDownEvent,
"IPrimaryScreen::buttonDown");
}
CEvent::Type
IPrimaryScreen::getButtonUpEvent()
{
return CEvent::registerTypeOnce(s_buttonUpEvent,
"IPrimaryScreen::buttonUp");
}
CEvent::Type
IPrimaryScreen::getMotionOnPrimaryEvent()
{
return CEvent::registerTypeOnce(s_motionPrimaryEvent,
"IPrimaryScreen::motionPrimary");
}
CEvent::Type
IPrimaryScreen::getMotionOnSecondaryEvent()
{
return CEvent::registerTypeOnce(s_motionSecondaryEvent,
"IPrimaryScreen::motionSecondary");
}
CEvent::Type
IPrimaryScreen::getWheelEvent()
{
return CEvent::registerTypeOnce(s_wheelEvent,
"IPrimaryScreen::wheel");
}
CEvent::Type
IPrimaryScreen::getScreensaverActivatedEvent()
{
return CEvent::registerTypeOnce(s_ssActivatedEvent,
"IPrimaryScreen::screensaverActivated");
}
CEvent::Type
IPrimaryScreen::getScreensaverDeactivatedEvent()
{
return CEvent::registerTypeOnce(s_ssDeactivatedEvent,
"IPrimaryScreen::screensaverDeactivated");
}
//
// IPrimaryScreen::CKeyInfo
//
IPrimaryScreen::CKeyInfo*
IPrimaryScreen::CKeyInfo::alloc(KeyID id,
KeyModifierMask mask, KeyButton button, SInt32 count)
{
CKeyInfo* info = (CKeyInfo*)malloc(sizeof(CKeyInfo));
info->m_key = id;
info->m_mask = mask;
info->m_button = button;
info->m_count = count;
return info;
}
//
// IPrimaryScreen::CButtonInfo
//
IPrimaryScreen::CButtonInfo*
IPrimaryScreen::CButtonInfo::alloc(ButtonID id)
{
CButtonInfo* info = (CButtonInfo*)malloc(sizeof(CButtonInfo));
info->m_button = id;
return info;
}
//
// IPrimaryScreen::CMotionInfo
//
IPrimaryScreen::CMotionInfo*
IPrimaryScreen::CMotionInfo::alloc(SInt32 x, SInt32 y)
{
CMotionInfo* info = (CMotionInfo*)malloc(sizeof(CMotionInfo));
info->m_x = x;
info->m_y = y;
return info;
}
//
// IPrimaryScreen::CWheelInfo
//
IPrimaryScreen::CWheelInfo*
IPrimaryScreen::CWheelInfo::alloc(SInt32 wheel)
{
CWheelInfo* info = (CWheelInfo*)malloc(sizeof(CWheelInfo));
info->m_wheel = wheel;
return info;
}

View File

@ -17,6 +17,8 @@
#include "IInterface.h" #include "IInterface.h"
#include "IKeyState.h" #include "IKeyState.h"
#include "CEvent.h"
#include "MouseTypes.h"
//! Primary screen interface //! Primary screen interface
/*! /*!
@ -25,6 +27,43 @@ primary screen implementations.
*/ */
class IPrimaryScreen : public IInterface { class IPrimaryScreen : public IInterface {
public: public:
//! Key event data
class CKeyInfo {
public:
static CKeyInfo* alloc(KeyID, KeyModifierMask, KeyButton, SInt32 count);
public:
KeyID m_key;
KeyModifierMask m_mask;
KeyButton m_button;
SInt32 m_count;
};
//! Button event data
class CButtonInfo {
public:
static CButtonInfo* alloc(ButtonID);
public:
ButtonID m_button;
};
//! Motion event data
class CMotionInfo {
public:
static CMotionInfo* alloc(SInt32 x, SInt32 y);
public:
SInt32 m_x;
SInt32 m_y;
};
//! Wheel motion event data
class CWheelInfo {
public:
static CWheelInfo* alloc(SInt32);
public:
SInt32 m_wheel;
};
//! @name manipulators //! @name manipulators
//@{ //@{
@ -58,10 +97,20 @@ public:
//! Test if mouse is pressed //! Test if mouse is pressed
/*! /*!
Return true if any mouse button is currently pressed. Return true if any mouse button is currently pressed. Ideally,
"current" means up to the last processed event but it can mean
the current physical mouse button state.
*/ */
virtual bool isAnyMouseButtonDown() const = 0; virtual bool isAnyMouseButtonDown() const = 0;
//! Get current modifier key state
/*!
Returns the current modifier key state. Ideally, "current" means
up to the lat processed event but it can mean the current physical
modifier key state.
*/
virtual KeyModifierMask getActiveModifiers() const = 0;
//! Get cursor center position //! Get cursor center position
/*! /*!
Return the cursor center position which is where we park the Return the cursor center position which is where we park the
@ -76,7 +125,47 @@ public:
*/ */
virtual const char* getKeyName(KeyButton) const = 0; virtual const char* getKeyName(KeyButton) const = 0;
//! Get key down event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyDownEvent();
//! Get key up event type. Event data is CKeyInfo*, count == 1.
static CEvent::Type getKeyUpEvent();
//! Get key repeat event type. Event data is CKeyInfo*.
static CEvent::Type getKeyRepeatEvent();
//! Get button down event type. Event data is CButtonInfo*.
static CEvent::Type getButtonDownEvent();
//! Get button up event type. Event data is CButtonInfo*.
static CEvent::Type getButtonUpEvent();
//! Get mouse motion on the primary screen event type
/*!
Event data is CMotionInfo* and the values are an absolute position.
*/
static CEvent::Type getMotionOnPrimaryEvent();
//! Get mouse motion on a secondary screen event type
/*!
Event data is CMotionInfo* and the values are motion deltas not
absolute coordinates.
*/
static CEvent::Type getMotionOnSecondaryEvent();
//! Get mouse wheel event type. Event data is CWheelInfo*.
static CEvent::Type getWheelEvent();
//! Get screensaver activated event type
static CEvent::Type getScreensaverActivatedEvent();
//! Get screensaver deactivated event type
static CEvent::Type getScreensaverDeactivatedEvent();
//@} //@}
private:
static CEvent::Type s_keyDownEvent;
static CEvent::Type s_keyUpEvent;
static CEvent::Type s_keyRepeatEvent;
static CEvent::Type s_buttonDownEvent;
static CEvent::Type s_buttonUpEvent;
static CEvent::Type s_motionPrimaryEvent;
static CEvent::Type s_motionSecondaryEvent;
static CEvent::Type s_wheelEvent;
static CEvent::Type s_ssActivatedEvent;
static CEvent::Type s_ssDeactivatedEvent;
}; };
#endif #endif

View File

@ -30,7 +30,7 @@ libsynergy_a_SOURCES = \
CProtocolUtil.cpp \ CProtocolUtil.cpp \
CScreen.cpp \ CScreen.cpp \
IClipboard.cpp \ IClipboard.cpp \
IPlatformScreen.cpp \ IPrimaryScreen.cpp \
IScreen.cpp \ IScreen.cpp \
XScreen.cpp \ XScreen.cpp \
XSynergy.cpp \ XSynergy.cpp \