From 20ba10bfa89159baa2f69d785c896d8e2aa5cf7a Mon Sep 17 00:00:00 2001 From: crs Date: Sun, 14 Mar 2004 17:55:53 +0000 Subject: [PATCH] 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. --- lib/platform/CXWindowsKeyMapper.cpp | 16 +-- lib/platform/CXWindowsScreen.cpp | 96 ++++++++++------- lib/platform/CXWindowsScreen.h | 3 +- lib/synergy/CScreen.cpp | 45 ++++---- lib/synergy/CScreen.h | 9 +- lib/synergy/IKeyState.h | 4 +- lib/synergy/IPlatformScreen.cpp | 157 ---------------------------- lib/synergy/IPlatformScreen.h | 112 ++++++-------------- lib/synergy/IPrimaryScreen.cpp | 157 ++++++++++++++++++++++++++++ lib/synergy/IPrimaryScreen.h | 91 +++++++++++++++- lib/synergy/Makefile.am | 2 +- 11 files changed, 382 insertions(+), 310 deletions(-) delete mode 100644 lib/synergy/IPlatformScreen.cpp create mode 100644 lib/synergy/IPrimaryScreen.cpp 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 \