Add Windows clipboard support
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include <Shlwapi.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "src/entry_handler.h"
|
||||
#include "src/globals.h"
|
||||
@@ -95,6 +96,10 @@ namespace {
|
||||
|
||||
namespace bp = boost::process;
|
||||
|
||||
static std::string ensureCrLf(const std::string& utf8Str);
|
||||
static std::wstring getClipboardData();
|
||||
static int setClipboardData(const std::string& acpStr);
|
||||
|
||||
using namespace std::literals;
|
||||
namespace platf {
|
||||
using adapteraddrs_t = util::c_ptr<IP_ADAPTER_ADDRESSES>;
|
||||
@@ -1941,4 +1946,103 @@ namespace platf {
|
||||
create_high_precision_timer() {
|
||||
return std::make_unique<win32_high_precision_timer>();
|
||||
}
|
||||
|
||||
std::string
|
||||
get_clipboard() {
|
||||
std::string currentClipboard = to_utf8(getClipboardData());
|
||||
return currentClipboard;
|
||||
}
|
||||
|
||||
bool
|
||||
set_clipboard(const std::string& content) {
|
||||
std::string cpContent = convertUtf8ToCurrentCodepage(ensureCrLf(content));
|
||||
return !setClipboardData(cpContent);
|
||||
}
|
||||
} // namespace platf
|
||||
|
||||
static std::string ensureCrLf(const std::string& utf8Str) {
|
||||
std::string result;
|
||||
result.reserve(utf8Str.size() + utf8Str.length() / 2); // Reserve extra space
|
||||
|
||||
for (size_t i = 0; i < utf8Str.size(); ++i) {
|
||||
if (utf8Str[i] == '\n' && (i == 0 || utf8Str[i - 1] != '\r')) {
|
||||
result += '\r'; // Add \r before \n if not present
|
||||
}
|
||||
result += utf8Str[i]; // Always add the current character
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::wstring getClipboardData() {
|
||||
if (!OpenClipboard(nullptr)) {
|
||||
BOOST_LOG(warning) << "Failed to open clipboard.";
|
||||
return L"";
|
||||
}
|
||||
|
||||
HANDLE hData = GetClipboardData(CF_UNICODETEXT);
|
||||
if (hData == nullptr) {
|
||||
BOOST_LOG(warning) << "No text data in clipboard or failed to get data.";
|
||||
CloseClipboard();
|
||||
return L"";
|
||||
}
|
||||
|
||||
wchar_t* pszText = static_cast<wchar_t*>(GlobalLock(hData));
|
||||
if (pszText == nullptr) {
|
||||
BOOST_LOG(warning) << "Failed to lock clipboard data.";
|
||||
CloseClipboard();
|
||||
return L"";
|
||||
}
|
||||
|
||||
std::wstring ret = pszText;
|
||||
|
||||
GlobalUnlock(hData);
|
||||
CloseClipboard();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int setClipboardData(const std::string& acpStr) {
|
||||
if (!OpenClipboard(nullptr)) {
|
||||
BOOST_LOG(warning) << "Failed to open clipboard.";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!EmptyClipboard()) {
|
||||
BOOST_LOG(warning) << "Failed to empty clipboard.";
|
||||
CloseClipboard();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Allocate global memory for the clipboard text
|
||||
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, acpStr.size() + 1);
|
||||
if (hGlobal == nullptr) {
|
||||
BOOST_LOG(warning) << "Failed to allocate global memory.";
|
||||
CloseClipboard();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Lock the global memory and copy the text
|
||||
char* pGlobal = static_cast<char*>(GlobalLock(hGlobal));
|
||||
if (pGlobal == nullptr) {
|
||||
BOOST_LOG(warning) << "Failed to lock global memory.";
|
||||
GlobalFree(hGlobal);
|
||||
CloseClipboard();
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(pGlobal, acpStr.c_str(), acpStr.size() + 1);
|
||||
GlobalUnlock(hGlobal);
|
||||
|
||||
// Set the clipboard data
|
||||
if (SetClipboardData(CF_TEXT, hGlobal) == nullptr) {
|
||||
BOOST_LOG(warning) << "Failed to set clipboard data.";
|
||||
GlobalFree(hGlobal);
|
||||
CloseClipboard();
|
||||
return 1;
|
||||
}
|
||||
|
||||
CloseClipboard();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user