This adds a Windows clipboard backend. This doesn't depend on VO, so it can be used even when no video window is created.
Unified · Split
| @@ -21,19 +21,61 @@ · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | static int init(struct clipboard_ctx *cl, struct clipboard_init_params *params) | 22 | static int init(struct clipboard_ctx *cl, struct clipboard_init_params *params) |
| 23 | { | 23 | { |
| 24 | return CLIPBOARD_FAILED; | 24 | return CLIPBOARD_SUCCESS; |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | static int get_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, | 27 | static int get_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, |
| 28 | struct clipboard_data *out, void *talloc_ctx) | 28 | struct clipboard_data *out, void *talloc_ctx) |
| 29 | { | 29 | { |
| 30 | return CLIPBOARD_FAILED; | 30 | if (params->type != CLIPBOARD_DATA_TEXT || !IsClipboardFormatAvailable(CF_UNICODETEXT)) |
| 31 | return CLIPBOARD_FAILED; | ||
| 32 | if (!OpenClipboard(NULL)) | ||
| 33 | return CLIPBOARD_FAILED; | ||
| 34 | |||
| 35 | HANDLE h = GetClipboardData(CF_UNICODETEXT); | ||
| 36 | wchar_t *wdata; | ||
| 37 | if (!h || !(wdata = GlobalLock(h))) { | ||
| 38 | CloseClipboard(); | ||
| 39 | return CLIPBOARD_FAILED; | ||
| 40 | } | ||
| 41 | |||
| 42 | int len = WideCharToMultiByte(CP_UTF8, 0, wdata, -1, NULL, 0, NULL, NULL); | ||
| 43 | if (len <= 0) | ||
| 44 | abort(); | ||
| 45 | char *data = talloc_array(talloc_ctx, char, len); | ||
| 46 | WideCharToMultiByte(CP_UTF8, 0, wdata, -1, data, len, NULL, NULL); | ||
| 47 | out->type = CLIPBOARD_DATA_TEXT; | ||
| 48 | out->u.text = data; | ||
| 49 | |||
| 50 | GlobalUnlock(h); | ||
| 51 | CloseClipboard(); | ||
| 52 | return CLIPBOARD_SUCCESS; | ||
| 31 | } | 53 | } |
| 32 | 54 | ||
| 33 | static int set_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, | 55 | static int set_data(struct clipboard_ctx *cl, struct clipboard_access_params *params, |
| 34 | struct clipboard_data *data) | 56 | struct clipboard_data *data) |
| 35 | { | 57 | { |
| 36 | return CLIPBOARD_FAILED; | 58 | if (params->type != CLIPBOARD_DATA_TEXT || data->type != CLIPBOARD_DATA_TEXT) |
| 59 | return CLIPBOARD_FAILED; | ||
| 60 | if (!OpenClipboard(NULL)) | ||
| 61 | return CLIPBOARD_FAILED; | ||
| 62 | |||
| 63 | int len = MultiByteToWideChar(CP_UTF8, 0, data->u.text, -1, NULL, 0); | ||
| 64 | if (len <= 0) | ||
| 65 | abort(); | ||
| 66 | HANDLE h = GlobalAlloc(GMEM_MOVEABLE, len * sizeof(wchar_t)); | ||
| 67 | wchar_t *wdata; | ||
| 68 | if (!h || !(wdata = GlobalLock(h))) { | ||
| 69 | CloseClipboard(); | ||
| 70 | return CLIPBOARD_FAILED; | ||
| 71 | } | ||
| 72 | |||
| 73 | MultiByteToWideChar(CP_UTF8, 0, data->u.text, -1, wdata, len); | ||
| 74 | GlobalUnlock(h); | ||
| 75 | EmptyClipboard(); | ||
| 76 | SetClipboardData(CF_UNICODETEXT, h); | ||
| 77 | CloseClipboard(); | ||
| 78 | return CLIPBOARD_SUCCESS; | ||
| 37 | } | 79 | } |
| 38 | 80 | ||
| 39 | const struct clipboard_backend clipboard_backend_win32 = { | 81 | const struct clipboard_backend clipboard_backend_win32 = { |