2012-06-10 16:50:54 +00:00
|
|
|
/*
|
2024-09-17 19:00:25 +00:00
|
|
|
* Deskflow -- mouse and keyboard sharing utility
|
2024-09-02 22:48:57 +00:00
|
|
|
* Copyright (C) 2012 Symless Ltd.
|
2012-09-04 02:09:56 +00:00
|
|
|
* Copyright (C) 2002 Chris Schoeneman
|
2024-07-02 19:07:06 +00:00
|
|
|
*
|
2012-06-10 16:50:54 +00:00
|
|
|
* This package is free software; you can redistribute it and/or
|
|
|
|
|
* modify it under the terms of the GNU General Public License
|
2015-05-03 02:33:52 +00:00
|
|
|
* found in the file LICENSE that should have accompanied this file.
|
2024-07-02 19:07:06 +00:00
|
|
|
*
|
2012-06-10 16:50:54 +00:00
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2014-02-28 12:36:45 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "base/Event.h"
|
|
|
|
|
#include "base/EventTypes.h"
|
2024-07-02 19:07:06 +00:00
|
|
|
#include "base/Stopwatch.h"
|
2014-02-28 12:36:45 +00:00
|
|
|
#include "common/stdmap.h"
|
|
|
|
|
#include "common/stdset.h"
|
|
|
|
|
#include "common/stdvector.h"
|
2024-09-17 19:00:25 +00:00
|
|
|
#include "deskflow/Clipboard.h"
|
|
|
|
|
#include "deskflow/DragInformation.h"
|
|
|
|
|
#include "deskflow/INode.h"
|
|
|
|
|
#include "deskflow/ServerArgs.h"
|
|
|
|
|
#include "deskflow/clipboard_types.h"
|
|
|
|
|
#include "deskflow/key_types.h"
|
|
|
|
|
#include "deskflow/mouse_types.h"
|
2024-07-02 19:07:06 +00:00
|
|
|
#include "server/Config.h"
|
2022-05-19 15:29:11 +00:00
|
|
|
#include <memory>
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2014-11-11 13:51:47 +00:00
|
|
|
class BaseClientProxy;
|
|
|
|
|
class EventQueueTimer;
|
|
|
|
|
class PrimaryClient;
|
|
|
|
|
class InputFilter;
|
2024-09-17 19:00:25 +00:00
|
|
|
namespace deskflow {
|
2024-07-02 19:07:06 +00:00
|
|
|
class Screen;
|
|
|
|
|
}
|
2013-06-29 14:17:49 +00:00
|
|
|
class IEventQueue;
|
2014-11-11 13:51:47 +00:00
|
|
|
class Thread;
|
2015-01-28 13:07:03 +00:00
|
|
|
class ClientListener;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-09-17 19:00:25 +00:00
|
|
|
//! Deskflow server
|
2012-06-10 16:50:54 +00:00
|
|
|
/*!
|
2024-09-17 19:00:25 +00:00
|
|
|
This class implements the top-level server algorithms for deskflow.
|
2012-06-10 16:50:54 +00:00
|
|
|
*/
|
2014-11-11 13:51:47 +00:00
|
|
|
class Server : public INode {
|
2024-09-17 19:00:25 +00:00
|
|
|
using ServerConfig = deskflow::server::Config;
|
2024-09-02 22:48:57 +00:00
|
|
|
|
2012-06-10 16:50:54 +00:00
|
|
|
public:
|
2024-07-02 19:07:06 +00:00
|
|
|
//! Lock cursor to screen data
|
|
|
|
|
class LockCursorToScreenInfo {
|
|
|
|
|
public:
|
|
|
|
|
enum State { kOff, kOn, kToggle };
|
|
|
|
|
|
|
|
|
|
static LockCursorToScreenInfo *alloc(State state = kToggle);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
State m_state;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//! Switch to screen data
|
|
|
|
|
class SwitchToScreenInfo {
|
|
|
|
|
public:
|
|
|
|
|
static SwitchToScreenInfo *alloc(const String &screen);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// this is a C-string; this type is a variable size structure
|
|
|
|
|
char m_screen[1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//! Switch in direction data
|
|
|
|
|
class SwitchInDirectionInfo {
|
|
|
|
|
public:
|
|
|
|
|
static SwitchInDirectionInfo *alloc(EDirection direction);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
EDirection m_direction;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//! Screen connected data
|
|
|
|
|
class ScreenConnectedInfo {
|
|
|
|
|
public:
|
|
|
|
|
ScreenConnectedInfo(String screen) : m_screen(screen) {}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
String m_screen; // was char[1]
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//! Keyboard broadcast data
|
|
|
|
|
class KeyboardBroadcastInfo {
|
|
|
|
|
public:
|
|
|
|
|
enum State { kOff, kOn, kToggle };
|
|
|
|
|
|
|
|
|
|
static KeyboardBroadcastInfo *alloc(State state = kToggle);
|
|
|
|
|
static KeyboardBroadcastInfo *alloc(State state, const String &screens);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
State m_state;
|
|
|
|
|
char m_screens[1];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
Start the server with the configuration \p config and the primary
|
|
|
|
|
client (local screen) \p primaryClient. The client retains
|
|
|
|
|
ownership of \p primaryClient.
|
|
|
|
|
*/
|
2024-07-16 13:36:44 +00:00
|
|
|
Server(
|
2024-09-02 22:48:57 +00:00
|
|
|
ServerConfig &config, PrimaryClient *primaryClient,
|
2024-09-17 19:00:25 +00:00
|
|
|
deskflow::Screen *screen, IEventQueue *events,
|
|
|
|
|
deskflow::ServerArgs const &args);
|
2024-07-02 19:07:06 +00:00
|
|
|
Server(Server const &) = delete;
|
|
|
|
|
Server(Server &&) = delete;
|
|
|
|
|
~Server();
|
|
|
|
|
|
|
|
|
|
Server &operator=(Server const &) = delete;
|
|
|
|
|
Server &operator=(Server &&) = delete;
|
2020-11-03 10:52:56 +00:00
|
|
|
|
2013-04-09 18:56:19 +00:00
|
|
|
#ifdef TEST_ENV
|
2024-07-02 19:07:06 +00:00
|
|
|
Server() : m_mock(true), m_config(NULL) {}
|
|
|
|
|
void setActive(BaseClientProxy *active) { m_active = active; }
|
2013-04-09 18:56:19 +00:00
|
|
|
#endif
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
//! @name manipulators
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
//! Set configuration
|
|
|
|
|
/*!
|
|
|
|
|
Change the server's configuration. Returns true iff the new
|
|
|
|
|
configuration was accepted (it must include the server's name).
|
|
|
|
|
This will disconnect any clients no longer in the configuration.
|
|
|
|
|
*/
|
2024-09-02 22:48:57 +00:00
|
|
|
bool setConfig(const ServerConfig &);
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
//! Add a client
|
|
|
|
|
/*!
|
|
|
|
|
Adds \p client to the server. The client is adopted and will be
|
|
|
|
|
destroyed when the client disconnects or is disconnected.
|
|
|
|
|
*/
|
|
|
|
|
void adoptClient(BaseClientProxy *client);
|
|
|
|
|
|
|
|
|
|
//! Disconnect clients
|
|
|
|
|
/*!
|
|
|
|
|
Disconnect clients. This tells them to disconnect but does not wait
|
|
|
|
|
for them to actually do so. The server sends the disconnected event
|
|
|
|
|
when they're all disconnected (or immediately if none are connected).
|
|
|
|
|
The caller can also just destroy this object to force the disconnection.
|
|
|
|
|
*/
|
|
|
|
|
void disconnect();
|
|
|
|
|
|
|
|
|
|
//! Create a new thread and use it to send file to client
|
|
|
|
|
void sendFileToClient(const char *filename);
|
|
|
|
|
|
|
|
|
|
//! Received dragging information from client
|
|
|
|
|
void dragInfoReceived(UInt32 fileNum, String content);
|
|
|
|
|
|
|
|
|
|
//! Store ClientListener pointer
|
|
|
|
|
void setListener(ClientListener *p) { m_clientListener = p; }
|
|
|
|
|
|
|
|
|
|
//@}
|
|
|
|
|
//! @name accessors
|
|
|
|
|
//@{
|
|
|
|
|
|
|
|
|
|
//! Get number of connected clients
|
|
|
|
|
/*!
|
|
|
|
|
Returns the number of connected clients, including the server itself.
|
|
|
|
|
*/
|
|
|
|
|
UInt32 getNumClients() const;
|
|
|
|
|
|
|
|
|
|
//! Get the list of connected clients
|
|
|
|
|
/*!
|
|
|
|
|
Set the \c list to the names of the currently connected clients.
|
|
|
|
|
*/
|
|
|
|
|
void getClients(std::vector<String> &list) const;
|
|
|
|
|
|
|
|
|
|
//! Return true if recieved file size is valid
|
|
|
|
|
bool isReceivedFileSizeValid();
|
|
|
|
|
|
|
|
|
|
//! Return expected file data size
|
|
|
|
|
size_t &getExpectedFileSize() { return m_expectedFileSize; }
|
|
|
|
|
|
|
|
|
|
//! Return received file data
|
|
|
|
|
String &getReceivedFileData() { return m_receivedFileData; }
|
|
|
|
|
|
|
|
|
|
//! Return fake drag file list
|
|
|
|
|
DragFileList getFakeDragFileList() { return m_fakeDragFileList; }
|
|
|
|
|
|
|
|
|
|
//! Returns true if it's client mode and server initiates connection
|
|
|
|
|
bool isClientMode() const;
|
|
|
|
|
|
|
|
|
|
//@}
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
|
private:
|
2024-07-02 19:07:06 +00:00
|
|
|
// get canonical name of client
|
|
|
|
|
String getName(const BaseClientProxy *) const;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// get the sides of the primary screen that have neighbors
|
|
|
|
|
UInt32 getActivePrimarySides() const;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// returns true iff mouse should be locked to the current screen
|
|
|
|
|
// according to this object only, ignoring what the primary client
|
|
|
|
|
// says.
|
|
|
|
|
bool isLockedToScreenServer() const;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// returns true iff mouse should be locked to the current screen
|
|
|
|
|
// according to this object or the primary client.
|
|
|
|
|
bool isLockedToScreen() const;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
2024-07-02 19:07:06 +00:00
|
|
|
// returns the jump zone of the client
|
|
|
|
|
SInt32 getJumpZoneSize(BaseClientProxy *) const;
|
|
|
|
|
|
|
|
|
|
// change the active screen
|
|
|
|
|
void switchScreen(BaseClientProxy *, SInt32 x, SInt32 y, bool forScreenSaver);
|
|
|
|
|
|
|
|
|
|
// jump to screen
|
|
|
|
|
void jumpToScreen(BaseClientProxy *);
|
|
|
|
|
|
|
|
|
|
// convert pixel position to fraction, using x or y depending on the
|
|
|
|
|
// direction.
|
|
|
|
|
float mapToFraction(BaseClientProxy *, EDirection, SInt32 x, SInt32 y) const;
|
|
|
|
|
|
|
|
|
|
// convert fraction to pixel position, writing only x or y depending
|
|
|
|
|
// on the direction.
|
2024-07-16 13:36:44 +00:00
|
|
|
void mapToPixel(
|
|
|
|
|
BaseClientProxy *, EDirection, float f, SInt32 &x, SInt32 &y) const;
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
// returns true if the client has a neighbor anywhere along the edge
|
|
|
|
|
// indicated by the direction.
|
|
|
|
|
bool hasAnyNeighbor(BaseClientProxy *, EDirection) const;
|
|
|
|
|
|
|
|
|
|
// lookup neighboring screen, mapping the coordinate independent of
|
|
|
|
|
// the direction to the neighbor's coordinate space.
|
2024-07-16 13:36:44 +00:00
|
|
|
BaseClientProxy *
|
|
|
|
|
getNeighbor(BaseClientProxy *, EDirection, SInt32 &x, SInt32 &y) const;
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
// lookup neighboring screen. given a position relative to the
|
|
|
|
|
// source screen, find the screen we should move onto and where.
|
|
|
|
|
// if the position is sufficiently far from the source then we
|
|
|
|
|
// cross multiple screens. if there is no suitable screen then
|
|
|
|
|
// return NULL and x,y are not modified.
|
2024-07-16 13:36:44 +00:00
|
|
|
BaseClientProxy *
|
|
|
|
|
mapToNeighbor(BaseClientProxy *, EDirection, SInt32 &x, SInt32 &y) const;
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
// adjusts x and y or neither to avoid ending up in a jump zone
|
|
|
|
|
// after entering the client in the given direction.
|
|
|
|
|
void avoidJumpZone(BaseClientProxy *, EDirection, SInt32 &x, SInt32 &y) const;
|
|
|
|
|
|
|
|
|
|
// test if a switch is permitted. this includes testing user
|
|
|
|
|
// options like switch delay and tracking any state required to
|
|
|
|
|
// implement them. returns true iff a switch is permitted.
|
2024-07-16 13:36:44 +00:00
|
|
|
bool isSwitchOkay(
|
|
|
|
|
BaseClientProxy *dst, EDirection, SInt32 x, SInt32 y, SInt32 xActive,
|
|
|
|
|
SInt32 yActive);
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
// update switch state due to a mouse move at \p x, \p y that
|
|
|
|
|
// doesn't switch screens.
|
|
|
|
|
void noSwitch(SInt32 x, SInt32 y);
|
|
|
|
|
|
|
|
|
|
// stop switch timers
|
|
|
|
|
void stopSwitch();
|
|
|
|
|
|
|
|
|
|
// start two tap switch timer
|
|
|
|
|
void startSwitchTwoTap();
|
|
|
|
|
|
|
|
|
|
// arm the two tap switch timer if \p x, \p y is outside the tap zone
|
|
|
|
|
void armSwitchTwoTap(SInt32 x, SInt32 y);
|
|
|
|
|
|
|
|
|
|
// stop the two tap switch timer
|
|
|
|
|
void stopSwitchTwoTap();
|
|
|
|
|
|
|
|
|
|
// returns true iff the two tap switch timer is started
|
|
|
|
|
bool isSwitchTwoTapStarted() const;
|
|
|
|
|
|
|
|
|
|
// returns true iff should switch because of two tap
|
|
|
|
|
bool shouldSwitchTwoTap() const;
|
|
|
|
|
|
|
|
|
|
// start delay switch timer
|
|
|
|
|
void startSwitchWait(SInt32 x, SInt32 y);
|
|
|
|
|
|
|
|
|
|
// stop delay switch timer
|
|
|
|
|
void stopSwitchWait();
|
|
|
|
|
|
|
|
|
|
// returns true iff the delay switch timer is started
|
|
|
|
|
bool isSwitchWaitStarted() const;
|
|
|
|
|
|
|
|
|
|
// returns the corner (EScreenSwitchCornerMasks) where x,y is on the
|
|
|
|
|
// given client. corners have the given size.
|
|
|
|
|
UInt32 getCorner(BaseClientProxy *, SInt32 x, SInt32 y, SInt32 size) const;
|
|
|
|
|
|
|
|
|
|
// stop relative mouse moves
|
|
|
|
|
void stopRelativeMoves();
|
|
|
|
|
|
|
|
|
|
// send screen options to \c client
|
|
|
|
|
void sendOptions(BaseClientProxy *client) const;
|
|
|
|
|
|
|
|
|
|
// process options from configuration
|
|
|
|
|
void processOptions();
|
|
|
|
|
|
|
|
|
|
// event handlers
|
|
|
|
|
void handleShapeChanged(const Event &, void *);
|
|
|
|
|
void handleClipboardGrabbed(const Event &, void *);
|
|
|
|
|
void handleClipboardChanged(const Event &, void *);
|
|
|
|
|
void handleKeyDownEvent(const Event &, void *);
|
|
|
|
|
void handleKeyUpEvent(const Event &, void *);
|
|
|
|
|
void handleKeyRepeatEvent(const Event &, void *);
|
|
|
|
|
void handleButtonDownEvent(const Event &, void *);
|
|
|
|
|
void handleButtonUpEvent(const Event &, void *);
|
|
|
|
|
void handleMotionPrimaryEvent(const Event &, void *);
|
|
|
|
|
void handleMotionSecondaryEvent(const Event &, void *);
|
|
|
|
|
void handleWheelEvent(const Event &, void *);
|
|
|
|
|
void handleScreensaverActivatedEvent(const Event &, void *);
|
|
|
|
|
void handleScreensaverDeactivatedEvent(const Event &, void *);
|
|
|
|
|
void handleSwitchWaitTimeout(const Event &, void *);
|
|
|
|
|
void handleClientDisconnected(const Event &, void *);
|
|
|
|
|
void handleClientCloseTimeout(const Event &, void *);
|
|
|
|
|
void handleSwitchToScreenEvent(const Event &, void *);
|
|
|
|
|
void handleSwitchInDirectionEvent(const Event &, void *);
|
|
|
|
|
void handleKeyboardBroadcastEvent(const Event &, void *);
|
|
|
|
|
void handleLockCursorToScreenEvent(const Event &, void *);
|
|
|
|
|
void handleFakeInputBeginEvent(const Event &, void *);
|
|
|
|
|
void handleFakeInputEndEvent(const Event &, void *);
|
|
|
|
|
void handleFileChunkSendingEvent(const Event &, void *);
|
|
|
|
|
void handleFileRecieveCompletedEvent(const Event &, void *);
|
|
|
|
|
|
|
|
|
|
// event processing
|
2024-07-16 13:36:44 +00:00
|
|
|
void
|
|
|
|
|
onClipboardChanged(BaseClientProxy *sender, ClipboardID id, UInt32 seqNum);
|
2024-07-02 19:07:06 +00:00
|
|
|
void onScreensaver(bool activated);
|
2024-07-16 13:36:44 +00:00
|
|
|
void onKeyDown(
|
|
|
|
|
KeyID, KeyModifierMask, KeyButton, const String &, const char *screens);
|
2024-07-02 19:07:06 +00:00
|
|
|
void onKeyUp(KeyID, KeyModifierMask, KeyButton, const char *screens);
|
|
|
|
|
void onKeyRepeat(KeyID, KeyModifierMask, SInt32, KeyButton, const String &);
|
|
|
|
|
void onMouseDown(ButtonID);
|
|
|
|
|
void onMouseUp(ButtonID);
|
|
|
|
|
bool onMouseMovePrimary(SInt32 x, SInt32 y);
|
|
|
|
|
void onMouseMoveSecondary(SInt32 dx, SInt32 dy);
|
|
|
|
|
void onMouseWheel(SInt32 xDelta, SInt32 yDelta);
|
|
|
|
|
void onFileChunkSending(const void *data);
|
|
|
|
|
void onFileRecieveCompleted();
|
|
|
|
|
|
|
|
|
|
// add client to list and attach event handlers for client
|
|
|
|
|
bool addClient(BaseClientProxy *);
|
|
|
|
|
|
|
|
|
|
// remove client from list and detach event handlers for client
|
|
|
|
|
bool removeClient(BaseClientProxy *);
|
|
|
|
|
|
|
|
|
|
// close a client
|
|
|
|
|
void closeClient(BaseClientProxy *, const char *msg);
|
|
|
|
|
|
|
|
|
|
// close clients not in \p config
|
2024-09-02 22:48:57 +00:00
|
|
|
void closeClients(const ServerConfig &config);
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
// close all clients whether they've completed the handshake or not,
|
|
|
|
|
// except the primary client
|
|
|
|
|
void closeAllClients();
|
|
|
|
|
|
|
|
|
|
// remove clients from internal state
|
|
|
|
|
void removeActiveClient(BaseClientProxy *);
|
|
|
|
|
void removeOldClient(BaseClientProxy *);
|
|
|
|
|
|
|
|
|
|
// force the cursor off of \p client
|
|
|
|
|
void forceLeaveClient(BaseClientProxy *client);
|
|
|
|
|
|
|
|
|
|
// thread funciton for sending file
|
|
|
|
|
void sendFileThread(void *);
|
|
|
|
|
|
|
|
|
|
// thread function for writing file to drop directory
|
|
|
|
|
void writeToDropDirThread(void *);
|
|
|
|
|
|
|
|
|
|
// thread function for sending drag information
|
|
|
|
|
void sendDragInfoThread(void *);
|
|
|
|
|
|
|
|
|
|
// send drag info to new client screen
|
|
|
|
|
void sendDragInfo(BaseClientProxy *newScreen);
|
2014-04-22 10:33:16 +00:00
|
|
|
|
2013-04-09 18:56:19 +00:00
|
|
|
public:
|
2024-07-02 19:07:06 +00:00
|
|
|
bool m_mock;
|
2012-06-10 16:50:54 +00:00
|
|
|
|
|
|
|
|
private:
|
2024-07-02 19:07:06 +00:00
|
|
|
class ClipboardInfo {
|
|
|
|
|
public:
|
|
|
|
|
ClipboardInfo();
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Clipboard m_clipboard;
|
|
|
|
|
String m_clipboardData;
|
|
|
|
|
String m_clipboardOwner;
|
|
|
|
|
UInt32 m_clipboardSeqNum;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// the primary screen client
|
|
|
|
|
PrimaryClient *m_primaryClient;
|
|
|
|
|
|
|
|
|
|
// all clients (including the primary client) indexed by name
|
|
|
|
|
typedef std::map<String, BaseClientProxy *> ClientList;
|
|
|
|
|
typedef std::set<BaseClientProxy *> ClientSet;
|
|
|
|
|
ClientList m_clients;
|
|
|
|
|
ClientSet m_clientSet;
|
|
|
|
|
|
|
|
|
|
// all old connections that we're waiting to hangup
|
|
|
|
|
typedef std::map<BaseClientProxy *, EventQueueTimer *> OldClients;
|
|
|
|
|
OldClients m_oldClients;
|
|
|
|
|
|
|
|
|
|
// the client with focus
|
|
|
|
|
BaseClientProxy *m_active;
|
|
|
|
|
|
|
|
|
|
// the sequence number of enter messages
|
|
|
|
|
UInt32 m_seqNum;
|
|
|
|
|
|
|
|
|
|
// current mouse position (in absolute screen coordinates) on
|
|
|
|
|
// whichever screen is active
|
|
|
|
|
SInt32 m_x, m_y;
|
|
|
|
|
|
|
|
|
|
// last mouse deltas. this is needed to smooth out double tap
|
|
|
|
|
// on win32 which reports bogus mouse motion at the edge of
|
|
|
|
|
// the screen when using low level hooks, synthesizing motion
|
|
|
|
|
// in the opposite direction the mouse actually moved.
|
|
|
|
|
SInt32 m_xDelta, m_yDelta;
|
|
|
|
|
SInt32 m_xDelta2, m_yDelta2;
|
|
|
|
|
|
|
|
|
|
// current configuration
|
2024-09-02 22:48:57 +00:00
|
|
|
ServerConfig *m_config;
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
// input filter (from m_config);
|
|
|
|
|
InputFilter *m_inputFilter;
|
|
|
|
|
|
|
|
|
|
// clipboard cache
|
|
|
|
|
ClipboardInfo m_clipboards[kClipboardEnd];
|
|
|
|
|
|
|
|
|
|
// state saved when screen saver activates
|
|
|
|
|
BaseClientProxy *m_activeSaver;
|
|
|
|
|
SInt32 m_xSaver, m_ySaver;
|
|
|
|
|
|
|
|
|
|
// common state for screen switch tests. all tests are always
|
|
|
|
|
// trying to reach the same screen in the same direction.
|
|
|
|
|
EDirection m_switchDir;
|
|
|
|
|
BaseClientProxy *m_switchScreen;
|
|
|
|
|
|
|
|
|
|
// state for delayed screen switching
|
|
|
|
|
double m_switchWaitDelay;
|
|
|
|
|
EventQueueTimer *m_switchWaitTimer;
|
|
|
|
|
SInt32 m_switchWaitX, m_switchWaitY;
|
|
|
|
|
|
|
|
|
|
// state for double-tap screen switching
|
|
|
|
|
double m_switchTwoTapDelay;
|
|
|
|
|
Stopwatch m_switchTwoTapTimer;
|
|
|
|
|
bool m_switchTwoTapEngaged;
|
|
|
|
|
bool m_switchTwoTapArmed;
|
|
|
|
|
SInt32 m_switchTwoTapZone;
|
|
|
|
|
|
|
|
|
|
// modifiers needed before switching
|
|
|
|
|
bool m_switchNeedsShift;
|
|
|
|
|
bool m_switchNeedsControl;
|
|
|
|
|
bool m_switchNeedsAlt;
|
|
|
|
|
|
|
|
|
|
// relative mouse move option
|
|
|
|
|
bool m_relativeMoves;
|
|
|
|
|
|
|
|
|
|
// flag whether or not we have broadcasting enabled and the screens to
|
|
|
|
|
// which we should send broadcasted keys.
|
|
|
|
|
bool m_keyboardBroadcasting;
|
|
|
|
|
String m_keyboardBroadcastingScreens;
|
|
|
|
|
|
|
|
|
|
// screen locking (former scroll lock)
|
|
|
|
|
bool m_lockedToScreen;
|
|
|
|
|
|
|
|
|
|
// server screen
|
2024-09-17 19:00:25 +00:00
|
|
|
deskflow::Screen *m_screen;
|
2024-07-02 19:07:06 +00:00
|
|
|
|
|
|
|
|
IEventQueue *m_events;
|
|
|
|
|
|
|
|
|
|
// file transfer
|
|
|
|
|
using AutoThread = std::unique_ptr<Thread>;
|
|
|
|
|
size_t m_expectedFileSize;
|
|
|
|
|
String m_receivedFileData;
|
|
|
|
|
DragFileList m_dragFileList;
|
|
|
|
|
DragFileList m_fakeDragFileList;
|
|
|
|
|
AutoThread m_sendFileThread;
|
|
|
|
|
AutoThread m_writeToDropDirThread;
|
|
|
|
|
String m_dragFileExt;
|
|
|
|
|
bool m_ignoreFileTransfer;
|
|
|
|
|
bool m_disableLockToScreen;
|
|
|
|
|
bool m_enableClipboard;
|
|
|
|
|
size_t m_maximumClipboardSize;
|
|
|
|
|
|
|
|
|
|
AutoThread m_sendDragInfoThread;
|
|
|
|
|
bool m_waitDragInfoThread;
|
|
|
|
|
|
|
|
|
|
ClientListener *m_clientListener;
|
2024-09-17 19:00:25 +00:00
|
|
|
deskflow::ServerArgs m_args;
|
2012-06-10 16:50:54 +00:00
|
|
|
};
|