diff options
author | Arnon Gilboa <agilboa@redhat.com> | 2010-07-19 10:29:47 +0300 |
---|---|---|
committer | Alon Levy <alevy@redhat.com> | 2010-07-19 10:30:19 +0300 |
commit | ce03f5449d68b2f0201dce409a81280300120069 (patch) | |
tree | 62f0877b9fd7f695253aa26f0ed046e873efbe66 /client/windows | |
parent | 4f8545ed628fbb89a893297c5fdf276511284b33 (diff) | |
download | spice-ce03f5449d68b2f0201dce409a81280300120069.tar.gz spice-ce03f5449d68b2f0201dce409a81280300120069.tar.xz spice-ce03f5449d68b2f0201dce409a81280300120069.zip |
client: add clipboard support
* windows - untested
* linux - small strings both ways, large implemented differently:
* client to guest - support INCR
* guest to client - we supply a single possibly very large property
* requires server changes in next patch to work with spice-vmc
Diffstat (limited to 'client/windows')
-rw-r--r-- | client/windows/platform.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/client/windows/platform.cpp b/client/windows/platform.cpp index 81eb787c..ae49d028 100644 --- a/client/windows/platform.cpp +++ b/client/windows/platform.cpp @@ -749,6 +749,96 @@ void WinPlatform::exit_modal_loop() modal_loop_active = false; } +void Platform::set_clipboard_listener(ClipboardListener* listener) +{ + //FIXME: call only on change, use statics + listener->on_clipboard_change(); +} + +UINT get_format(uint32_t type) +{ + switch (type) { + case Platform::CLIPBOARD_UTF8_TEXT: + return CF_UNICODETEXT; + default: + return 0; + } +} + +bool Platform::set_clipboard_data(uint32_t type, const uint8_t* data, int32_t size) +{ + UINT format = get_format(type); + HGLOBAL clip_data; + LPVOID clip_buf; + int clip_size; + bool ret; + + //LOG_INFO("type %u size %d %s", type, size, data); + if (!format || !OpenClipboard(paltform_win)) { + return false; + } + clip_size = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)data, size, NULL, 0); + if (!clip_size || !(clip_data = GlobalAlloc(GMEM_DDESHARE, clip_size * sizeof(WCHAR)))) { + CloseClipboard(); + return false; + } + if (!(clip_buf = GlobalLock(clip_data))) { + GlobalFree(clip_data); + CloseClipboard(); + return false; + } + ret = !!MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)data, size, (LPWSTR)clip_buf, clip_size); + GlobalUnlock(clip_data); + if (ret) { + EmptyClipboard(); + ret = !!SetClipboardData(format, clip_data); + } + CloseClipboard(); + return ret; +} + +bool Platform::get_clipboard_data(uint32_t type, uint8_t* data, int32_t size) +{ + UINT format = get_format(type); + HANDLE clip_data; + LPVOID clip_buf; + bool ret; + + LOG_INFO("type %u size %d", type, size); + if (!format || !IsClipboardFormatAvailable(format) || !OpenClipboard(paltform_win)) { + return false; + } + if (!(clip_data = GetClipboardData(format)) || !(clip_buf = GlobalLock(clip_data))) { + CloseClipboard(); + return false; + } + ret = !!WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)clip_buf, -1, (LPSTR)data, size, NULL, NULL); + GlobalUnlock(clip_data); + CloseClipboard(); + return ret; +} + +int32_t Platform::get_clipboard_data_size(uint32_t type) +{ + UINT format = get_format(type); + HANDLE clip_data; + LPVOID clip_buf; + int clip_size; + + if (!format || !IsClipboardFormatAvailable(format) || !OpenClipboard(paltform_win)) { + return 0; + } + if (!(clip_data = GetClipboardData(format)) || !(clip_buf = GlobalLock(clip_data))) { + CloseClipboard(); + return 0; + } + clip_size = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)clip_buf, -1, NULL, 0, NULL, NULL); + GlobalUnlock(clip_data); + CloseClipboard(); + return clip_size; +} + + static bool has_console = false; static void create_console() |