summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2011-08-24 20:13:14 +0300
committerAndrei Karas <akaras@inbox.ru>2011-09-07 03:13:54 +0300
commit3f84fc198131ff706e18c56f612e38ff147b0005 (patch)
treea723a9a9163498cd880bdc23c9752d0b4e9373ca
parent64f4e1132355eaac4f5594bee516b56adb2ad083 (diff)
downloadplus-3f84fc198131ff706e18c56f612e38ff147b0005.tar.gz
plus-3f84fc198131ff706e18c56f612e38ff147b0005.tar.bz2
plus-3f84fc198131ff706e18c56f612e38ff147b0005.tar.xz
plus-3f84fc198131ff706e18c56f612e38ff147b0005.zip
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.
-rw-r--r--src/gui/widgets/textfield.cpp10
-rw-r--r--src/gui/widgets/textfield.h2
-rw-r--r--src/utils/copynpaste.cpp87
-rw-r--r--src/utils/copynpaste.h1
4 files changed, 100 insertions, 0 deletions
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<unsigned>(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);