diff --git a/src/lib/client/Client.cpp b/src/lib/client/Client.cpp index 61c2d030..1d2d3d62 100644 --- a/src/lib/client/Client.cpp +++ b/src/lib/client/Client.cpp @@ -757,7 +757,7 @@ CClient::writeToDropDirThread(void*) #else dropTarget.append("/"); #endif - dropTarget.append(m_dragFileList.at(0)); + dropTarget.append(m_dragFileList.at(0).getFilename()); file.open(dropTarget.c_str(), std::ios::out | std::ios::binary); if (!file.is_open()) { // TODO: file open failed @@ -833,7 +833,7 @@ CClient::sendFileThread(void* filename) } void -CClient::sendDragInfo(UInt32 fileCount, CString& fileList, size_t size) +CClient::sendDragInfo(UInt32 fileCount, CString& info, size_t size) { - m_server->sendDragInfo(fileCount, fileList.c_str(), size); + m_server->sendDragInfo(fileCount, info.c_str(), size); } diff --git a/src/lib/client/Client.h b/src/lib/client/Client.h index 1f318be8..76bea8a6 100644 --- a/src/lib/client/Client.h +++ b/src/lib/client/Client.h @@ -114,7 +114,7 @@ public: void setFileTransferDes(CString& des) { m_fileTransferDes = des; } //! Send dragging file information back to server - void sendDragInfo(UInt32 fileCount, CString& fileList, size_t size); + void sendDragInfo(UInt32 fileCount, CString& info, size_t size); //@} //! @name accessors diff --git a/src/lib/client/ServerProxy.cpp b/src/lib/client/ServerProxy.cpp index 6a91b432..af6b441a 100644 --- a/src/lib/client/ServerProxy.cpp +++ b/src/lib/client/ServerProxy.cpp @@ -949,8 +949,8 @@ CServerProxy::fileChunkSending(UInt8 mark, char* data, size_t dataSize) } void -CServerProxy::sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize) +CServerProxy::sendDragInfo(UInt32 fileCount, const char* info, size_t size) { - CString info(data, dataSize); - CProtocolUtil::writef(m_stream, kMsgDDragInfo, fileCount, &info); + CString data(info, size); + CProtocolUtil::writef(m_stream, kMsgDDragInfo, fileCount, &data); } diff --git a/src/lib/client/ServerProxy.h b/src/lib/client/ServerProxy.h index e0c7ebd9..5fbc90ff 100644 --- a/src/lib/client/ServerProxy.h +++ b/src/lib/client/ServerProxy.h @@ -58,7 +58,7 @@ public: void fileChunkSending(UInt8 mark, char* data, size_t dataSize); // sending dragging information to server - void sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize); + void sendDragInfo(UInt32 fileCount, const char* info, size_t size); #ifdef TEST_ENV void handleDataForTest() { handleData(CEvent(), NULL); } diff --git a/src/lib/platform/OSXScreen.cpp b/src/lib/platform/OSXScreen.cpp index 25f52f5e..3288b5b0 100644 --- a/src/lib/platform/OSXScreen.cpp +++ b/src/lib/platform/OSXScreen.cpp @@ -909,21 +909,30 @@ COSXScreen::leave() if (isDraggingStarted()) { CString& fileList = getDraggingFilename(); - size_t size = fileList.size(); if (!m_isPrimary) { + // TODO: is this duplicated? // fake esc key down and up fakeKeyDown(kKeyEscape, 8192, 1); fakeKeyUp(1); - fakeMouseButton(kButtonLeft, false); if (fileList.empty() == false) { CClientApp& app = CClientApp::instance(); CClient* client = app.getClientPtr(); - UInt32 fileCount = 1; - client->sendDragInfo(fileCount, fileList, size); + + CDragInformation di; + di.setFilename(fileList); + CDragFileList dragFileList; + dragFileList.push_back(di); + CString info; + UInt32 fileCount = CDragInformation::setupDragInfo( + dragFileList, info); + client->sendDragInfo(fileCount, info, info.size()); LOG((CLOG_DEBUG "send dragging file to server")); + + // TODO: what to do with multiple file or even + // a folder client->sendFileToServer(fileList.c_str()); } } @@ -2080,7 +2089,8 @@ COSXScreen::fakeDraggingFiles(CDragFileList fileList) m_fakeDraggingStarted = true; CString fileExt; if (fileList.size() == 1) { - fileExt = CDragInformation::getDragFileExtension(fileList.at(0)); + fileExt = CDragInformation::getDragFileExtension( + fileList.at(0).getFilename()); } #if defined(MAC_OS_X_VERSION_10_7) diff --git a/src/lib/server/BaseClientProxy.h b/src/lib/server/BaseClientProxy.h index 3aad1488..ad744cc5 100644 --- a/src/lib/server/BaseClientProxy.h +++ b/src/lib/server/BaseClientProxy.h @@ -78,7 +78,8 @@ public: virtual void screensaver(bool activate) = 0; virtual void resetOptions() = 0; virtual void setOptions(const COptionsList& options) = 0; - virtual void sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize) = 0; + virtual void sendDragInfo(UInt32 fileCount, const char* info, + size_t size) = 0; virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0; virtual CString getName() const; diff --git a/src/lib/server/ClientProxy.h b/src/lib/server/ClientProxy.h index f88c9a5e..4fd181c7 100644 --- a/src/lib/server/ClientProxy.h +++ b/src/lib/server/ClientProxy.h @@ -83,7 +83,8 @@ public: virtual void screensaver(bool activate) = 0; virtual void resetOptions() = 0; virtual void setOptions(const COptionsList& options) = 0; - virtual void sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize) = 0; + virtual void sendDragInfo(UInt32 fileCount, const char* info, + size_t size) = 0; virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize) = 0; private: diff --git a/src/lib/server/ClientProxy1_0.cpp b/src/lib/server/ClientProxy1_0.cpp index d5500b83..8a25460a 100644 --- a/src/lib/server/ClientProxy1_0.cpp +++ b/src/lib/server/ClientProxy1_0.cpp @@ -361,7 +361,7 @@ CClientProxy1_0::mouseWheel(SInt32, SInt32 yDelta) } void -CClientProxy1_0::sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize) +CClientProxy1_0::sendDragInfo(UInt32 fileCount, const char* info, size_t size) { // ignore -- not supported in protocol 1.0 LOG((CLOG_DEBUG "draggingInfoSending not supported")); diff --git a/src/lib/server/ClientProxy1_0.h b/src/lib/server/ClientProxy1_0.h index c4c0674d..0bd8a68f 100644 --- a/src/lib/server/ClientProxy1_0.h +++ b/src/lib/server/ClientProxy1_0.h @@ -58,7 +58,7 @@ public: virtual void screensaver(bool activate); virtual void resetOptions(); virtual void setOptions(const COptionsList& options); - virtual void sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize); + virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size); virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize); protected: diff --git a/src/lib/server/ClientProxy1_5.cpp b/src/lib/server/ClientProxy1_5.cpp index 13abe0ee..f7db42d0 100644 --- a/src/lib/server/ClientProxy1_5.cpp +++ b/src/lib/server/ClientProxy1_5.cpp @@ -42,11 +42,11 @@ CClientProxy1_5::~CClientProxy1_5() } void -CClientProxy1_5::sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize) +CClientProxy1_5::sendDragInfo(UInt32 fileCount, const char* info, size_t size) { - CString info(data, dataSize); + CString data(info, size); - CProtocolUtil::writef(getStream(), kMsgDDragInfo, fileCount, &info); + CProtocolUtil::writef(getStream(), kMsgDDragInfo, fileCount, &data); } void diff --git a/src/lib/server/ClientProxy1_5.h b/src/lib/server/ClientProxy1_5.h index 821b8b1a..2c292826 100644 --- a/src/lib/server/ClientProxy1_5.h +++ b/src/lib/server/ClientProxy1_5.h @@ -29,7 +29,7 @@ public: CClientProxy1_5(const CString& name, synergy::IStream* adoptedStream, CServer* server, IEventQueue* events); ~CClientProxy1_5(); - virtual void sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize); + virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size); virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize); virtual bool parseMessage(const UInt8* code); void fileChunkReceived(); diff --git a/src/lib/server/PrimaryClient.cpp b/src/lib/server/PrimaryClient.cpp index a811974a..5fcd1b3e 100644 --- a/src/lib/server/PrimaryClient.cpp +++ b/src/lib/server/PrimaryClient.cpp @@ -250,7 +250,7 @@ CPrimaryClient::screensaver(bool) } void -CPrimaryClient::sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize) +CPrimaryClient::sendDragInfo(UInt32 fileCount, const char* info, size_t size) { // ignore } diff --git a/src/lib/server/PrimaryClient.h b/src/lib/server/PrimaryClient.h index 256d37fb..7fcdf0be 100644 --- a/src/lib/server/PrimaryClient.h +++ b/src/lib/server/PrimaryClient.h @@ -143,7 +143,7 @@ public: virtual void screensaver(bool activate); virtual void resetOptions(); virtual void setOptions(const COptionsList& options); - virtual void sendDragInfo(UInt32 fileCount, const char* data, size_t dataSize); + virtual void sendDragInfo(UInt32 fileCount, const char* info, size_t size); virtual void fileChunkSending(UInt8 mark, char* data, size_t dataSize); private: diff --git a/src/lib/server/Server.cpp b/src/lib/server/Server.cpp index f8550672..0445e380 100644 --- a/src/lib/server/Server.cpp +++ b/src/lib/server/Server.cpp @@ -1802,7 +1802,9 @@ CServer::getDragInfoThread(void*) m_dragFileList.clear(); CString& dragFileList = m_screen->getDraggingFilename(); if (!dragFileList.empty()) { - m_dragFileList.push_back(dragFileList); + CDragInformation di; + di.setFilename(dragFileList); + m_dragFileList.push_back(di); } #if defined(__APPLE__) @@ -1820,20 +1822,19 @@ CServer::getDragInfoThread(void*) void CServer::sendDragInfo(CBaseClientProxy* newScreen) { - // TODO: support multiple files dragging - CString& dragFile = m_dragFileList.at(0); - size_t size = dragFile.size() + 1; - char* fileList = NULL; - UInt32 fileCount = 1; - if (dragFile.empty() == false) { - fileList = new char[size]; - memcpy(fileList, dragFile.c_str(), size); - fileList[size - 1] = '\0'; - + CString infoString; + UInt32 fileCount = CDragInformation::setupDragInfo(m_dragFileList, infoString); + + if (fileCount > 0) { + char* info = NULL; + size_t size = infoString.size(); + info = new char[size]; + memcpy(info, infoString.c_str(), size); + LOG((CLOG_DEBUG2 "sending drag information to client")); - LOG((CLOG_DEBUG3 "dragging file list: %s", fileList)); + LOG((CLOG_DEBUG3 "dragging file list: %s", info)); LOG((CLOG_DEBUG3 "dragging file list string size: %i", size)); - newScreen->sendDragInfo(fileCount, fileList, size); + newScreen->sendDragInfo(fileCount, info, size); } } @@ -2050,7 +2051,7 @@ CServer::writeToDropDirThread(void*) #else dropTarget.append("/"); #endif - dropTarget.append(m_dragFileList.at(0)); + dropTarget.append(m_dragFileList.at(0).getFilename()); file.open(dropTarget.c_str(), std::ios::out | std::ios::binary); if (!file.is_open()) { // TODO: file open failed @@ -2058,6 +2059,8 @@ CServer::writeToDropDirThread(void*) file.write(m_receivedFileData.c_str(), m_receivedFileData.size()); file.close(); + + m_dragFileList.clear(); } else { LOG((CLOG_ERR "drop file failed: drop target is empty")); diff --git a/src/lib/synergy/DragInformation.cpp b/src/lib/synergy/DragInformation.cpp index b3f77361..ba83b06d 100644 --- a/src/lib/synergy/DragInformation.cpp +++ b/src/lib/synergy/DragInformation.cpp @@ -18,8 +18,17 @@ #include "synergy/DragInformation.h" #include "base/Log.h" +#include +#include + using namespace std; +CDragInformation::CDragInformation() : + m_filename(), + m_filesize(0) +{ +} + void CDragInformation::parseDragInfo(CDragFileList& dragFileList, UInt32 fileNum, CString data) { @@ -31,26 +40,47 @@ CDragInformation::parseDragInfo(CDragFileList& dragFileList, UInt32 fileNum, CSt if (data.find("/", startPos) != string::npos) { slash = "/"; } - - while (fileNum) { - findResult1 = data.find('\0', startPos); + + int index = 0; + while (index < fileNum) { + findResult1 = data.find(',', startPos); findResult2 = data.find_last_of(slash, findResult1); if (findResult1 == startPos) { //TODO: file number does not match, something goes wrong break; } + + // set filename if (findResult1 - findResult2 > 1) { - dragFileList.push_back(data.substr(findResult2 + 1, findResult1 - findResult2)); + CString filename = data.substr(findResult2 + 1, + findResult1 - findResult2 - 1); + CDragInformation di; + di.setFilename(filename); + dragFileList.push_back(di); } startPos = findResult1 + 1; - --fileNum; + + //set filesize + findResult2 = data.find(',', startPos); + if (findResult2 - findResult1 > 1) { + CString filesize = data.substr(findResult1 + 1, + findResult2 - findResult1 - 1); + size_t size = stringToNum(filesize); + dragFileList.at(index).setFilesize(size); + } + startPos = findResult1 + 1; + + ++index; } - LOG((CLOG_DEBUG "drag info received, total drag file number: %i", dragFileList.size())); + LOG((CLOG_DEBUG "drag info received, total drag file number: %i", + dragFileList.size())); for (size_t i = 0; i < dragFileList.size(); ++i) { - LOG((CLOG_DEBUG2 "dragging file %i name: %s", i + 1, dragFileList.at(i).c_str())); + LOG((CLOG_DEBUG2 "dragging file %i name: %s", + i + 1, + dragFileList.at(i).getFilename().c_str())); } } @@ -66,3 +96,47 @@ CDragInformation::getDragFileExtension(CString fileName) return ""; } } + +int +CDragInformation::setupDragInfo(CDragFileList& fileList, CString& output) +{ + int size = fileList.size(); + for (int i = 0; i < size; ++i) { + output.append(fileList.at(i).getFilename()); + output.append(","); + CString filesize = getFileSize(fileList.at(i).getFilename()); + output.append(filesize); + output.append(","); + } + return size; +} + +size_t +CDragInformation::stringToNum(CString& str) +{ + istringstream iss(str.c_str()); + size_t size; + iss >> size; + return size; +} + +CString +CDragInformation::getFileSize(CString& filename) +{ + std::fstream file(filename, ios::in|ios::binary); + + if (!file.is_open()) { + throw runtime_error("failed to get file size"); + } + + // check file size + file.seekg (0, std::ios::end); + size_t size = (size_t)file.tellg(); + + stringstream ss; + ss << size; + + file. close(); + + return ss.str(); +} diff --git a/src/lib/synergy/DragInformation.h b/src/lib/synergy/DragInformation.h index 7922e118..b328f732 100644 --- a/src/lib/synergy/DragInformation.h +++ b/src/lib/synergy/DragInformation.h @@ -21,14 +21,31 @@ #include "base/String.h" #include "base/EventTypes.h" -typedef std::vector CDragFileList; +class CDragInformation; +typedef std::vector CDragFileList; class CDragInformation { public: - CDragInformation() { } - + CDragInformation(); ~CDragInformation() { } - + + CString& getFilename() { return m_filename; } + void setFilename(CString& name) { m_filename = name; } + size_t getFilesize() { return m_filesize; } + void setFilesize(size_t size) { m_filesize = size; } + static void parseDragInfo(CDragFileList& dragFileList, UInt32 fileNum, CString data); static CString getDragFileExtension(CString fileName); + // helper function to setuo drag info + // example: filename1,filesize1,filename2,filesize2, + // return file count + static int setupDragInfo(CDragFileList& fileList, CString& output); + +private: + static size_t stringToNum(CString& str); + static CString getFileSize(CString& filename); + +private: + CString m_filename; + size_t m_filesize; };