diff --git a/lib/platform/CXWindowsKeyMapper.cpp b/lib/platform/CXWindowsKeyMapper.cpp index 35526a05..5ff68ebd 100644 --- a/lib/platform/CXWindowsKeyMapper.cpp +++ b/lib/platform/CXWindowsKeyMapper.cpp @@ -173,21 +173,21 @@ CXWindowsKeyMapper::update(Display* display, IKeyState* keyState) // transfer to our state for (UInt32 i = 0, j = 0; i < 32; j += 8, ++i) { if ((keys[i] & 0x01) != 0) - keyState->setKeyDown(j + 0); + keyState->setKeyDown(j + 0, true); if ((keys[i] & 0x02) != 0) - keyState->setKeyDown(j + 1); + keyState->setKeyDown(j + 1, true); if ((keys[i] & 0x04) != 0) - keyState->setKeyDown(j + 2); + keyState->setKeyDown(j + 2, true); if ((keys[i] & 0x08) != 0) - keyState->setKeyDown(j + 3); + keyState->setKeyDown(j + 3, true); if ((keys[i] & 0x10) != 0) - keyState->setKeyDown(j + 4); + keyState->setKeyDown(j + 4, true); if ((keys[i] & 0x20) != 0) - keyState->setKeyDown(j + 5); + keyState->setKeyDown(j + 5, true); if ((keys[i] & 0x40) != 0) - keyState->setKeyDown(j + 6); + keyState->setKeyDown(j + 6, true); if ((keys[i] & 0x80) != 0) - keyState->setKeyDown(j + 7); + keyState->setKeyDown(j + 7, true); } // set toggle modifier states diff --git a/lib/platform/CXWindowsScreen.cpp b/lib/platform/CXWindowsScreen.cpp index de18c1d0..da9a705c 100644 --- a/lib/platform/CXWindowsScreen.cpp +++ b/lib/platform/CXWindowsScreen.cpp @@ -184,8 +184,8 @@ CXWindowsScreen::CXWindowsScreen(bool isPrimary) : // install event handlers EVENTQUEUE->adoptHandler(CEvent::kSystem, IEventQueue::getSystemTarget(), - new TMethodEventJob(this, - &CXWindowsScreen::handleSystemEvent)); + new TMethodEventJob(this, + &IPlatformScreen::handleSystemEvent)); // install the platform event queue EVENTQUEUE->adoptBuffer(new CXWindowsEventQueueBuffer(m_display, m_window)); @@ -244,6 +244,9 @@ CXWindowsScreen::enable() // warp the mouse to the cursor center fakeMouseMove(m_xCenter, m_yCenter); } + else { + m_keyState->updateKeys(); + } } void @@ -544,6 +547,21 @@ CXWindowsScreen::isAnyMouseButtonDown() const 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 CXWindowsScreen::getCursorCenter(SInt32& x, SInt32& y) const { @@ -841,12 +859,49 @@ CXWindowsScreen::sendClipboardEvent(CEvent::Type type, ClipboardID id) sendEvent(type, info); } +Bool +CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg) +{ + CKeyEventFilter* filter = reinterpret_cast(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 CXWindowsScreen::handleSystemEvent(const CEvent& event, void*) { XEvent* xevent = reinterpret_cast(event.getData()); 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 if (m_ic != NULL) { // XFilterEvent() may eat the event and generate a new KeyPress @@ -977,7 +1032,7 @@ CXWindowsScreen::handleSystemEvent(const CEvent& event, void*) case KeyRelease: if (m_isPrimary) { - onKeyRelease(xevent->xkey); + onKeyRelease(xevent->xkey, isRepeat); } return; @@ -1037,41 +1092,12 @@ CXWindowsScreen::onKeyPress(XKeyEvent& xkey) } } -Bool -CXWindowsScreen::findKeyEvent(Display*, XEvent* xevent, XPointer arg) -{ - CKeyEventFilter* filter = reinterpret_cast(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 -CXWindowsScreen::onKeyRelease(XKeyEvent& xkey) +CXWindowsScreen::onKeyRelease(XKeyEvent& xkey, bool isRepeat) { const KeyModifierMask mask = m_keyMapper.mapModifier(xkey.state); KeyID key = mapKeyFromX(&xkey); 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 if ((key == kKeyPause || key == kKeyBreak) && (mask & (KeyModifierControl | KeyModifierAlt)) == @@ -1079,11 +1105,11 @@ CXWindowsScreen::onKeyRelease(XKeyEvent& xkey) // pretend it's ctrl+alt+del and ignore autorepeat LOG((CLOG_DEBUG "emulate ctrl+alt+del")); key = kKeyDelete; - hasPress = false; + isRepeat = false; } KeyButton keycode = static_cast(xkey.keycode); - if (!hasPress) { + if (!isRepeat) { // no press event follows so it's a plain release LOG((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", keycode, xkey.state)); KeyModifierMask keyMask = m_keyState->getMaskForKey(keycode); diff --git a/lib/platform/CXWindowsScreen.h b/lib/platform/CXWindowsScreen.h index b56c693d..7298190f 100644 --- a/lib/platform/CXWindowsScreen.h +++ b/lib/platform/CXWindowsScreen.h @@ -67,6 +67,7 @@ public: virtual void warpCursor(SInt32 x, SInt32 y); virtual SInt32 getJumpZoneSize() const; virtual bool isAnyMouseButtonDown() const; + virtual KeyModifierMask getActiveModifiers() const; virtual void getCursorCenter(SInt32& x, SInt32& y) const; virtual const char* getKeyName(KeyButton) const; @@ -123,7 +124,7 @@ private: bool grabMouseAndKeyboard(); void onKeyPress(XKeyEvent&); - void onKeyRelease(XKeyEvent&); + void onKeyRelease(XKeyEvent&, bool isRepeat); void onMousePress(const XButtonEvent&); void onMouseRelease(const XButtonEvent&); void onMouseMove(const XMotionEvent&); diff --git a/lib/synergy/CScreen.cpp b/lib/synergy/CScreen.cpp index a4164f55..dde44703 100644 --- a/lib/synergy/CScreen.cpp +++ b/lib/synergy/CScreen.cpp @@ -394,21 +394,22 @@ CScreen::isLockedToScreen() const return true; } - // we don't keep primary key state up to date so get the - // current state. - const_cast(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 KeyButton key = isAnyKeyDown(); if (key != 0) { - LOG((CLOG_DEBUG "locked by %s", m_screen->getKeyName(key))); - return true; + // double check current state of the keys. this shouldn't + // 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(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 @@ -476,6 +477,7 @@ CScreen::updateKeys() void CScreen::releaseKeys() { +LOG((CLOG_INFO "releaseKeys")); // FIXME // 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 // is still physically pressing. @@ -489,9 +491,16 @@ CScreen::releaseKeys() } 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 @@ -614,11 +623,11 @@ KeyModifierMask CScreen::getActiveModifiers() const { if (m_isPrimary) { - // we don't keep primary key state up to date so get the - // current state. - const_cast(this)->updateKeys(); + return m_screen->getActiveModifiers(); + } + else { + return m_mask; } - return m_mask; } bool diff --git a/lib/synergy/CScreen.h b/lib/synergy/CScreen.h index a20c021e..524bb0bd 100644 --- a/lib/synergy/CScreen.h +++ b/lib/synergy/CScreen.h @@ -187,10 +187,9 @@ public: //! Get screen lock state /*! Returns true if there's any reason that the user should not be - allowed to leave the screen. Active toggle keys (excluding the - scroll lock key) are not be counted as reasons to lock to the - screen. If this method returns true it logs a message on why at - the CLOG_DEBUG level. + allowed to leave the screen (usually because a button or key is + pressed). If this method returns true it logs a message as to + why at the CLOG_DEBUG level. */ bool isLockedToScreen() const; @@ -221,7 +220,7 @@ public: // IKeyState overrides virtual void updateKeys(); virtual void releaseKeys(); - virtual void setKeyDown(KeyButton key); + virtual void setKeyDown(KeyButton key, bool); virtual void setToggled(KeyModifierMask); virtual void addModifier(KeyModifierMask, KeyButtons&); virtual void setToggleState(KeyModifierMask); diff --git a/lib/synergy/IKeyState.h b/lib/synergy/IKeyState.h index 14a415c2..f8dec884 100644 --- a/lib/synergy/IKeyState.h +++ b/lib/synergy/IKeyState.h @@ -51,9 +51,9 @@ public: //! 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 /*! diff --git a/lib/synergy/IPlatformScreen.cpp b/lib/synergy/IPlatformScreen.cpp deleted file mode 100644 index a9a37418..00000000 --- a/lib/synergy/IPlatformScreen.cpp +++ /dev/null @@ -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; -} diff --git a/lib/synergy/IPlatformScreen.h b/lib/synergy/IPlatformScreen.h index bae81e86..379ef03d 100644 --- a/lib/synergy/IPlatformScreen.h +++ b/lib/synergy/IPlatformScreen.h @@ -20,7 +20,6 @@ #include "ISecondaryScreen.h" #include "ClipboardTypes.h" #include "OptionTypes.h" -#include "CEvent.h" class IClipboard; class IKeyState; @@ -29,51 +28,11 @@ class IKeyState; /*! This interface defines the methods common to all platform dependent screen implementations that are used by both primary and secondary -screens. A platform screen is expected to post the events defined -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(). +screens. */ class IPlatformScreen : public IScreen, public IPrimaryScreen, public ISecondaryScreen { 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 //@{ @@ -167,7 +126,8 @@ public: //! 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; @@ -187,34 +147,6 @@ public: */ 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 @@ -229,6 +161,7 @@ public: virtual void warpCursor(SInt32 x, SInt32 y) = 0; virtual SInt32 getJumpZoneSize() const = 0; virtual bool isAnyMouseButtonDown() const = 0; + virtual KeyModifierMask getActiveModifiers() const = 0; virtual void getCursorCenter(SInt32& x, SInt32& y) const = 0; virtual const char* getKeyName(KeyButton) const = 0; @@ -243,17 +176,32 @@ public: KeyModifierMask desiredMask, bool isAutoRepeat) const = 0; -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; +protected: + //! Handle system event + /*! + A platform screen is expected to install a handler for system + events in its c'tor like so: + \code + EVENTQUEUE->adoptHandler(CEvent::kSystem, + IEventQueue::getSystemTarget(), + new TMethodEventJob(this, + &IPlatformScreen::handleSystemEvent)); + \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 diff --git a/lib/synergy/IPrimaryScreen.cpp b/lib/synergy/IPrimaryScreen.cpp new file mode 100644 index 00000000..9a201001 --- /dev/null +++ b/lib/synergy/IPrimaryScreen.cpp @@ -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; +} diff --git a/lib/synergy/IPrimaryScreen.h b/lib/synergy/IPrimaryScreen.h index fb3f6ccb..9b88caf8 100644 --- a/lib/synergy/IPrimaryScreen.h +++ b/lib/synergy/IPrimaryScreen.h @@ -17,6 +17,8 @@ #include "IInterface.h" #include "IKeyState.h" +#include "CEvent.h" +#include "MouseTypes.h" //! Primary screen interface /*! @@ -25,6 +27,43 @@ primary screen implementations. */ class IPrimaryScreen : public IInterface { 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 //@{ @@ -58,10 +97,20 @@ public: //! 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; + //! 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 /*! Return the cursor center position which is where we park the @@ -76,7 +125,47 @@ public: */ 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 diff --git a/lib/synergy/Makefile.am b/lib/synergy/Makefile.am index e34363d7..60a304ca 100644 --- a/lib/synergy/Makefile.am +++ b/lib/synergy/Makefile.am @@ -30,7 +30,7 @@ libsynergy_a_SOURCES = \ CProtocolUtil.cpp \ CScreen.cpp \ IClipboard.cpp \ - IPlatformScreen.cpp \ + IPrimaryScreen.cpp \ IScreen.cpp \ XScreen.cpp \ XSynergy.cpp \