Browse Source

Implemented copying and pasting for MS-Windows, which should work for UTF-16 and Latin-1. Most native formats should work with the 7-bit subset of Latin-1 until they are handled.

David Piuva 2 years ago
parent
commit
874954731c

+ 3 - 2
Source/DFPSR/api/guiAPI.cpp

@@ -508,12 +508,13 @@ String dsr::window_getTitle(Window& window) {
 	MUST_EXIST(window, window_getTitle);
 	return window->backend->getTitle();
 }
+
 String window_loadFromClipboard(Window& window, double timeoutInSeconds) {
 	MUST_EXIST(window, window_loadFromClipboard);
 	return window->backend->loadFromClipboard(timeoutInSeconds);
 }
 
-void window_saveToClipboard(Window& window, const ReadableString &text) {
+void window_saveToClipboard(Window& window, const ReadableString &text, double timeoutInSeconds) {
 	MUST_EXIST(window, window_saveToClipboard);
-	window->backend->saveToClipboard(text);
+	window->backend->saveToClipboard(text, timeoutInSeconds);
 }

+ 1 - 1
Source/DFPSR/api/guiAPI.h

@@ -64,7 +64,7 @@ namespace dsr {
 	String window_loadFromClipboard(Window& window, double timeoutInSeconds);
 	// Stores the text argument to an internal or extenal clipboard.
 	//   The internal clipboard within the application is used when the system specific backend has not implemented clipboard access.
-	void window_saveToClipboard(Window& window, const ReadableString &text);
+	void window_saveToClipboard(Window& window, const ReadableString &text, double timeoutInSeconds);
 
 // Layout files
 	// Loading an interface by parsing a layout file's content, with any external resources loaded relative to fromPath.

+ 1 - 1
Source/DFPSR/gui/BackendWindow.cpp

@@ -33,7 +33,7 @@ ReadableString BackendWindow::loadFromClipboard(double timeoutInSeconds) {
 	return backupClipboard;
 }
 
-void BackendWindow::saveToClipboard(const ReadableString &text) {
+void BackendWindow::saveToClipboard(const ReadableString &text, double timeoutInSeconds) {
 	sendWarning(U"saveToClipboard is not implemented! Simulating clipboard using a variable within the same application.");
 	backupClipboard = text;
 }

+ 1 - 1
Source/DFPSR/gui/BackendWindow.h

@@ -93,7 +93,7 @@ public:
 	// Load from the clipboard, waiting at most timeoutInMilliseconds milliseconds.
 	virtual ReadableString loadFromClipboard(double timeoutInSeconds = 0.5);
 	// Save text to the clipboard.
-	virtual void saveToClipboard(const ReadableString &text);
+	virtual void saveToClipboard(const ReadableString &text, double timeoutInSeconds = 0.5);
 public:
 	// Each callback declaration has a public variable and a public getter and setter
 	DECLARE_CALLBACK(closeEvent, emptyCallback);

+ 56 - 0
Source/windowManagers/Win32Window.cpp

@@ -13,6 +13,8 @@ Link to these dependencies for MS Windows:
 
 #include "../DFPSR/api/imageAPI.h"
 #include "../DFPSR/api/drawAPI.h"
+#include "../DFPSR/api/bufferAPI.h"
+#include "../DFPSR/api/timeAPI.h"
 #include "../DFPSR/gui/BackendWindow.h"
 
 #include <mutex>
@@ -90,12 +92,65 @@ public:
 	bool isFullScreen() override { return this->windowState == 2; }
 	void redraw(HWND& hwnd, bool locked, bool swap); // HWND is passed by argument because drawing might be called before the constructor has assigned it to this->hwnd
 	void showCanvas() override;
+	// Clipboard		
+	dsr::ReadableString loadFromClipboard(double timeoutInSeconds);
+	void saveToClipboard(const dsr::ReadableString &text, double timeoutInSeconds);
 };
 
 static LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
 
 static TCHAR windowClassName[] = _T("DfpsrWindowApplication");
 
+dsr::ReadableString Win32Window::loadFromClipboard(double timeoutInSeconds) {
+	dsr::String result = U"";
+	if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
+		// TODO: Repeat attempts to open the clipboard in a delayed loop until the timeout is reached.
+		if (OpenClipboard(this->hwnd)) {
+			HGLOBAL globalBuffer = GetClipboardData(CF_UNICODETEXT);
+			void *globalData = GlobalLock(globalBuffer);
+			if (globalData) {
+				result = dsr::string_dangerous_decodeFromData(globalData, dsr::CharacterEncoding::BOM_UTF16LE);
+				GlobalUnlock(globalBuffer);
+			}
+			CloseClipboard();
+		}
+	} else if (IsClipboardFormatAvailable(CF_TEXT)) {
+		// TODO: Repeat attempts to open the clipboard in a delayed loop until the timeout is reached.
+		if (OpenClipboard(this->hwnd)) {
+			HGLOBAL globalBuffer = GetClipboardData(CF_TEXT);
+			void *globalData = GlobalLock(globalBuffer);
+			if (globalData) {
+				// TODO: Use a built-in conversion from native text formats.
+				// If the text is not in Unicode format, assume Latin-1.
+				result = dsr::string_dangerous_decodeFromData(globalData, dsr::CharacterEncoding::Raw_Latin1);
+				GlobalUnlock(globalBuffer);
+			}
+			CloseClipboard();
+		}
+	}
+	return result;
+}
+
+void Win32Window::saveToClipboard(const dsr::ReadableString &text, double timeoutInSeconds) {
+	// TODO: Repeat attempts to open the clipboard in a delayed loop until the timeout is reached.
+	if (OpenClipboard(this->hwnd)) {
+		EmptyClipboard();
+		dsr::Buffer savedText = dsr::string_saveToMemory(text, dsr::CharacterEncoding::BOM_UTF16LE, dsr::LineEncoding::CrLf, false, true);
+		int64_t textSize = dsr::buffer_getSize(savedText);
+		HGLOBAL globalBuffer = GlobalAlloc(GMEM_MOVEABLE, textSize);
+		if (globalBuffer) {
+			void *globalData = GlobalLock(globalBuffer);
+			uint8_t *localData = dsr::buffer_dangerous_getUnsafeData(savedText);
+			memcpy(globalData, localData, textSize);
+			GlobalUnlock(globalBuffer);
+			SetClipboardData(CF_UNICODETEXT, globalBuffer);
+		} else {
+			dsr::sendWarning(U"Could not allocate global memory for saving text to the clipboard!\n");
+		}
+		CloseClipboard();
+	}
+}
+
 void Win32Window::updateTitle_locked() {
 	windowLock.lock();
 		if (!SetWindowTextA(this->hwnd, this->title.toStdString().c_str())) {
@@ -574,6 +629,7 @@ void Win32Window::resizeCanvas(int width, int height) {
 	}
 	this->firstFrame = true;
 }
+
 Win32Window::~Win32Window() {
 	#ifndef DISABLE_MULTI_THREADING
 		// Wait for the last update of the window to finish so that it doesn't try to operate on freed resources

+ 2 - 2
Source/windowManagers/X11Window.cpp

@@ -108,7 +108,7 @@ public:
 	void initializeClipboard();
 	void terminateClipboard();		
 	dsr::ReadableString loadFromClipboard(double timeoutInSeconds);
-	void saveToClipboard(const dsr::ReadableString &text);
+	void saveToClipboard(const dsr::ReadableString &text, double timeoutInSeconds);
 };
 
 void X11Window::initializeClipboard() {
@@ -141,7 +141,7 @@ void X11Window::listContentInClipboard() {
 	XSetSelectionOwner(this->display, this->clipboardAtom, this->window, CurrentTime);
 }
 
-void X11Window::saveToClipboard(const dsr::ReadableString &text) {
+void X11Window::saveToClipboard(const dsr::ReadableString &text, double timeoutInSeconds) {
 	this->textToClipboard = text;
 	this->listContentInClipboard();
 }