Feature to drag a file from Windows (client) to Mac (server):

- changed the size of the window for dragging on Mac to 3 by 3 pixels.
- on server side, use a new thread to write file to the drop directory.
This commit is contained in:
jerry 2013-09-24 16:29:51 +00:00
parent e145fef76f
commit 4816a30db3
12 changed files with 126 additions and 55 deletions

View File

@ -38,6 +38,8 @@
#include "CArchMiscWindows.h" #include "CArchMiscWindows.h"
#include "CApp.h" #include "CApp.h"
#include "CArgsBase.h" #include "CArgsBase.h"
#include "CClientApp.h"
#include "CClient.h"
#include <string.h> #include <string.h>
#include <pbt.h> #include <pbt.h>
#include <Shlobj.h> #include <Shlobj.h>
@ -126,8 +128,9 @@ CMSWindowsScreen::CMSWindowsScreen(
try { try {
if (m_isPrimary && !m_noHooks) { if (m_isPrimary && !m_noHooks) {
m_hookLibrary = openHookLibrary("synwinhk"); m_hookLibrary = openHookLibrary("synwinhk");
m_shellLibrary = openShellLibrary("synwinxt");
} }
m_shellLibrary = openShellLibrary("synwinxt");
m_screensaver = new CMSWindowsScreenSaver(); m_screensaver = new CMSWindowsScreenSaver();
m_desks = new CMSWindowsDesks( m_desks = new CMSWindowsDesks(
m_isPrimary, m_noHooks, m_isPrimary, m_noHooks,
@ -359,6 +362,26 @@ CMSWindowsScreen::leave()
forceShowCursor(); forceShowCursor();
if (m_draggingStarted) { if (m_draggingStarted) {
CString& draggingDir = getDraggingFileDir();
LOG((CLOG_DEBUG "get dragging file dir: %s", draggingDir.c_str()));
size_t size = draggingDir.size();
if (!m_isPrimary) {
// TODO: fake these keys properly
fakeKeyDown(kKeyEscape, 8192, 1);
fakeKeyUp(1);
fakeMouseButton(kButtonLeft, false);
CClientApp& app = CClientApp::instance();
CClient* client = app.getClientPtr();
UInt32 fileCount = 1;
LOG((CLOG_DEBUG "send dragging info to server: %s", draggingDir.c_str()));
client->draggingInfoSending(fileCount, draggingDir, size);
LOG((CLOG_DEBUG "send dragging file to server"));
client->sendFileToServer(draggingDir.c_str());
}
m_draggingStarted = false; m_draggingStarted = false;
} }
@ -708,12 +731,26 @@ void
CMSWindowsScreen::fakeMouseButton(ButtonID id, bool press) CMSWindowsScreen::fakeMouseButton(ButtonID id, bool press)
{ {
m_desks->fakeMouseButton(id, press); m_desks->fakeMouseButton(id, press);
if (id == kButtonLeft) {
if (press) {
m_buttons[kButtonLeft] = true;
}
else {
m_buttons[kButtonLeft] = false;
m_fakeDraggingStarted = false;
m_draggingStarted = false;
}
}
} }
void void
CMSWindowsScreen::fakeMouseMove(SInt32 x, SInt32 y) CMSWindowsScreen::fakeMouseMove(SInt32 x, SInt32 y)
{ {
m_desks->fakeMouseMove(x, y); m_desks->fakeMouseMove(x, y);
if (m_buttons[kButtonLeft]) {
m_draggingStarted = true;
}
} }
void void

View File

@ -123,6 +123,7 @@ endif()
include_directories(${inc}) include_directories(${inc})
add_library(platform STATIC ${src}) add_library(platform STATIC ${src})
target_link_libraries(platform client ${libs})
if (UNIX) if (UNIX)
target_link_libraries(platform io net ipc synergy server client ${libs}) target_link_libraries(platform io net ipc synergy server client ${libs})

View File

@ -37,7 +37,7 @@ runCocoaApp()
g_app = app; g_app = app;
NSWindow* window = [[NSWindow alloc] NSWindow* window = [[NSWindow alloc]
initWithContentRect: NSMakeRect(0, 0, 100, 4) initWithContentRect: NSMakeRect(0, 0, 3, 3)
styleMask: NSBorderlessWindowMask styleMask: NSBorderlessWindowMask
backing: NSBackingStoreBuffered backing: NSBackingStoreBuffered
defer: NO]; defer: NO];
@ -45,7 +45,7 @@ runCocoaApp()
[window setAlphaValue:0.1]; [window setAlphaValue:0.1];
[window makeKeyAndOrderFront:nil]; [window makeKeyAndOrderFront:nil];
COSXDragView* dragView = [[COSXDragView alloc] initWithFrame:NSMakeRect(0, 0, 100, 4)]; COSXDragView* dragView = [[COSXDragView alloc] initWithFrame:NSMakeRect(0, 0, 3, 3)];
g_dragWindow = window; g_dragWindow = window;
g_dragView = dragView; g_dragView = dragView;
@ -74,24 +74,10 @@ fakeDragging(const char* str, int length, int cursorX, int cursorY)
int newPosX = 0; int newPosX = 0;
int newPosY = 0; int newPosY = 0;
if (cursorX == 0) { newPosX = cursorX - 1;
newPosX = cursorX - 99; newPosY = screen.size.height - cursorY - 1;
}
else if (cursorX == screen.size.width - 1) {
newPosX = cursorX - 1;
}
newPosY = screen.size.height - cursorY - 2;
if (cursorY == 0) { NSRect rect = NSMakeRect(newPosX, newPosY, 3, 3);
newPosY = screen.size.height - 1;
newPosX = cursorX - 50;
}
else if (cursorY == screen.size.height - 1) {
newPosY = 1;
newPosX = cursorX - 50;
}
NSRect rect = NSMakeRect(newPosX, newPosY, 100, 4);
NSLog ( @"newPosX: %d", newPosX); NSLog ( @"newPosX: %d", newPosX);
NSLog ( @"newPosY: %d", newPosY); NSLog ( @"newPosY: %d", newPosY);

View File

@ -102,7 +102,6 @@ COSXScreen::COSXScreen(IEventQueue* events, bool isPrimary, bool autoShowHideCur
m_eventTapRLSR(nullptr), m_eventTapRLSR(nullptr),
m_eventTapPort(nullptr), m_eventTapPort(nullptr),
m_pmRootPort(0), m_pmRootPort(0),
m_fakeDraggingStarted(false),
m_getDropTargetThread(NULL) m_getDropTargetThread(NULL)
{ {
try { try {
@ -601,7 +600,6 @@ COSXScreen::fakeMouseButton(ButtonID id, bool press)
this, &COSXScreen::getDropTargetThread)); this, &COSXScreen::getDropTargetThread));
} }
m_fakeDraggingStarted = false;
m_draggingStarted = false; m_draggingStarted = false;
} }
} }
@ -637,6 +635,7 @@ COSXScreen::getDropTargetThread(void*)
#else #else
LOG((CLOG_WARN "drag drop not supported")); LOG((CLOG_WARN "drag drop not supported"));
#endif #endif
m_fakeDraggingStarted = false;
} }
void void
@ -743,15 +742,6 @@ COSXScreen::showCursor()
} }
m_cursorHidden = false; m_cursorHidden = false;
if (m_fakeDraggingStarted) {
#if defined(MAC_OS_X_VERSION_10_7)
// TODO: use real file extension
fakeDragging("txt", 3, m_xCursor, m_yCursor);
#else
LOG((CLOG_WARN "drag drop not supported"));
#endif
}
} }
void void
@ -1234,6 +1224,11 @@ COSXScreen::onMouseButton(bool pressed, UInt16 macButton)
LOG((CLOG_DEBUG2 "dragging file directory is cleared")); LOG((CLOG_DEBUG2 "dragging file directory is cleared"));
} }
else { else {
if (m_fakeDraggingStarted) {
m_getDropTargetThread = new CThread(new TMethodJob<COSXScreen>(
this, &COSXScreen::getDropTargetThread));
}
m_draggingStarted = false; m_draggingStarted = false;
} }
} }
@ -2093,6 +2088,12 @@ void
COSXScreen::fakeDraggingFiles(CString str) COSXScreen::fakeDraggingFiles(CString str)
{ {
m_fakeDraggingStarted = true; m_fakeDraggingStarted = true;
#if defined(MAC_OS_X_VERSION_10_7)
// TODO: use real file extension
fakeDragging("txt", 3, m_xCursor, m_yCursor);
#else
LOG((CLOG_WARN "drag drop not supported"));
#endif
} }
CString& CString&

