diff --git a/src/pc/gfx/gfx_dummy.c b/src/pc/gfx/gfx_dummy.c index b0fda743..b4a49b4e 100644 --- a/src/pc/gfx/gfx_dummy.c +++ b/src/pc/gfx/gfx_dummy.c @@ -113,7 +113,7 @@ static void gfx_dummy_wm_start_text_input(void) { static void gfx_dummy_wm_stop_text_input(void) { } -static void gfx_dummy_wm_set_clipboard_text(UNUSED char* text) { +static void gfx_dummy_wm_set_clipboard_text(UNUSED const char* text) { } static void gfx_dummy_wm_set_cursor_visible(UNUSED bool visible) { diff --git a/src/pc/gfx/gfx_dxgi.cpp b/src/pc/gfx/gfx_dxgi.cpp index 0488c60d..4441fe13 100644 --- a/src/pc/gfx/gfx_dxgi.cpp +++ b/src/pc/gfx/gfx_dxgi.cpp @@ -719,26 +719,40 @@ void gfx_dxgi_start_text_input(void) { inTextInput = TRUE; } void gfx_dxgi_stop_text_input(void) { inTextInput = FALSE; } static char* gfx_dxgi_get_clipboard_text(void) { + static char clipboard_buf[WAPI_CLIPBOARD_BUFSIZ]; + clipboard_buf[0] = '\0'; + if (OpenClipboard(NULL)) { - HANDLE clip = GetClipboardData(CF_TEXT); + LPCWSTR text = (LPCWSTR)GetClipboardData(CF_UNICODETEXT); + if (text != NULL) { + WideCharToMultiByte(CP_UTF8, 0, text, (-1), clipboard_buf, WAPI_CLIPBOARD_BUFSIZ, NULL, NULL); + } CloseClipboard(); - return (char*)clip; } - return NULL; + + clipboard_buf[WAPI_CLIPBOARD_BUFSIZ - 1] = '\0'; + return clipboard_buf; } -void gfx_dxgi_set_clipboard_text(char* text) { - if (OpenClipboard(NULL)) { - HGLOBAL clipbuffer; - char *buffer; - EmptyClipboard(); - clipbuffer = GlobalAlloc(GMEM_DDESHARE, strlen(text) + 1); - buffer = (char *) GlobalLock(clipbuffer); - strcpy(buffer, LPCSTR(text)); - GlobalUnlock(clipbuffer); - SetClipboardData(CF_TEXT, clipbuffer); - CloseClipboard(); +void gfx_dxgi_set_clipboard_text(const char* text) { + if (!OpenClipboard(NULL)) { return; } + EmptyClipboard(); + + int cch = MultiByteToWideChar(CP_UTF8, 0, text, (-1), NULL, 0); + if (cch > 0) { + HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, cch * sizeof(WCHAR)); + if (hMem != NULL) { + LPWSTR wcsBuffer = (LPWSTR)GlobalLock(hMem); + if (wcsBuffer != NULL) { + MultiByteToWideChar(CP_UTF8, 0, text, (-1), wcsBuffer, cch); + GlobalUnlock(hMem); + SetClipboardData(CF_UNICODETEXT, hMem); + } else { + GlobalFree(hMem); + } + } } + CloseClipboard(); } void gfx_dxgi_set_cursor_visible(bool visible) { ShowCursor(visible); } diff --git a/src/pc/gfx/gfx_sdl1.c b/src/pc/gfx/gfx_sdl1.c index 378c981a..cf6b4a27 100644 --- a/src/pc/gfx/gfx_sdl1.c +++ b/src/pc/gfx/gfx_sdl1.c @@ -211,8 +211,8 @@ static bool gfx_sdl_has_focus(void) { static void gfx_sdl_start_text_input(void) { return; } static void gfx_sdl_stop_text_input(void) { return; } -static char* gfx_sdl_get_clipboard_text(void) { return NULL; } -static void gfx_sdl_set_clipboard_text(char* text) { return; } +static char* gfx_sdl_get_clipboard_text(void) { return ""; } +static void gfx_sdl_set_clipboard_text(UNUSED const char* text) { return; } static void gfx_sdl_set_cursor_visible(bool visible) { SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); } struct GfxWindowManagerAPI gfx_sdl = { diff --git a/src/pc/gfx/gfx_sdl2.c b/src/pc/gfx/gfx_sdl2.c index 0b448b3d..c980c560 100644 --- a/src/pc/gfx/gfx_sdl2.c +++ b/src/pc/gfx/gfx_sdl2.c @@ -304,8 +304,19 @@ static bool gfx_sdl_has_focus(void) { static void gfx_sdl_start_text_input(void) { SDL_StartTextInput(); } static void gfx_sdl_stop_text_input(void) { SDL_StopTextInput(); } -static char* gfx_sdl_get_clipboard_text(void) { return SDL_GetClipboardText(); } -static void gfx_sdl_set_clipboard_text(char* text) { SDL_SetClipboardText(text); } + +static char* gfx_sdl_get_clipboard_text(void) { + static char clipboard_buf[WAPI_CLIPBOARD_BUFSIZ]; + + char* text = SDL_GetClipboardText(); + strncpy(clipboard_buf, text, WAPI_CLIPBOARD_BUFSIZ - 1); + SDL_free(text); + + clipboard_buf[WAPI_CLIPBOARD_BUFSIZ - 1] = '\0'; + return clipboard_buf; +} + +static void gfx_sdl_set_clipboard_text(const char* text) { SDL_SetClipboardText(text); } static void gfx_sdl_set_cursor_visible(bool visible) { SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE); } struct GfxWindowManagerAPI gfx_sdl = { diff --git a/src/pc/gfx/gfx_window_manager_api.h b/src/pc/gfx/gfx_window_manager_api.h index b94ecdd5..57204a85 100644 --- a/src/pc/gfx/gfx_window_manager_api.h +++ b/src/pc/gfx/gfx_window_manager_api.h @@ -7,6 +7,8 @@ // special value for window position that signifies centered position #define WAPI_WIN_CENTERPOS 0xFFFFFFFF +#define WAPI_CLIPBOARD_BUFSIZ 1024 + typedef bool (*kb_callback_t)(int code); struct GfxWindowManagerAPI { @@ -23,7 +25,7 @@ struct GfxWindowManagerAPI { void (*start_text_input)(void); void (*stop_text_input)(void); char* (*get_clipboard_text)(void); - void (*set_clipboard_text)(char*); + void (*set_clipboard_text)(const char*); void (*set_cursor_visible)(bool); void (*delay)(unsigned int ms); int (*get_max_msaa)(void);