• Main Page
  • Classes
  • Files
  • File List

CServer.h

00001 /*
00002  * synergy -- mouse and keyboard sharing utility
00003  * Copyright (C) 2012 Bolton Software Ltd.
00004  * Copyright (C) 2002 Chris Schoeneman
00005  * 
00006  * This package is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU General Public License
00008  * found in the file COPYING that should have accompanied this file.
00009  * 
00010  * This package is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017  */
00018 
00019 #ifndef CSERVER_H
00020 #define CSERVER_H
00021 
00022 #include "CConfig.h"
00023 #include "CClipboard.h"
00024 #include "ClipboardTypes.h"
00025 #include "KeyTypes.h"
00026 #include "MouseTypes.h"
00027 #include "CEvent.h"
00028 #include "CStopwatch.h"
00029 #include "stdmap.h"
00030 #include "stdset.h"
00031 #include "stdvector.h"
00032 #include "INode.h"
00033 
00034 class CBaseClientProxy;
00035 class CEventQueueTimer;
00036 class CPrimaryClient;
00037 class CInputFilter;
00038 class CScreen;
00039 
00041 
00044 class CServer : public INode {
00045 public:
00047     class CLockCursorToScreenInfo {
00048     public:
00049         enum State { kOff, kOn, kToggle };
00050 
00051         static CLockCursorToScreenInfo* alloc(State state = kToggle);
00052 
00053     public:
00054         State           m_state;
00055     };
00056 
00058     class CSwitchToScreenInfo {
00059     public:
00060         static CSwitchToScreenInfo* alloc(const CString& screen);
00061 
00062     public:
00063         // this is a C-string;  this type is a variable size structure
00064         char            m_screen[1];
00065     };
00066 
00068     class CSwitchInDirectionInfo {
00069     public:
00070         static CSwitchInDirectionInfo* alloc(EDirection direction);
00071 
00072     public:
00073         EDirection      m_direction;
00074     };
00075 
00077     class CScreenConnectedInfo {
00078     public:
00079         CScreenConnectedInfo(CString screen) : m_screen(screen) { }
00080 
00081     public:
00082         CString         m_screen; // was char[1]
00083     };
00084 
00086     class CKeyboardBroadcastInfo {
00087     public:
00088         enum State { kOff, kOn, kToggle };
00089 
00090         static CKeyboardBroadcastInfo* alloc(State state = kToggle);
00091         static CKeyboardBroadcastInfo* alloc(State state,
00092                                             const CString& screens);
00093 
00094     public:
00095         State           m_state;
00096         char            m_screens[1];
00097     };
00098 
00104     CServer(const CConfig& config, CPrimaryClient* primaryClient, CScreen* screen);
00105     ~CServer();
00106     
00107 #ifdef TEST_ENV
00108     CServer() { }
00109 #endif
00110 
00112 
00113 
00115 
00120     bool                setConfig(const CConfig&);
00121 
00123 
00127     void                adoptClient(CBaseClientProxy* client);
00128 
00130 
00136     void                disconnect();
00137 
00139     void                gameDeviceTimingResp(UInt16 freq);
00140 
00142     void                gameDeviceFeedback(GameDeviceID id, UInt16 m1, UInt16 m2);
00143 
00145 
00146 
00147 
00149 
00152     UInt32              getNumClients() const;
00153 
00155 
00158     void                getClients(std::vector<CString>& list) const;
00159 
00161 
00165     static CEvent::Type getErrorEvent();
00166 
00168 
00173     static CEvent::Type getConnectedEvent();
00174 
00176 
00180     static CEvent::Type getDisconnectedEvent();
00181 
00183 
00188     static CEvent::Type getSwitchToScreenEvent();
00189 
00191 
00196     static CEvent::Type getSwitchInDirectionEvent();
00197 
00199 
00204     static CEvent::Type getKeyboardBroadcastEvent();
00205 
00207 
00212     static CEvent::Type getLockCursorToScreenEvent();
00213 
00215 
00219     static CEvent::Type getScreenSwitchedEvent();
00220 
00222 
00223 private:
00224     // get canonical name of client
00225     CString             getName(const CBaseClientProxy*) const;
00226 
00227     // get the sides of the primary screen that have neighbors
00228     UInt32              getActivePrimarySides() const;
00229 
00230     // returns true iff mouse should be locked to the current screen
00231     // according to this object only, ignoring what the primary client
00232     // says.
00233     bool                isLockedToScreenServer() const;
00234 
00235     // returns true iff mouse should be locked to the current screen
00236     // according to this object or the primary client.
00237     bool                isLockedToScreen() const;
00238 
00239     // returns the jump zone of the client
00240     SInt32              getJumpZoneSize(CBaseClientProxy*) const;
00241 
00242     // change the active screen
00243     void                switchScreen(CBaseClientProxy*,
00244                             SInt32 x, SInt32 y, bool forScreenSaver);
00245 
00246     // jump to screen
00247     void                jumpToScreen(CBaseClientProxy*);
00248 
00249     // convert pixel position to fraction, using x or y depending on the
00250     // direction.
00251     float               mapToFraction(CBaseClientProxy*, EDirection,
00252                             SInt32 x, SInt32 y) const;
00253 
00254     // convert fraction to pixel position, writing only x or y depending
00255     // on the direction.
00256     void                mapToPixel(CBaseClientProxy*, EDirection, float f,
00257                             SInt32& x, SInt32& y) const;
00258 
00259     // returns true if the client has a neighbor anywhere along the edge
00260     // indicated by the direction.
00261     bool                hasAnyNeighbor(CBaseClientProxy*, EDirection) const;
00262 
00263     // lookup neighboring screen, mapping the coordinate independent of
00264     // the direction to the neighbor's coordinate space.
00265     CBaseClientProxy*   getNeighbor(CBaseClientProxy*, EDirection,
00266                             SInt32& x, SInt32& y) const;
00267 
00268     // lookup neighboring screen.  given a position relative to the
00269     // source screen, find the screen we should move onto and where.
00270     // if the position is sufficiently far from the source then we
00271     // cross multiple screens.  if there is no suitable screen then
00272     // return NULL and x,y are not modified.
00273     CBaseClientProxy*   mapToNeighbor(CBaseClientProxy*, EDirection,
00274                             SInt32& x, SInt32& y) const;
00275 
00276     // adjusts x and y or neither to avoid ending up in a jump zone
00277     // after entering the client in the given direction.
00278     void                avoidJumpZone(CBaseClientProxy*, EDirection,
00279                             SInt32& x, SInt32& y) const;
00280 
00281     // test if a switch is permitted.  this includes testing user
00282     // options like switch delay and tracking any state required to
00283     // implement them.  returns true iff a switch is permitted.
00284     bool                isSwitchOkay(CBaseClientProxy* dst, EDirection,
00285                             SInt32 x, SInt32 y, SInt32 xActive, SInt32 yActive);
00286 
00287     // update switch state due to a mouse move at \p x, \p y that
00288     // doesn't switch screens.
00289     void                noSwitch(SInt32 x, SInt32 y);
00290 
00291     // stop switch timers
00292     void                stopSwitch();
00293 
00294     // start two tap switch timer
00295     void                startSwitchTwoTap();
00296 
00297     // arm the two tap switch timer if \p x, \p y is outside the tap zone
00298     void                armSwitchTwoTap(SInt32 x, SInt32 y);
00299 
00300     // stop the two tap switch timer
00301     void                stopSwitchTwoTap();
00302 
00303     // returns true iff the two tap switch timer is started
00304     bool                isSwitchTwoTapStarted() const;
00305 
00306     // returns true iff should switch because of two tap
00307     bool                shouldSwitchTwoTap() const;
00308 
00309     // start delay switch timer
00310     void                startSwitchWait(SInt32 x, SInt32 y);
00311 
00312     // stop delay switch timer
00313     void                stopSwitchWait();
00314 
00315     // returns true iff the delay switch timer is started
00316     bool                isSwitchWaitStarted() const;
00317 
00318     // returns the corner (EScreenSwitchCornerMasks) where x,y is on the
00319     // given client.  corners have the given size.
00320     UInt32              getCorner(CBaseClientProxy*,
00321                             SInt32 x, SInt32 y, SInt32 size) const;
00322 
00323     // stop relative mouse moves
00324     void                stopRelativeMoves();
00325 
00326     // send screen options to \c client
00327     void                sendOptions(CBaseClientProxy* client) const;
00328 
00329     // process options from configuration
00330     void                processOptions();
00331 
00332     // event handlers
00333     void                handleShapeChanged(const CEvent&, void*);
00334     void                handleClipboardGrabbed(const CEvent&, void*);
00335     void                handleClipboardChanged(const CEvent&, void*);
00336     void                handleKeyDownEvent(const CEvent&, void*);
00337     void                handleKeyUpEvent(const CEvent&, void*);
00338     void                handleKeyRepeatEvent(const CEvent&, void*);
00339     void                handleButtonDownEvent(const CEvent&, void*);
00340     void                handleButtonUpEvent(const CEvent&, void*);
00341     void                handleMotionPrimaryEvent(const CEvent&, void*);
00342     void                handleMotionSecondaryEvent(const CEvent&, void*);
00343     void                handleWheelEvent(const CEvent&, void*);
00344     void                handleGameDeviceButtons(const CEvent&, void*);
00345     void                handleGameDeviceSticks(const CEvent&, void*);
00346     void                handleGameDeviceTriggers(const CEvent&, void*);
00347     void                handleGameDeviceTimingReq(const CEvent&, void*);
00348     void                handleScreensaverActivatedEvent(const CEvent&, void*);
00349     void                handleScreensaverDeactivatedEvent(const CEvent&, void*);
00350     void                handleSwitchWaitTimeout(const CEvent&, void*);
00351     void                handleClientDisconnected(const CEvent&, void*);
00352     void                handleClientCloseTimeout(const CEvent&, void*);
00353     void                handleSwitchToScreenEvent(const CEvent&, void*);
00354     void                handleSwitchInDirectionEvent(const CEvent&, void*);
00355     void                handleKeyboardBroadcastEvent(const CEvent&,void*);
00356     void                handleLockCursorToScreenEvent(const CEvent&, void*);
00357     void                handleFakeInputBeginEvent(const CEvent&, void*);
00358     void                handleFakeInputEndEvent(const CEvent&, void*);
00359 
00360     // event processing
00361     void                onClipboardChanged(CBaseClientProxy* sender,
00362                             ClipboardID id, UInt32 seqNum);
00363     void                onScreensaver(bool activated);
00364     void                onKeyDown(KeyID, KeyModifierMask, KeyButton,
00365                             const char* screens);
00366     void                onKeyUp(KeyID, KeyModifierMask, KeyButton,
00367                             const char* screens);
00368     void                onKeyRepeat(KeyID, KeyModifierMask, SInt32, KeyButton);
00369     void                onMouseDown(ButtonID);
00370     void                onMouseUp(ButtonID);
00371     bool                onMouseMovePrimary(SInt32 x, SInt32 y);
00372     void                onMouseMoveSecondary(SInt32 dx, SInt32 dy);
00373     void                onMouseWheel(SInt32 xDelta, SInt32 yDelta);
00374     void                onGameDeviceButtons(GameDeviceID id, GameDeviceButton buttons);
00375     void                onGameDeviceSticks(GameDeviceID id, SInt16 x1, SInt16 y1, SInt16 x2, SInt16 y2);
00376     void                onGameDeviceTriggers(GameDeviceID id, UInt8 t1, UInt8 t2);
00377     void                onGameDeviceTimingReq();
00378 
00379     // add client to list and attach event handlers for client
00380     bool                addClient(CBaseClientProxy*);
00381 
00382     // remove client from list and detach event handlers for client
00383     bool                removeClient(CBaseClientProxy*);
00384 
00385     // close a client
00386     void                closeClient(CBaseClientProxy*, const char* msg);
00387 
00388     // close clients not in \p config
00389     void                closeClients(const CConfig& config);
00390 
00391     // close all clients whether they've completed the handshake or not,
00392     // except the primary client
00393     void                closeAllClients();
00394 
00395     // remove clients from internal state
00396     void                removeActiveClient(CBaseClientProxy*);
00397     void                removeOldClient(CBaseClientProxy*);
00398 
00399     // force the cursor off of \p client
00400     void                forceLeaveClient(CBaseClientProxy* client);
00401     
00402 public:
00403     bool                m_mock;
00404 
00405 private:
00406     class CClipboardInfo {
00407     public:
00408         CClipboardInfo();
00409 
00410     public:
00411         CClipboard      m_clipboard;
00412         CString         m_clipboardData;
00413         CString         m_clipboardOwner;
00414         UInt32          m_clipboardSeqNum;
00415     };
00416 
00417     // the primary screen client
00418     CPrimaryClient*     m_primaryClient;
00419 
00420     // all clients (including the primary client) indexed by name
00421     typedef std::map<CString, CBaseClientProxy*> CClientList;
00422     typedef std::set<CBaseClientProxy*> CClientSet;
00423     CClientList         m_clients;
00424     CClientSet          m_clientSet;
00425 
00426     // all old connections that we're waiting to hangup
00427     typedef std::map<CBaseClientProxy*, CEventQueueTimer*> COldClients;
00428     COldClients         m_oldClients;
00429 
00430     // the client with focus
00431     CBaseClientProxy*   m_active;
00432 
00433     // the sequence number of enter messages
00434     UInt32              m_seqNum;
00435 
00436     // current mouse position (in absolute screen coordinates) on
00437     // whichever screen is active
00438     SInt32              m_x, m_y;
00439 
00440     // last mouse deltas.  this is needed to smooth out double tap
00441     // on win32 which reports bogus mouse motion at the edge of
00442     // the screen when using low level hooks, synthesizing motion
00443     // in the opposite direction the mouse actually moved.
00444     SInt32              m_xDelta, m_yDelta;
00445     SInt32              m_xDelta2, m_yDelta2;
00446 
00447     // current configuration
00448     CConfig             m_config;
00449 
00450     // input filter (from m_config);
00451     CInputFilter*       m_inputFilter;
00452 
00453     // clipboard cache
00454     CClipboardInfo      m_clipboards[kClipboardEnd];
00455 
00456     // state saved when screen saver activates
00457     CBaseClientProxy*   m_activeSaver;
00458     SInt32              m_xSaver, m_ySaver;
00459 
00460     // common state for screen switch tests.  all tests are always
00461     // trying to reach the same screen in the same direction.
00462     EDirection          m_switchDir;
00463     CBaseClientProxy*   m_switchScreen;
00464 
00465     // state for delayed screen switching
00466     double              m_switchWaitDelay;
00467     CEventQueueTimer*   m_switchWaitTimer;
00468     SInt32              m_switchWaitX, m_switchWaitY;
00469 
00470     // state for double-tap screen switching
00471     double              m_switchTwoTapDelay;
00472     CStopwatch          m_switchTwoTapTimer;
00473     bool                m_switchTwoTapEngaged;
00474     bool                m_switchTwoTapArmed;
00475     SInt32              m_switchTwoTapZone;
00476 
00477     // modifiers needed before switching
00478     bool                m_switchNeedsShift;
00479     bool                m_switchNeedsControl;
00480     bool                m_switchNeedsAlt;
00481     
00482     // relative mouse move option
00483     bool                m_relativeMoves;
00484 
00485     // flag whether or not we have broadcasting enabled and the screens to
00486     // which we should send broadcasted keys.
00487     bool                m_keyboardBroadcasting;
00488     CString             m_keyboardBroadcastingScreens;
00489 
00490     // screen locking (former scroll lock)
00491     bool                m_lockedToScreen;
00492 
00493     // server screen
00494     CScreen*            m_screen;
00495 
00496     static CEvent::Type s_errorEvent;
00497     static CEvent::Type s_connectedEvent;
00498     static CEvent::Type s_disconnectedEvent;
00499     static CEvent::Type s_switchToScreen;
00500     static CEvent::Type s_switchInDirection;
00501     static CEvent::Type s_keyboardBroadcast;
00502     static CEvent::Type s_lockCursorToScreen;
00503     static CEvent::Type s_screenSwitched;
00504 };
00505 
00506 #endif

Generated on Fri May 24 2013 00:00:04 for Synergy by  doxygen 1.7.1