View File

@ -345,7 +345,6 @@ private:
IEventQueue* m_events; IEventQueue* m_events;
bool m_fakeDraggingStarted;
CThread* m_getDropTargetThread; CThread* m_getDropTargetThread;
CString m_dropTarget; CString m_dropTarget;
}; };

View File

@ -75,7 +75,8 @@ CServer::CServer(CConfig& config, CPrimaryClient* primaryClient, CScreen* screen
m_keyboardBroadcasting(false), m_keyboardBroadcasting(false),
m_lockedToScreen(false), m_lockedToScreen(false),
m_screen(screen), m_screen(screen),
m_sendFileThread(NULL) m_sendFileThread(NULL),
m_writeToDropDir(NULL)
{ {
// must have a primary client and it must have a canonical name // must have a primary client and it must have a canonical name
assert(m_primaryClient != NULL); assert(m_primaryClient != NULL);
@ -1957,27 +1958,42 @@ void
CServer::onFileRecieveCompleted() CServer::onFileRecieveCompleted()
{ {
if (isReceivedFileSizeValid()) { if (isReceivedFileSizeValid()) {
m_fileTransferDes = m_screen->getDropTarget(); m_writeToDropDir = new CThread(
if (!m_fileTransferDes.empty() && m_dragFileList.size() > 0) { new TMethodJob<CServer>(
std::fstream file; this, &CServer::writeToDropDirThread));
CString dropTarget = m_fileTransferDes; }
#ifdef SYSAPI_WIN32 }
dropTarget.append("\\");
#else
dropTarget.append("/");
#endif
dropTarget.append(m_dragFileList.at(0));
file.open(dropTarget.c_str(), std::ios::out | std::ios::binary);
if (!file.is_open()) {
// TODO: file open failed
}
file.write(m_receivedFileData.c_str(), m_receivedFileData.size()); void
file.close(); CServer::writeToDropDirThread(void*)
} {
else { while (m_screen->getFakeDraggingStarted()) {
LOG((CLOG_ERR "drop file failed: drop target is empty")); LOG((CLOG_DEBUG "write to drop dir: fakeDraggingStarted = true"));
ARCH->sleep(.1f);
}
LOG((CLOG_DEBUG "write to drop dir: fakeDraggingStarted = false"));
m_fileTransferDes = m_screen->getDropTarget();
if (!m_fileTransferDes.empty() && m_dragFileList.size() > 0) {
std::fstream file;
CString dropTarget = m_fileTransferDes;
#ifdef SYSAPI_WIN32
dropTarget.append("\\");
#else
dropTarget.append("/");
#endif
dropTarget.append(m_dragFileList.at(0));
file.open(dropTarget.c_str(), std::ios::out | std::ios::binary);
if (!file.is_open()) {
// TODO: file open failed
} }
file.write(m_receivedFileData.c_str(), m_receivedFileData.size());
file.close();
}
else {
LOG((CLOG_ERR "drop file failed: drop target is empty"));
} }
} }
@ -2309,8 +2325,20 @@ CServer::dragInfoReceived(UInt32 fileNum, CString content)
LOG((CLOG_DEBUG "total drag file number: %i", m_dragFileList.size())); LOG((CLOG_DEBUG "total drag file number: %i", m_dragFileList.size()));
for(int i = 0; i < m_dragFileList.size(); ++i) { for(int i = 0; i < m_dragFileList.size(); ++i) {
LOG((CLOG_DEBUG2 "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str())); LOG((CLOG_DEBUG "dragging file %i name: %s", i + 1, m_dragFileList.at(i).c_str()));
} }
if (m_dragFileList.size() == 1) {
m_dragFileExt = CDragInformation::getDragFileExtension(m_dragFileList.at(0));
}
else if (m_dragFileList.size() > 1) {
m_dragFileExt.clear();
}
else {
return;
}
m_screen->startDraggingFiles(m_dragFileExt);
} }
void void

View File

@ -363,6 +363,9 @@ private:
// thread funciton for sending file // thread funciton for sending file
void sendFileThread(void*); void sendFileThread(void*);
// thread function for writing file to drop directory
void writeToDropDirThread(void*);
public: public:
bool m_mock; bool m_mock;
@ -466,6 +469,8 @@ private:
CString m_fileTransferDes; CString m_fileTransferDes;
CDragFileList m_dragFileList; CDragFileList m_dragFileList;
CThread* m_sendFileThread; CThread* m_sendFileThread;
CThread* m_writeToDropDir;
CString m_dragFileExt;
}; };
#endif #endif

View File

@ -20,7 +20,8 @@
CPlatformScreen::CPlatformScreen(IEventQueue* events) : CPlatformScreen::CPlatformScreen(IEventQueue* events) :
IPlatformScreen(events), IPlatformScreen(events),
m_draggingStarted(false) m_draggingStarted(false),
m_fakeDraggingStarted(false)
{ {
} }

View File

@ -79,6 +79,7 @@ public:
virtual void setDraggingStarted(bool started) { m_draggingStarted = started; } virtual void setDraggingStarted(bool started) { m_draggingStarted = started; }
virtual bool getDraggingStarted() { return m_draggingStarted; } virtual bool getDraggingStarted() { return m_draggingStarted; }
virtual bool getFakeDraggingStarted() { return m_fakeDraggingStarted; }
virtual CString& getDraggingFileDir() { return m_draggingFileDir; } virtual CString& getDraggingFileDir() { return m_draggingFileDir; }
// IPlatformScreen overrides // IPlatformScreen overrides
@ -121,6 +122,7 @@ protected:
protected: protected:
CString m_draggingFileDir; CString m_draggingFileDir;
bool m_draggingStarted; bool m_draggingStarted;
bool m_fakeDraggingStarted;
}; };
#endif #endif

