From dcde47e15be49a41ca9aaffc1d0d5920cae44457 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Thu, 21 Nov 2024 23:33:41 -0500 Subject: [PATCH] clipboard-win: add Windows clipboard backend This adds a Windows clipboard backend. This doesn't depend on VO, so it can be used even when no video window is created. --- player/clipboard/clipboard-win.c | 48 ++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/player/clipboard/clipboard-win.c b/player/clipboard/clipboard-win.c index c0512af7d8..844b725be4 100644 --- a/player/clipboard/clipboard-win.c +++ b/player/clipboard/clipboard-win.c @@ -21,19 +21,61 @@ static int init(struct clipboard_ctx *cl, struct clipboard_init_params *params) { - return CLIPBOARD_FAILED; + return CLIPBOARD_SUCCESS; } static int get_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, struct clipboard_data *out, void *talloc_ctx) { - return CLIPBOARD_FAILED; + if (params->type != CLIPBOARD_DATA_TEXT || !IsClipboardFormatAvailable(CF_UNICODETEXT)) + return CLIPBOARD_FAILED; + if (!OpenClipboard(NULL)) + return CLIPBOARD_FAILED; + + HANDLE h = GetClipboardData(CF_UNICODETEXT); + wchar_t *wdata; + if (!h || !(wdata = GlobalLock(h))) { + CloseClipboard(); + return CLIPBOARD_FAILED; + } + + int len = WideCharToMultiByte(CP_UTF8, 0, wdata, -1, NULL, 0, NULL, NULL); + if (len <= 0) + abort(); + char *data = talloc_array(talloc_ctx, char, len); + WideCharToMultiByte(CP_UTF8, 0, wdata, -1, data, len, NULL, NULL); + out->type = CLIPBOARD_DATA_TEXT; + out->u.text = data; + + GlobalUnlock(h); + CloseClipboard(); + return CLIPBOARD_SUCCESS; } static int set_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, struct clipboard_data *data) { - return CLIPBOARD_FAILED; + if (params->type != CLIPBOARD_DATA_TEXT || data->type != CLIPBOARD_DATA_TEXT) + return CLIPBOARD_FAILED; + if (!OpenClipboard(NULL)) + return CLIPBOARD_FAILED; + + int len = MultiByteToWideChar(CP_UTF8, 0, data->u.text, -1, NULL, 0); + if (len <= 0) + abort(); + HANDLE h = GlobalAlloc(GMEM_MOVEABLE, len * sizeof(wchar_t)); + wchar_t *wdata; + if (!h || !(wdata = GlobalLock(h))) { + CloseClipboard(); + return CLIPBOARD_FAILED; + } + + MultiByteToWideChar(CP_UTF8, 0, data->u.text, -1, wdata, len); + GlobalUnlock(h); + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, h); + CloseClipboard(); + return CLIPBOARD_SUCCESS; } const struct clipboard_backend clipboard_backend_win32 = {