aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFakhri Mouad <moad_fakhri_1999@outlook.com>2024-08-28 16:36:06 +0100
committerFakhri Mouad <moad_fakhri_1999@outlook.com>2024-08-28 16:36:06 +0100
commit16503c3b91694f5ce9262e7edd7607b85926327d (patch)
tree34856732d65de18dde7cc4de2753d8623791a5d9
parent1e6419b5b7bdafe3f1d1a2b4321238b6257c44e6 (diff)
Add Win32 procs needed to handle clipboard
-rw-r--r--core/sys/windows/kernel32.odin3
-rw-r--r--core/sys/windows/user32.odin35
-rw-r--r--tests/core/sys/windows/test_clipboard.odin52
3 files changed, 90 insertions, 0 deletions
diff --git a/core/sys/windows/kernel32.odin b/core/sys/windows/kernel32.odin
index 629ece3de..81db67185 100644
--- a/core/sys/windows/kernel32.odin
+++ b/core/sys/windows/kernel32.odin
@@ -400,6 +400,9 @@ foreign kernel32 {
GlobalAlloc :: proc(flags: UINT, bytes: SIZE_T) -> LPVOID ---
GlobalReAlloc :: proc(mem: LPVOID, bytes: SIZE_T, flags: UINT) -> LPVOID ---
GlobalFree :: proc(mem: LPVOID) -> LPVOID ---
+
+ GlobalLock :: proc(hMem: HGLOBAL) -> LPVOID ---
+ GlobalUnlock :: proc(hMem: HGLOBAL) -> BOOL ---
ReadDirectoryChangesW :: proc(
hDirectory: HANDLE,
diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin
index 31fc59f72..e13dcd55f 100644
--- a/core/sys/windows/user32.odin
+++ b/core/sys/windows/user32.odin
@@ -305,6 +305,13 @@ foreign user32 {
GetProcessWindowStation :: proc() -> HWINSTA ---
GetUserObjectInformationW :: proc(hObj: HANDLE, nIndex: GetUserObjectInformationFlags, pvInfo: PVOID, nLength: DWORD, lpnLengthNeeded: LPDWORD) -> BOOL ---
+
+ OpenClipboard :: proc(hWndNewOwner: HWND) -> BOOL ---
+ CloseClipboard :: proc() -> BOOL ---
+ GetClipboardData :: proc(uFormat: UINT) -> HANDLE ---
+ SetClipboardData :: proc(uFormat: UINT, hMem: HANDLE) -> HANDLE ---
+ IsClipboardFormatAvailable :: proc(format: UINT) -> BOOL ---
+ EmptyClipboard :: proc() -> BOOL ---
}
CreateWindowW :: #force_inline proc "system" (
@@ -746,3 +753,31 @@ WinEventFlag :: enum DWORD {
SKIPOWNPROCESS = 1,
INCONTEXT = 2,
}
+
+// Standard Clipboard Formats
+CF_TEXT :: 1
+CF_BITMAP :: 2
+CF_METAFILEPICT :: 3
+CF_SYLK :: 4
+CF_DIF :: 5
+CF_TIFF :: 6
+CF_OEMTEXT :: 7
+CF_DIB :: 8
+CF_PALETTE :: 9
+CF_PENDATA :: 10
+CF_RIFF :: 11
+CF_WAVE :: 12
+CF_UNICODETEXT :: 13
+CF_ENHMETAFILE :: 14
+CF_HDROP :: 15
+CF_LOCALE :: 16
+CF_DIBV5 :: 17
+CF_DSPBITMAP :: 0x0082
+CF_DSPENHMETAFILE :: 0x008E
+CF_DSPMETAFILEPICT :: 0x0083
+CF_DSPTEXT :: 0x0081
+CF_GDIOBJFIRST :: 0x0300
+CF_GDIOBJLAST :: 0x03FF
+CF_OWNERDISPLAY :: 0x0080
+CF_PRIVATEFIRST :: 0x0200
+CF_PRIVATELAST :: 0x02FF
diff --git a/tests/core/sys/windows/test_clipboard.odin b/tests/core/sys/windows/test_clipboard.odin
new file mode 100644
index 000000000..460012cae
--- /dev/null
+++ b/tests/core/sys/windows/test_clipboard.odin
@@ -0,0 +1,52 @@
+//+build windows
+package test_core_sys_windows
+
+import "core:testing"
+import win32 "core:sys/windows"
+import "base:runtime"
+import "core:strings"
+import "core:mem"
+
+read_from_clipboard :: proc(wnd_handle: win32.HWND, allocator: runtime.Allocator) -> (result: string)
+{
+ if !win32.IsClipboardFormatAvailable(win32.CF_TEXT) do return;
+
+ if !win32.OpenClipboard(wnd_handle) do return;
+ defer win32.CloseClipboard();
+
+ clipboard_data := win32.GetClipboardData(win32.CF_TEXT);
+ if clipboard_data != nil {
+ if cstr := cstring(win32.GlobalLock(win32.HGLOBAL(clipboard_data))); cstr != nil {
+ result = strings.clone_from_cstring(cstr, allocator);
+ }
+ win32.GlobalUnlock(win32.HGLOBAL(clipboard_data));
+ }
+ return;
+}
+
+write_to_clipboard :: proc(wnd_handle: win32.HWND, text: string)
+{
+ if !win32.OpenClipboard(wnd_handle) do return;
+ defer win32.CloseClipboard();
+ win32.EmptyClipboard();
+
+ h_mem := win32.HGLOBAL(win32.GlobalAlloc(win32.GMEM_MOVEABLE, len(text) + 1));
+ if h_mem == nil do return;
+
+ cstr_dst := cast([^]u8)win32.GlobalLock(h_mem);
+ defer win32.GlobalUnlock(h_mem);
+ if cstr_dst == nil do return;
+
+ mem.copy(rawptr(cstr_dst), raw_data(text), len(text));
+ cstr_dst[len(text)] = 0;
+
+ win32.SetClipboardData(win32.CF_TEXT, win32.HANDLE(h_mem));
+}
+
+
+@(test)
+verify_win32_clipboard :: proc(t: ^testing.T) {
+ write_to_clipboard(nil, "Hello everynyan! OH MY GAH");
+ clipboard_content := read_from_clipboard(nil, context.temp_allocator);
+ testing.expect_value(t, clipboard_content, "Hello everynyan! OH MY GAH");
+}