source: vendor/synergy/current/lib/server/CServer.h

Last change on this file was 2749, checked in by bird, 19 years ago

synergy v1.3.1 sources (zip).

File size: 13.1 KB
Line 
1/*
2 * synergy -- mouse and keyboard sharing utility
3 * Copyright (C) 2002 Chris Schoeneman
4 *
5 * This package is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * found in the file COPYING that should have accompanied this file.
8 *
9 * This package is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15#ifndef CSERVER_H
16#define CSERVER_H
17
18#include "CConfig.h"
19#include "CClipboard.h"
20#include "ClipboardTypes.h"
21#include "KeyTypes.h"
22#include "MouseTypes.h"
23#include "CEvent.h"
24#include "CStopwatch.h"
25#include "stdmap.h"
26#include "stdset.h"
27#include "stdvector.h"
28
29class CBaseClientProxy;
30class CEventQueueTimer;
31class CPrimaryClient;
32class CInputFilter;
33
34//! Synergy server
35/*!
36This class implements the top-level server algorithms for synergy.
37*/
38class CServer {
39public:
40 //! Lock cursor to screen data
41 class CLockCursorToScreenInfo {
42 public:
43 enum State { kOff, kOn, kToggle };
44
45 static CLockCursorToScreenInfo* alloc(State state = kToggle);
46
47 public:
48 State m_state;
49 };
50
51 //! Switch to screen data
52 class CSwitchToScreenInfo {
53 public:
54 static CSwitchToScreenInfo* alloc(const CString& screen);
55
56 public:
57 // this is a C-string; this type is a variable size structure
58 char m_screen[1];
59 };
60
61 //! Switch in direction data
62 class CSwitchInDirectionInfo {
63 public:
64 static CSwitchInDirectionInfo* alloc(EDirection direction);
65
66 public:
67 EDirection m_direction;
68 };
69
70 //! Screen connected data
71 class CScreenConnectedInfo {
72 public:
73 static CScreenConnectedInfo* alloc(const CString& screen);
74
75 public:
76 // this is a C-string; this type is a variable size structure
77 char m_screen[1];
78 };
79
80 /*!
81 Start the server with the configuration \p config and the primary
82 client (local screen) \p primaryClient. The client retains
83 ownership of \p primaryClient.
84 */
85 CServer(const CConfig& config, CPrimaryClient* primaryClient);
86 ~CServer();
87
88 //! @name manipulators
89 //@{
90
91 //! Set configuration
92 /*!
93 Change the server's configuration. Returns true iff the new
94 configuration was accepted (it must include the server's name).
95 This will disconnect any clients no longer in the configuration.
96 */
97 bool setConfig(const CConfig&);
98
99 //! Add a client
100 /*!
101 Adds \p client to the server. The client is adopted and will be
102 destroyed when the client disconnects or is disconnected.
103 */
104 void adoptClient(CBaseClientProxy* client);
105
106 //! Disconnect clients
107 /*!
108 Disconnect clients. This tells them to disconnect but does not wait
109 for them to actually do so. The server sends the disconnected event
110 when they're all disconnected (or immediately if none are connected).
111 The caller can also just destroy this object to force the disconnection.
112 */
113 void disconnect();
114
115 //@}
116 //! @name accessors
117 //@{
118
119 //! Get number of connected clients
120 /*!
121 Returns the number of connected clients, including the server itself.
122 */
123 UInt32 getNumClients() const;
124
125 //! Get the list of connected clients
126 /*!
127 Set the \c list to the names of the currently connected clients.
128 */
129 void getClients(std::vector<CString>& list) const;
130
131 //! Get error event type
132 /*!
133 Returns the error event type. This is sent when the server fails
134 for some reason.
135 */
136 static CEvent::Type getErrorEvent();
137
138 //! Get connected event type
139 /*!
140 Returns the connected event type. This is sent when a client screen
141 has connected. The event data is a \c CScreenConnectedInfo* that
142 indicates the connected screen.
143 */
144 static CEvent::Type getConnectedEvent();
145
146 //! Get disconnected event type
147 /*!
148 Returns the disconnected event type. This is sent when all the
149 clients have disconnected.
150 */
151 static CEvent::Type getDisconnectedEvent();
152
153 //! Get switch to screen event type
154 /*!
155 Returns the switch to screen event type. The server responds to this
156 by switching screens. The event data is a \c CSwitchToScreenInfo*
157 that indicates the target screen.
158 */
159 static CEvent::Type getSwitchToScreenEvent();
160
161 //! Get switch in direction event type
162 /*!
163 Returns the switch in direction event type. The server responds to this
164 by switching screens. The event data is a \c CSwitchInDirectionInfo*
165 that indicates the target direction.
166 */
167 static CEvent::Type getSwitchInDirectionEvent();
168
169 //! Get lock cursor event type
170 /*!
171 Returns the lock cursor event type. The server responds to this
172 by locking the cursor to the active screen or unlocking it. The
173 event data is a \c CLockCursorToScreenInfo*.
174 */
175 static CEvent::Type getLockCursorToScreenEvent();
176
177 //@}
178
179private:
180 // get canonical name of client
181 CString getName(const CBaseClientProxy*) const;
182
183 // get the sides of the primary screen that have neighbors
184 UInt32 getActivePrimarySides() const;
185
186 // returns true iff mouse should be locked to the current screen
187 // according to this object only, ignoring what the primary client
188 // says.
189 bool isLockedToScreenServer() const;
190
191 // returns true iff mouse should be locked to the current screen
192 // according to this object or the primary client.
193 bool isLockedToScreen() const;
194
195 // returns the jump zone of the client
196 SInt32 getJumpZoneSize(CBaseClientProxy*) const;
197
198 // change the active screen
199 void switchScreen(CBaseClientProxy*,
200 SInt32 x, SInt32 y, bool forScreenSaver);
201
202 // jump to screen
203 void jumpToScreen(CBaseClientProxy*);
204
205 // convert pixel position to fraction, using x or y depending on the
206 // direction.
207 float mapToFraction(CBaseClientProxy*, EDirection,
208 SInt32 x, SInt32 y) const;
209
210 // convert fraction to pixel position, writing only x or y depending
211 // on the direction.
212 void mapToPixel(CBaseClientProxy*, EDirection, float f,
213 SInt32& x, SInt32& y) const;
214
215 // returns true if the client has a neighbor anywhere along the edge
216 // indicated by the direction.
217 bool hasAnyNeighbor(CBaseClientProxy*, EDirection) const;
218
219 // lookup neighboring screen, mapping the coordinate independent of
220 // the direction to the neighbor's coordinate space.
221 CBaseClientProxy* getNeighbor(CBaseClientProxy*, EDirection,
222 SInt32& x, SInt32& y) const;
223
224 // lookup neighboring screen. given a position relative to the
225 // source screen, find the screen we should move onto and where.
226 // if the position is sufficiently far from the source then we
227 // cross multiple screens. if there is no suitable screen then
228 // return NULL and x,y are not modified.
229 CBaseClientProxy* mapToNeighbor(CBaseClientProxy*, EDirection,
230 SInt32& x, SInt32& y) const;
231
232 // adjusts x and y or neither to avoid ending up in a jump zone
233 // after entering the client in the given direction.
234 void avoidJumpZone(CBaseClientProxy*, EDirection,
235 SInt32& x, SInt32& y) const;
236
237 // test if a switch is permitted. this includes testing user
238 // options like switch delay and tracking any state required to
239 // implement them. returns true iff a switch is permitted.
240 bool isSwitchOkay(CBaseClientProxy* dst, EDirection,
241 SInt32 x, SInt32 y, SInt32 xActive, SInt32 yActive);
242
243 // update switch state due to a mouse move at \p x, \p y that
244 // doesn't switch screens.
245 void noSwitch(SInt32 x, SInt32 y);
246
247 // stop switch timers
248 void stopSwitch();
249
250 // start two tap switch timer
251 void startSwitchTwoTap();
252
253 // arm the two tap switch timer if \p x, \p y is outside the tap zone
254 void armSwitchTwoTap(SInt32 x, SInt32 y);
255
256 // stop the two tap switch timer
257 void stopSwitchTwoTap();
258
259 // returns true iff the two tap switch timer is started
260 bool isSwitchTwoTapStarted() const;
261
262 // returns true iff should switch because of two tap
263 bool shouldSwitchTwoTap() const;
264
265 // start delay switch timer
266 void startSwitchWait(SInt32 x, SInt32 y);
267
268 // stop delay switch timer
269 void stopSwitchWait();
270
271 // returns true iff the delay switch timer is started
272 bool isSwitchWaitStarted() const;
273
274 // returns the corner (EScreenSwitchCornerMasks) where x,y is on the
275 // given client. corners have the given size.
276 UInt32 getCorner(CBaseClientProxy*,
277 SInt32 x, SInt32 y, SInt32 size) const;
278
279 // stop relative mouse moves
280 void stopRelativeMoves();
281
282 // send screen options to \c client
283 void sendOptions(CBaseClientProxy* client) const;
284
285 // process options from configuration
286 void processOptions();
287
288 // event handlers
289 void handleShapeChanged(const CEvent&, void*);
290 void handleClipboardGrabbed(const CEvent&, void*);
291 void handleClipboardChanged(const CEvent&, void*);
292 void handleKeyDownEvent(const CEvent&, void*);
293 void handleKeyUpEvent(const CEvent&, void*);
294 void handleKeyRepeatEvent(const CEvent&, void*);
295 void handleButtonDownEvent(const CEvent&, void*);
296 void handleButtonUpEvent(const CEvent&, void*);
297 void handleMotionPrimaryEvent(const CEvent&, void*);
298 void handleMotionSecondaryEvent(const CEvent&, void*);
299 void handleWheelEvent(const CEvent&, void*);
300 void handleScreensaverActivatedEvent(const CEvent&, void*);
301 void handleScreensaverDeactivatedEvent(const CEvent&, void*);
302 void handleSwitchWaitTimeout(const CEvent&, void*);
303 void handleClientDisconnected(const CEvent&, void*);
304 void handleClientCloseTimeout(const CEvent&, void*);
305 void handleSwitchToScreenEvent(const CEvent&, void*);
306 void handleSwitchInDirectionEvent(const CEvent&, void*);
307 void handleLockCursorToScreenEvent(const CEvent&, void*);
308 void handleFakeInputBeginEvent(const CEvent&, void*);
309 void handleFakeInputEndEvent(const CEvent&, void*);
310
311 // event processing
312 void onClipboardChanged(CBaseClientProxy* sender,
313 ClipboardID id, UInt32 seqNum);
314 void onScreensaver(bool activated);
315 void onKeyDown(KeyID, KeyModifierMask, KeyButton,
316 const char* screens);
317 void onKeyUp(KeyID, KeyModifierMask, KeyButton,
318 const char* screens);
319 void onKeyRepeat(KeyID, KeyModifierMask, SInt32, KeyButton);
320 void onMouseDown(ButtonID);
321 void onMouseUp(ButtonID);
322 bool onMouseMovePrimary(SInt32 x, SInt32 y);
323 void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
324 void onMouseWheel(SInt32 xDelta, SInt32 yDelta);
325
326 // add client to list and attach event handlers for client
327 bool addClient(CBaseClientProxy*);
328
329 // remove client from list and detach event handlers for client
330 bool removeClient(CBaseClientProxy*);
331
332 // close a client
333 void closeClient(CBaseClientProxy*, const char* msg);
334
335 // close clients not in \p config
336 void closeClients(const CConfig& config);
337
338 // close all clients whether they've completed the handshake or not,
339 // except the primary client
340 void closeAllClients();
341
342 // remove clients from internal state
343 void removeActiveClient(CBaseClientProxy*);
344 void removeOldClient(CBaseClientProxy*);
345
346 // force the cursor off of \p client
347 void forceLeaveClient(CBaseClientProxy* client);
348
349private:
350 class CClipboardInfo {
351 public:
352 CClipboardInfo();
353
354 public:
355 CClipboard m_clipboard;
356 CString m_clipboardData;
357 CString m_clipboardOwner;
358 UInt32 m_clipboardSeqNum;
359 };
360
361 // the primary screen client
362 CPrimaryClient* m_primaryClient;
363
364 // all clients (including the primary client) indexed by name
365 typedef std::map<CString, CBaseClientProxy*> CClientList;
366 typedef std::set<CBaseClientProxy*> CClientSet;
367 CClientList m_clients;
368 CClientSet m_clientSet;
369
370 // all old connections that we're waiting to hangup
371 typedef std::map<CBaseClientProxy*, CEventQueueTimer*> COldClients;
372 COldClients m_oldClients;
373
374 // the client with focus
375 CBaseClientProxy* m_active;
376
377 // the sequence number of enter messages
378 UInt32 m_seqNum;
379
380 // current mouse position (in absolute screen coordinates) on
381 // whichever screen is active
382 SInt32 m_x, m_y;
383
384 // last mouse deltas. this is needed to smooth out double tap
385 // on win32 which reports bogus mouse motion at the edge of
386 // the screen when using low level hooks, synthesizing motion
387 // in the opposite direction the mouse actually moved.
388 SInt32 m_xDelta, m_yDelta;
389 SInt32 m_xDelta2, m_yDelta2;
390
391 // current configuration
392 CConfig m_config;
393
394 // input filter (from m_config);
395 CInputFilter* m_inputFilter;
396
397 // clipboard cache
398 CClipboardInfo m_clipboards[kClipboardEnd];
399
400 // state saved when screen saver activates
401 CBaseClientProxy* m_activeSaver;
402 SInt32 m_xSaver, m_ySaver;
403
404 // common state for screen switch tests. all tests are always
405 // trying to reach the same screen in the same direction.
406 EDirection m_switchDir;
407 CBaseClientProxy* m_switchScreen;
408
409 // state for delayed screen switching
410 double m_switchWaitDelay;
411 CEventQueueTimer* m_switchWaitTimer;
412 SInt32 m_switchWaitX, m_switchWaitY;
413
414 // state for double-tap screen switching
415 double m_switchTwoTapDelay;
416 CStopwatch m_switchTwoTapTimer;
417 bool m_switchTwoTapEngaged;
418 bool m_switchTwoTapArmed;
419 SInt32 m_switchTwoTapZone;
420
421 // relative mouse move option
422 bool m_relativeMoves;
423
424 // screen locking (former scroll lock)
425 bool m_lockedToScreen;
426
427 static CEvent::Type s_errorEvent;
428 static CEvent::Type s_connectedEvent;
429 static CEvent::Type s_disconnectedEvent;
430 static CEvent::Type s_switchToScreen;
431 static CEvent::Type s_switchInDirection;
432 static CEvent::Type s_lockCursorToScreen;
433};
434
435#endif
Note: See TracBrowser for help on using the repository browser.