From: Ray Chason Date: Mon, 17 Oct 2022 02:32:11 +0000 (-0400) Subject: Copy Unicode to the clipboard X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f7aa79f9391fb8f5f4eecca80df583eb51ff4737;p=nethack Copy Unicode to the clipboard --- diff --git a/win/win32/mhmain.c b/win/win32/mhmain.c index e11dd33d0..f10e953ed 100644 --- a/win/win32/mhmain.c +++ b/win/win32/mhmain.c @@ -35,8 +35,11 @@ static void register_main_window_class(void); static int menuid2mapmode(int menuid); static int mapmode2menuid(int map_mode); static void nhlock_windows(BOOL lock); -static char *nh_compose_ascii_screenshot(); -static void mswin_apply_window_style_all(); +static char *nh_compose_ascii_screenshot(void); +#ifdef ENHANCED_SYMBOLS +static WCHAR *nh_compose_unicode_screenshot(void); +#endif +static void mswin_apply_window_style_all(void); // returns strdup() created pointer - callee assumes the ownership HWND @@ -871,42 +874,79 @@ onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) break; case IDM_SETTING_SCREEN_TO_CLIPBOARD: { - char *p; + char *p = NULL; +#ifdef ENHANCED_SYMBOLS + WCHAR *wp = NULL; +#endif + unsigned chr_size = 1; size_t len; HANDLE hglbCopy; - char *p_copy; - p = nh_compose_ascii_screenshot(); - if (!p) - return 0; - len = strlen(p); +#ifdef ENHANCED_SYMBOLS + if (SYMHANDLING(H_UTF8)) { + wp = nh_compose_unicode_screenshot(); + if (!wp) + return 0; + len = wcslen(wp); + chr_size = sizeof(WCHAR); + } else +#endif + { + p = nh_compose_ascii_screenshot(); + if (!p) + return 0; + len = strlen(p); + } if (!OpenClipboard(hWnd)) { NHMessageBox(hWnd, TEXT("Cannot open clipboard"), MB_OK | MB_ICONERROR); free(p); +#ifdef ENHANCED_SYMBOLS + free(wp); +#endif return 0; } EmptyClipboard(); - hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * sizeof(char)); + hglbCopy = GlobalAlloc(GMEM_MOVEABLE, (len + 1) * chr_size); if (hglbCopy == NULL) { CloseClipboard(); free(p); +#ifdef ENHANCED_SYMBOLS + free(wp); +#endif return FALSE; } - p_copy = (char *) GlobalLock(hglbCopy); - strncpy(p_copy, p, len); - p_copy[len] = 0; // null character +#ifdef ENHANCED_SYMBOLS + if (SYMHANDLING(H_UTF8)) { + WCHAR *p_copy = (WCHAR *) GlobalLock(hglbCopy); + wcsncpy(p_copy, wp, len); + p_copy[len] = 0; // null character + } else +#endif + { + char *p_copy = (char *) GlobalLock(hglbCopy); + strncpy(p_copy, p, len); + p_copy[len] = 0; // null character + } GlobalUnlock(hglbCopy); - SetClipboardData(SYMHANDLING(H_IBM) ? CF_OEMTEXT : CF_TEXT, hglbCopy); +#ifdef ENHANCED_SYMBOLS + if (SYMHANDLING(H_UTF8)) + SetClipboardData(CF_UNICODETEXT, hglbCopy); + else +#endif + SetClipboardData(SYMHANDLING(H_IBM) ? CF_OEMTEXT : CF_TEXT, hglbCopy); CloseClipboard(); free(p); +#ifdef ENHANCED_SYMBOLS + free(wp); +#endif } break; case IDM_SETTING_SCREEN_TO_FILE: { @@ -1276,3 +1316,57 @@ nh_compose_ascii_screenshot(void) free(text); return retval; } + +#ifdef ENHANCED_SYMBOLS +// returns malloc() created pointer - callee assumes the ownership +static WCHAR * +nh_compose_unicode_screenshot(void) +{ + WCHAR *retval; + PMSNHMsgGetText text; + PMSNHMsgGetWideText wtext; + size_t retsize; + const size_t max_size = 3 * TEXT_BUFFER_SIZE; + + retval = (WCHAR *) malloc(max_size * sizeof(WCHAR)); + retsize = 0; + + text = + (PMSNHMsgGetText) malloc(sizeof(MSNHMsgGetText) + TEXT_BUFFER_SIZE); + text->max_size = + TEXT_BUFFER_SIZE + - 1; /* make sure we always have 0 at the end of the buffer */ + + wtext = + (PMSNHMsgGetWideText) malloc(sizeof(MSNHMsgGetWideText) + + TEXT_BUFFER_SIZE * sizeof(WCHAR)); + wtext->max_size = + TEXT_BUFFER_SIZE + - 1; /* make sure we always have 0 at the end of the buffer */ + + ZeroMemory(text->buffer, TEXT_BUFFER_SIZE); + SendMessage(mswin_hwnd_from_winid(WIN_MESSAGE), WM_MSNH_COMMAND, + (WPARAM) MSNH_MSG_GETTEXT, (LPARAM) text); + retsize += MultiByteToWideChar(CP_ACP, 0, + text->buffer, strlen(text->buffer), + retval + retsize, max_size - retsize); + + ZeroMemory(wtext->buffer, TEXT_BUFFER_SIZE * sizeof(WCHAR)); + SendMessage(mswin_hwnd_from_winid(WIN_MAP), WM_MSNH_COMMAND, + (WPARAM) MSNH_MSG_GETWIDETEXT, (LPARAM) wtext); + wcsncpy(retval + retsize, wtext->buffer, max_size - retsize - 1); + retsize += wcslen(retval + retsize); + + ZeroMemory(text->buffer, TEXT_BUFFER_SIZE); + SendMessage(mswin_hwnd_from_winid(WIN_STATUS), WM_MSNH_COMMAND, + (WPARAM) MSNH_MSG_GETTEXT, (LPARAM) text); + retsize += MultiByteToWideChar(CP_ACP, 0, + text->buffer, strlen(text->buffer), + retval + retsize, max_size - retsize); + retval[retsize] = L'\0'; + + free(text); + free(wtext); + return retval; +} +#endif diff --git a/win/win32/mhmap.c b/win/win32/mhmap.c index 723a0f7ce..bee0b8282 100644 --- a/win/win32/mhmap.c +++ b/win/win32/mhmap.c @@ -765,6 +765,36 @@ onMSNHCommand(HWND hWnd, WPARAM wParam, LPARAM lParam) } } break; +#ifdef ENHANCED_SYMBOLS + case MSNH_MSG_GETWIDETEXT: { + PMSNHMsgGetWideText msg_data = (PMSNHMsgGetWideText) lParam; + size_t index; + int col, row; + + index = 0; + for (row = 0; row < ROWNO; row++) { + for (col = 0; col < COLNO; col++) { + glyph_info *glyphinfo; + uint32 ch; + if (index >= msg_data->max_size) + break; + glyphinfo = &data->map[col][row]; + if (glyphinfo->gm.u && glyphinfo->gm.u->utf8str) { + ch = glyphinfo->gm.u->utf32ch; + } else { + ch = glyphinfo->ttychar; + } + winos_ascii_to_wide(msg_data->buffer + index, ch); + index += wcslen(msg_data->buffer + index); + } + if (index >= msg_data->max_size - 1) + break; + msg_data->buffer[index++] = '\r'; + msg_data->buffer[index++] = '\n'; + } + } break; +#endif + case MSNH_MSG_RANDOM_INPUT: nhassert(0); // unexpected break; diff --git a/win/win32/mhmsg.h b/win/win32/mhmsg.h index 9ccd1bd2d..90413e0cc 100644 --- a/win/win32/mhmsg.h +++ b/win/win32/mhmsg.h @@ -22,6 +22,9 @@ #define MSNH_MSG_GETTEXT 111 #define MSNH_MSG_UPDATE_STATUS 112 #define MSNH_MSG_RANDOM_INPUT 113 +#ifdef ENHANCED_SYMBOLS +#define MSNH_MSG_GETWIDETEXT 114 +#endif typedef struct mswin_nhmsg_add_wnd { winid wid; @@ -71,6 +74,13 @@ typedef struct mswin_nhmsg_get_text { char buffer[TEXT_BUFFER_SIZE]; } MSNHMsgGetText, *PMSNHMsgGetText; +#ifdef ENHANCED_SYMBOLS +typedef struct mswin_nhmsg_get_wide_text { + size_t max_size; + WCHAR buffer[TEXT_BUFFER_SIZE]; +} MSNHMsgGetWideText, *PMSNHMsgGetWideText; +#endif + typedef struct mswin_nhmsg_update_status { struct mswin_status_lines * status_lines; } MSNHMsgUpdateStatus, *PMSNHMsgUpdateStatus;