View File

@ -415,6 +415,12 @@ CScreen::getDraggingStarted() const
return m_screen->getDraggingStarted(); return m_screen->getDraggingStarted();
} }
bool
CScreen::getFakeDraggingStarted() const
{
return m_screen->getFakeDraggingStarted();
}
void void
CScreen::setDraggingStarted(bool started) CScreen::setDraggingStarted(bool started)
{ {

View File

@ -273,10 +273,14 @@ public:
*/ */
KeyModifierMask pollActiveModifiers() const; KeyModifierMask pollActiveModifiers() const;
//! Check if dragging has started. //! Check if a local dragging has started.
bool getDraggingStarted() const; bool getDraggingStarted() const;
//! Check if a fake dragging has started.
bool getFakeDraggingStarted() const;
//! Get dragging file's directory. //! Get dragging file's directory.
CString& getDraggingFileDir() const; CString& getDraggingFileDir() const;

View File

@ -190,6 +190,7 @@ public:
virtual CString& getDraggingFileDir() = 0; virtual CString& getDraggingFileDir() = 0;
virtual bool getDraggingStarted() = 0; virtual bool getDraggingStarted() = 0;
virtual bool getFakeDraggingStarted() = 0;
virtual void fakeDraggingFiles(CString str) = 0; virtual void fakeDraggingFiles(CString str) = 0;
virtual const CString& virtual const CString&