From 3f84fc198131ff706e18c56f612e38ff147b0005 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 24 Aug 2011 20:13:14 +0300 Subject: Add support for copy text to clipboard (Ctrl+C). In X enviroments used xsel to copy string to clipboard. In windows used native clipboard api. MacOSX not supported. --- src/gui/widgets/textfield.cpp | 10 +++++ src/gui/widgets/textfield.h | 2 + src/utils/copynpaste.cpp | 87 +++++++++++++++++++++++++++++++++++++++++++ src/utils/copynpaste.h | 1 + 4 files changed, 100 insertions(+) (limited to 'src') diff --git a/src/gui/widgets/textfield.cpp b/src/gui/widgets/textfield.cpp index 2729e5407..d9f5bed9a 100644 --- a/src/gui/widgets/textfield.cpp +++ b/src/gui/widgets/textfield.cpp @@ -309,6 +309,10 @@ void TextField::keyPressed(gcn::KeyEvent &keyEvent) } break; + case 3: + handleCopy(); + break; + case 22: // Control code 22, SYNCHRONOUS IDLE, sent on Ctrl+v // hack to prevent paste key sticking if (mLastEventPaste && mLastEventPaste > cur_time) @@ -348,3 +352,9 @@ void TextField::handlePaste() setCaretPosition(static_cast(caretPos)); } } + +void TextField::handleCopy() +{ + std::string text = getText(); + sendBuffer(text); +} diff --git a/src/gui/widgets/textfield.h b/src/gui/widgets/textfield.h index 79197bb7a..79790d83a 100644 --- a/src/gui/widgets/textfield.h +++ b/src/gui/widgets/textfield.h @@ -99,6 +99,8 @@ class TextField : public gcn::TextField private: void handlePaste(); + void handleCopy(); + static int instances; static float mAlpha; static ImageRect skin; diff --git a/src/utils/copynpaste.cpp b/src/utils/copynpaste.cpp index 5b1ccb5bc..6d1c675d3 100644 --- a/src/utils/copynpaste.cpp +++ b/src/utils/copynpaste.cpp @@ -1,6 +1,7 @@ /* * Retrieve string pasted depending on OS mechanisms. * Copyright (C) 2001-2010 Wormux Team + * Copyright (C) 2011 ManaPlus Developers * * This file is part of The ManaPlus Client. * @@ -90,6 +91,40 @@ bool retrieveBuffer(std::string& text, std::string::size_type& pos) CloseClipboard(); return ret; } + +bool sendBuffer(std::string& text) +{ + int wCharsLen = MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, NULL, 0); + if (!wCharsLen) + return false; + + HANDLE h; + WCHAR *out; + h = GlobalAlloc(GMEM_MOVEABLE | GMEM_DDESHARE, wCharsLen * sizeof(WCHAR)); + out = (WCHAR*)GlobalLock(h); + + MultiByteToWideChar(CP_UTF8, 0, text.c_str(), -1, out, wCharsLen); + + if (!OpenClipboard(0)) + { + GlobalUnlock(h); + GlobalFree(h); + return false; + } + GlobalUnlock(h); + EmptyClipboard(); + if (!SetClipboardData(CF_UNICODETEXT, out)) + { + GlobalFree(h); + CloseClipboard(); + return false; + } + GlobalFree(h); + CloseClipboard(); + + return true; +} + #elif defined(__APPLE__) #ifdef Status @@ -243,6 +278,11 @@ bool retrieveBuffer(std::string& text, std::string::size_type& pos) } } +bool sendBuffer(std::string& text) +{ + return false; +} + #elif USE_X11 static char* getSelection2(Display *dpy, Window us, Atom selection, Atom request_target) @@ -362,9 +402,56 @@ bool retrieveBuffer(std::string& text, std::string::size_type& pos) } return false; } + +bool sendBuffer(std::string& text) +{ + pid_t pid; + int fd[2]; + + if (pipe(fd)) + return false; + + if ((pid = fork()) == -1) + { // fork error + return false; + } + else if (!pid) + { // child + close(fd[1]); + + if (fd[0] != STDIN_FILENO) + { + if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) + { + close(fd[0]); + exit(1); + } + close(fd[0]); + } + execl("/usr/bin/xsel", "xsel", "-i", (char *)0); + exit(1); + } + + // parent + close(fd[0]); + const int len = strlen(text.c_str()); + if (write(fd[1], text.c_str(), len) != len) + { + close(fd[1]); + return false; + } + close(fd[1]); + return true; +} + #else bool retrieveBuffer(std::string&, std::string::size_type&) { return false; } + +bool sendBuffer(std::string& text) +{ + return false; +} #endif diff --git a/src/utils/copynpaste.h b/src/utils/copynpaste.h index d09105139..03596d5d1 100644 --- a/src/utils/copynpaste.h +++ b/src/utils/copynpaste.h @@ -31,3 +31,4 @@ */ bool retrieveBuffer(std::string& text, std::string::size_type& pos); +bool sendBuffer(std::string& text); -- cgit v1.2.3-70-g09d2