Revision: 7969 https://osdn.net/projects/ttssh2/scm/svn/commits/7969 Author: zmatsuo Date: 2019-08-15 23:05:04 +0900 (Thu, 15 Aug 2019) Log Message: ----------- Unicodeクリップボードからのペースト Modified Paths: -------------- branches/unicode_buf/teraterm/teraterm/CMakeLists.txt branches/unicode_buf/teraterm/teraterm/clipboar.c branches/unicode_buf/teraterm/teraterm/clipboar.h branches/unicode_buf/teraterm/teraterm/teraterm.cpp branches/unicode_buf/teraterm/teraterm/vtterm.c branches/unicode_buf/teraterm/teraterm/vtwin.cpp branches/unicode_buf/teraterm/ttpmacro/fileread.cpp branches/unicode_buf/teraterm/ttpmacro/fileread.h -------------- next part -------------- Modified: branches/unicode_buf/teraterm/teraterm/CMakeLists.txt =================================================================== --- branches/unicode_buf/teraterm/teraterm/CMakeLists.txt 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/teraterm/CMakeLists.txt 2019-08-15 14:05:04 UTC (rev 7969) @@ -145,6 +145,9 @@ unicode.cpp unicode_asian_width.tbl unicode_combine.tbl + # + ../ttpmacro/fileread.h + ../ttpmacro/fileread.cpp ) include_directories( Modified: branches/unicode_buf/teraterm/teraterm/clipboar.c =================================================================== --- branches/unicode_buf/teraterm/teraterm/clipboar.c 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/teraterm/clipboar.c 2019-08-15 14:05:04 UTC (rev 7969) @@ -1,6 +1,6 @@ /* * Copyright (C) 1994-1998 T. Teranishi - * (C) 2006-2017 TeraTerm Project + * (C) 2006-2019 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,6 +36,7 @@ #include <stdlib.h> #include <stdio.h> #include <commctrl.h> +#include <crtdbg.h> #include "ttwinman.h" #include "ttcommon.h" @@ -44,7 +45,10 @@ #include "clipboar.h" #include "tt_res.h" +#include "../ttpmacro/fileread.h" +#define UNICODE_BUF 1 + // for clipboard copy static HGLOBAL CBCopyHandle = NULL; static PCHAR CBCopyPtr = NULL; @@ -62,8 +66,20 @@ static BOOL CBEchoOnly; static BOOL CBInsertDelay = FALSE; -static LRESULT CALLBACK OnClipboardDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp); +#if UNICODE_BUF +typedef struct { + wchar_t *send_str; + size_t str_len; + size_t send_left; + size_t send_index; + BOOL waited; + DWORD send_cr_tick; +} clipbard_work_t; +static clipbard_work_t cbwork; +#endif +static INT_PTR CALLBACK OnClipboardDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp); + PCHAR CBOpen(LONG MemSize) { if (MemSize==0) { @@ -169,7 +185,8 @@ } // \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x83o\x83b\x83t\x83@\x82̖\x96\x94\xF6\x82ɂ\xA0\x82\xE9 CR / LF \x82\xF0\x82\xB7\x82ׂč폜\x82\xB7\x82\xE9 -BOOL TrimTrailingNL(BOOL AddCR, BOOL Bracketed) { +static BOOL TrimTrailingNL(BOOL AddCR, BOOL Bracketed) +{ PCHAR tail; if (ts.PasteFlag & CPF_TRIM_TRAILING_NL) { for (tail = CBMemPtr+strlen(CBMemPtr)-1; tail >= CBMemPtr; tail--) { @@ -183,8 +200,20 @@ return TRUE; } +static void TrimTrailingNLW(wchar_t *src) +{ + wchar_t *tail = src + wcslen(src) - 1; + while(tail >= src) { + if (*tail != L'\r' && *tail != L'\n') { + break; + } + *tail = L'\0'; + tail--; + } +} + // \x89\xFC\x8Ds\x82\xF0 CR+LF \x82ɐ\xB3\x8BK\x89\xBB\x82\xB7\x82\xE9 -BOOL NormalizeLineBreak(BOOL AddCR, BOOL Bracketed) { +static BOOL NormalizeLineBreak(BOOL AddCR, BOOL Bracketed) { char *p, *p2; unsigned int len, need_len, alloc_len; HGLOBAL TmpHandle; @@ -273,8 +302,73 @@ return TRUE; } +static wchar_t *NormalizeLineBreakW(const wchar_t *src_) +{ + const wchar_t *src = src_; + wchar_t *dest_top; + wchar_t *dest; + size_t len, need_len, alloc_len; + const size_t src_len = wcslen(src_); + + // \x93\\x82\xE8\x95t\x82\xAF\x83f\x81[\x83^\x82̒\xB7\x82\xB3(len)\x81A\x82\xA8\x82\xE6\x82ѐ\xB3\x8BK\x89\xBB\x8C\xE3\x82̃f\x81[\x83^\x82̒\xB7\x82\xB3(need_len)\x82̃J\x83E\x83\x93\x83g + for (len=0, need_len=0, src=src_; *src != '\0'; src++, len++, need_len++) { + if (*src == CR) { + need_len++; + if (*(src+1) == LF) { + len++; + src++; + } + } + else if (*src == LF) { + need_len++; + } + } + + // \x90\xB3\x8BK\x89\xBB\x8C\xE3\x82\xE0\x83f\x81[\x83^\x92\xB7\x82\xAA\x95ς\xED\x82\xE7\x82Ȃ\xA2 => \x90\xB3\x8BK\x89\xBB\x82͕K\x97v\x82Ȃ\xB5 + if (need_len == len) { + wchar_t *dest = _wcsdup(src_); + return dest; + } + alloc_len = need_len + 1; + + dest_top = (wchar_t *)malloc(sizeof(wchar_t) * alloc_len); + + src = src_ + len - 1; + dest = dest_top + need_len; + *dest-- = '\0'; + len = need_len; + + while (len > 0 && dest_top <= dest) { + if (*src == LF) { + *dest-- = *src--; + if (--len == 0) { + *dest = CR; + break; + } + if (*src != CR) { + *dest-- = CR; + if (dest <= dest_top) { + break; + } + else { + continue; + } + } + } + else if (*src == CR) { + *dest-- = LF; + if (src == dest) + break; + } + *dest-- = *src--; + len--; + } + + return dest_top; +} + // \x83t\x83@\x83C\x83\x8B\x82ɒ\xE8\x8B`\x82\xB3\x82ꂽ\x95\xB6\x8E\x9A\x97Atext\x82Ɋ܂܂\xEA\x82邩\x82ׂ\xE9\x81B -BOOL search_dict(char *filename, char *text) +static BOOL search_dict(char *filename, char *text) { BOOL ret = FALSE; FILE *fp = NULL; @@ -307,6 +401,58 @@ return (ret); } +/** + * \x83t\x83@\x83C\x83\x8B\x82ɒ\xE8\x8B`\x82\xB3\x82ꂽ\x95\xB6\x8E\x9A\x97Atext\x82Ɋ܂܂\xEA\x82邩\x82ׂ\xE9\x81B + * \x8C\xA9\x82\xA9\x82\xEA\x82\xCE TRUE\x82\xF0\x95Ԃ\xB7 + */ +static BOOL search_dictW(char *filename, const wchar_t *text) +{ + BOOL result = FALSE; + const wchar_t *buf_top = LoadFileWA(filename, NULL); + const wchar_t *buf = buf_top; + if (buf == NULL) { + return FALSE; + } + + for(;;) { + const wchar_t *line_end; + size_t len; + wchar_t *search_str; + if (*buf == 0) { + break; + } + if (*buf == '\r' || *buf == '\n') { + buf++; + continue; + } + line_end = wcspbrk(buf, L"\r\n"); + if (line_end == NULL) { + // \x89\xFC\x8Ds\x82\xAA\x82Ȃ\xA2 + len = wcslen(buf); + if (len == 0) { + // \x8FI\x97\xB9 + break; + } + } else { + len = line_end - buf; + } + search_str = (wchar_t *)malloc(sizeof(wchar_t) * (len+1)); + if (search_str == NULL) + continue; + memcpy(search_str, buf, sizeof(wchar_t) * len); + search_str[len] = 0; + buf += len; + result = (wcsstr(text, search_str) != NULL); + free(search_str); + if (result) { + result = TRUE; + break; + } + } + free((void *)buf_top); + return result; +} + /* * \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82̓\xE0\x97e\x82\xF0\x8Am\x94F\x82\xB5\x81A\x93\\x82\xE8\x95t\x82\xAF\x82\xF0\x8Ds\x82\xA4\x82\xA9\x8Am\x94F\x83_\x83C\x83A\x83\x8D\x83O\x82\xF0\x8Fo\x82\xB7\x81B * @@ -372,6 +518,55 @@ } } +/* + * \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82̓\xE0\x97e\x82\xF0\x8Am\x94F\x82\xB5\x81A\x93\\x82\xE8\x95t\x82\xAF\x82\xF0\x8Ds\x82\xA4\x82\xA9\x8Am\x94F\x83_\x83C\x83A\x83\x8D\x83O\x82\xF0\x8Fo\x82\xB7\x81B + * + * \x95Ԃ\xE8\x92l: + * TRUE -> \x96\xE2\x91\xE8\x82Ȃ\xB5\x81A\x93\\x82\xE8\x95t\x82\xAF\x82\xF0\x8E\xC0\x8E{ + * FALSE -> \x93\\x82\xE8\x95t\x82\xAF\x92\x86\x8E~ + */ +static BOOL CheckClipboardContentW(HWND HWin, const wchar_t *str_w, BOOL AddCR, BOOL Bracketed) +{ + int ret = IDOK; + BOOL confirm = FALSE; + + if ((ts.PasteFlag & CPF_CONFIRM_CHANGEPASTE) == 0) { + return TRUE; + } + + if (AddCR) { + if (ts.PasteFlag & CPF_CONFIRM_CHANGEPASTE_CR) { + confirm = TRUE; + } + } + else { + size_t pos = wcscspn(str_w, L"\r\n"); // \x89\xFC\x8Ds\x82\xAA\x8A܂܂\xEA\x82Ă\xA2\x82\xBD\x82\xE7 + if (str_w[pos] != '\0') { + confirm = TRUE; + } + } + + // \x8E\xAB\x8F\x91\x82\xF0\x83T\x81[\x83`\x82\xB7\x82\xE9 + if (!confirm && search_dictW(ts.ConfirmChangePasteStringFile, str_w)) { + confirm = TRUE; + } + + if (confirm) { + ret = TTDialogBox(hInst, MAKEINTRESOURCE(IDD_CLIPBOARD_DIALOG), + HWin, (DLGPROC)OnClipboardDlgProc); + /* + * \x88ȑO\x82̓_\x83C\x83A\x83\x8D\x83O\x82̓\xE0\x97e\x82\xF0\x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82ɏ\x91\x82\xAB\x96߂\xB5\x82Ă\xA2\x82\xBD\x82\xAF\x82\xEA\x82ǁA\x95K\x97v? + */ + } + + if (ret == IDOK) { + return TRUE; + } + else { + return FALSE; + } +} + void CBStartPaste(HWND HWin, BOOL AddCR, BOOL Bracketed) { UINT Cf; @@ -522,6 +717,156 @@ CBMemPtr = NULL; } +/** + * \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82\xA9\x82\xE7wchar_t\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82\xB7\x82\xE9 + * \x95\xB6\x8E\x9A\x97\xAA\x95K\x97v\x82ȂƂ\xAB\x82\xCDwcslen()\x82\xB7\x82邱\x82\xC6 + * @param hWnd + * @param emtpy TRUE\x82̂Ƃ\xAB\x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82\xF0\x8B\xF3\x82ɂ\xB7\x82\xE9 + * @retval \x95\xB6\x8E\x9A\x97\xF1\x82ւ̃|\x83C\x83\x93\x83^ \x8Eg\x97p\x8C\xE3free()\x82\xB7\x82邱\x82\xC6 + * \x95\xB6\x8E\x9A\x82\xAA\x82Ȃ\xA2(\x82܂\xBD\x82̓G\x83\x89\x81[\x8E\x9E)\x82\xCDNULL + * + * TODO ttssh2/ttxssh/auth.c \x82\xCC GetClipboardTextA() \x82̒u\x82\xAB\x8A\xB7\x82\xA6 + */ +static wchar_t *GetClipboardTextW(HWND hWnd, BOOL empty) +{ + UINT Cf; + wchar_t *str_w = NULL; + size_t str_w_len; + HGLOBAL TmpHandle; + + if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { + Cf = CF_UNICODETEXT; + } + else if (IsClipboardFormatAvailable(CF_TEXT)) { + Cf = CF_TEXT; + } + else if (IsClipboardFormatAvailable(CF_OEMTEXT)) { + Cf = CF_OEMTEXT; + } + else { + return NULL; + } + + if (!OpenClipboard(hWnd)) { + return NULL; + } + TmpHandle = GetClipboardData(Cf); + if (TmpHandle == NULL) { + return NULL; + } + if (Cf == CF_UNICODETEXT) { + const wchar_t *str_cb = (wchar_t *)GlobalLock(TmpHandle); + if (str_cb != NULL) { + size_t str_cb_len = GlobalSize(TmpHandle); // bytes + str_w_len = str_cb_len / sizeof(wchar_t); + str_w = malloc((str_w_len + 1) * sizeof(wchar_t)); // +1 for terminator + memcpy(str_w, str_cb, str_cb_len); + str_w[str_w_len] = L'\0'; + } + } + else { + const char *str_cb = (char *)GlobalLock(TmpHandle); + if (str_cb != NULL) { + size_t str_cb_len = GlobalSize(TmpHandle); + str_w_len = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str_cb, str_cb_len, NULL, 0); + str_w = malloc(sizeof(wchar_t) * (str_w_len + 1)); // +1 for terminator + str_w_len = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str_cb, str_cb_len, str_w, str_w_len); + str_w[str_w_len] = L'\0'; + } + } + GlobalUnlock(TmpHandle); + if (empty) { + EmptyClipboard(); + } + CloseClipboard(); + return str_w; +} + +#if 1 +void CBStartPasteW(HWND HWin, BOOL AddCR, BOOL Bracketed) +{ + unsigned int StrLen = 0, BuffLen = 0; + clipbard_work_t *p; + wchar_t *str_w; + + if (! cv.Ready) { + return; + } + if (TalkStatus!=IdTalkKeyb) { + return; + } + + CBEchoOnly = FALSE; + + p = &cbwork; + if (p->send_str != NULL) { + // \x91\x97\x90M\x92\x86? + return; + } + + str_w = GetClipboardTextW(HWin, FALSE); + if (str_w == NULL) { + // \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x82\xA9\x82當\x8E\x9A\x97\xF1\x82\xF0\x8E擾\x82ł\xAB\x82Ȃ\xA9\x82\xC1\x82\xBD + CBEndPaste(); + return; + } + p->send_str = str_w; + + if (Bracketed) { + BuffLen += BracketStartLen + BracketEndLen; + } + + if (ts.PasteFlag & CPF_TRIM_TRAILING_NL) { + // \x83o\x83b\x83t\x83@\x8DŌ\xE3\x82̉\xFC\x8Ds\x82\xF0\x8D폜 + TrimTrailingNLW(str_w); + } + + if (!(ts.PasteFlag & CPF_NORMALIZE_LINEBREAK)) { + // \x89\xFC\x8Ds\x82𐳋K\x89\xBB + wchar_t *dest = NormalizeLineBreakW(str_w); + free(str_w); + str_w = dest; + } + + p->send_str = str_w; // \x83_\x83C\x83A\x83\x8D\x83O\x82ŕ\\x8E\xA6\x82\xB7\x82\xE9 + if (!CheckClipboardContentW(HWin, str_w, AddCR, Bracketed)) { + CBEndPaste(); + return; + } + + if (AddCR) { + size_t str_len = wcslen(str_w) + 2; + str_w = realloc(str_w, sizeof(wchar_t) * str_len); + str_w[str_len-2] = L'\r'; + str_w[str_len-1] = 0; + } + + if (Bracketed) { + size_t str_len = wcslen(str_w); + size_t dest_len = str_len + BracketStartLen + BracketEndLen; + wchar_t *dest = malloc(sizeof(wchar_t) * (dest_len+1)); + size_t i = 0; + memcpy(&dest[i], BracketStart, BracketStartLen); + i += BracketStartLen; + memcpy(&dest[i], str_w, str_len); + i += str_len; + memcpy(&dest[i], BracketEnd, BracketEndLen); + i += BracketEndLen; + dest[i] = 0; + free(str_w); + str_w = dest; + } + + // \x93\\x82\xE8\x95t\x82\xAF\x82̏\x80\x94\x{142A90}\xB3\x8F\xED\x82ɏo\x97\x88\x82\xBD + p->send_str = str_w; + p->send_index = 0; + p->waited = FALSE; + p->str_len = wcslen(p->send_str); + p->send_left = p->str_len; + TalkStatus = IdTalkCB; +} +#endif + void CBStartPasteB64(HWND HWin, PCHAR header, PCHAR footer) { HANDLE tmpHandle = NULL; @@ -738,6 +1083,89 @@ } } +// \x83N\x83\x8A\x83b\x83v\x83{\x81[\x83h\x83f\x81[\x83^\x82\xF0\x92[\x96\x96\x82֑\x97\x82荞\x82ށB +// +void CBSendW() +{ + clipbard_work_t *p = &cbwork; + int c; + + if (p->send_str == NULL) { + return; + } + + if (CBEchoOnly) { + CBEcho(); + return; + } + + if (ts.PasteDelayPerLine > 0 && p->waited) { + // \x8Ds\x96\x88wait + if (GetTickCount() - p->send_cr_tick < (DWORD)ts.PasteDelayPerLine) { + return; + } + } + + if (CBRetryEcho) { + c = CommTextEcho(&cv,(PCHAR)&CBByte,1); + CBRetryEcho = (c==0); + if (CBRetryEcho) { + return; + } + } + + for(;;){ + BOOL send_one_line = FALSE; + size_t send_len; + int r; + + // \x8FI\x92[? + if (p->send_str[p->send_index] == 0) { + // \x8FI\x97\xB9 + CBEndPaste(); + return; + } + + send_len = p->send_left; + if (ts.PasteDelayPerLine > 0) { + // 1\x8Ds\x8E\xE6\x82\xE8\x8Fo\x82\xB5(clipboard\x82̉\xFC\x8Ds\x82\xCD L"\r\n") + const wchar_t *line_top = &p->send_str[p->send_index]; + const wchar_t *line_end = wcsstr(line_top, L"\r\n"); + if (line_end != NULL && *line_end == 0x0d && *(line_end+1) == 0x0a) { + // L'\r' \x82܂ő\x97\x90M + send_len = (line_end - line_top) + 1; + send_one_line = TRUE; + } else { + // \x89\xFC\x8Ds\x8C\xA9\x82\xA9\x82炸\x81A\x8DŌ\xE3\x82܂ő\x97\x90M + send_len = p->send_left; + } + } + + r = CommTextOutW(&cv, &p->send_str[p->send_index], send_len); + if ((r != 0) && (ts.LocalEcho>0)) { + CommTextEchoW(&cv, &p->send_str[p->send_index], send_len); + } + if (r == 0) { + // \x8Fo\x97͂ł\xAB\x82Ȃ\xAD\x82Ȃ\xC1\x82\xBD(\x8Fo\x97̓o\x83b\x83t\x83@\x82\xAA\x82\xA2\x82\xC1\x82ς\xA2?) + return; + } + p->send_index += r; + p->send_left -= r; + + if (send_one_line) { + // L'\n'\x82̓X\x83\x8B\x81[\x82\xB7\x82\xE9 + p->send_index++; + p->send_left--; + + // wait\x82ɓ\xFC\x82\xE9 + p->waited = TRUE; + p->send_cr_tick = GetTickCount(); + SetTimer(HVTWin, IdPasteDelayTimer, ts.PasteDelayPerLine, NULL); + break; + } + } +} + void CBEcho() { if (CBMemHandle==NULL) { @@ -792,8 +1220,14 @@ void CBEndPaste() { + clipbard_work_t *p = &cbwork; TalkStatus = IdTalkKeyb; + if (p->send_str != NULL) { + free(p->send_str); + p->send_str = NULL; + } + if (CBMemHandle!=NULL) { if (CBMemPtr!=NULL) { GlobalUnlock(CBMemHandle); @@ -806,6 +1240,7 @@ CBMemPtr2 = 0; CBEchoOnly = FALSE; CBInsertDelay = FALSE; + _CrtCheckMemory(); } BOOL CBSetClipboard(HWND owner, HGLOBAL hMem) @@ -858,7 +1293,7 @@ return hMem; } -static LRESULT CALLBACK OnClipboardDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp) +static INT_PTR CALLBACK OnClipboardDlgProc(HWND hDlgWnd, UINT msg, WPARAM wp, LPARAM lp) { static const DlgTextInfo TextInfos[] = { { 0, "DLG_CLIPBOARD_TITLE" }, @@ -878,7 +1313,15 @@ case WM_INITDIALOG: SetDlgTexts(hDlgWnd, TextInfos, _countof(TextInfos), ts.UILanguageFile); +#if UNICODE_BUF + if (cbwork.send_str != NULL) { + SetDlgItemTextW(hDlgWnd, IDC_EDIT, cbwork.send_str); + } else { + SetDlgItemTextA(hDlgWnd, IDC_EDIT, CBMemPtr); + } +#else SetDlgItemTextA(hDlgWnd, IDC_EDIT, CBMemPtr); +#endif if (ActiveWin == IdVT) { // VT Window /* Modified: branches/unicode_buf/teraterm/teraterm/clipboar.h =================================================================== --- branches/unicode_buf/teraterm/teraterm/clipboar.h 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/teraterm/clipboar.h 2019-08-15 14:05:04 UTC (rev 7969) @@ -35,13 +35,15 @@ /* prototypes */ PCHAR CBOpen(LONG MemSize); -void CBClose(); +void CBClose(void); void CBStartSend(PCHAR DataPtr, int DataSize, BOOL EchoOnly); void CBStartPaste(HWND HWin, BOOL AddCR, BOOL Bracketed); +void CBStartPasteW(HWND HWin, BOOL AddCR, BOOL Bracketed); void CBStartPasteB64(HWND HWin, PCHAR header, PCHAR footer); -void CBSend(); -void CBEcho(); -void CBEndPaste(); +void CBSend(void); +void CBSendW(void); +void CBEcho(void); +void CBEndPaste(void); #ifdef __cplusplus } Modified: branches/unicode_buf/teraterm/teraterm/teraterm.cpp =================================================================== --- branches/unicode_buf/teraterm/teraterm/teraterm.cpp 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/teraterm/teraterm.cpp 2019-08-15 14:05:04 UTC (rev 7969) @@ -202,7 +202,11 @@ /* Talker */ switch (TalkStatus) { case IdTalkCB: +#if UNICODE_INTERNAL_BUFF + CBSendW(); +#else CBSend(); +#endif break; /* clip board */ case IdTalkFile: FileSend(); @@ -300,6 +304,7 @@ } if (!message_processed) { + _CrtCheckMemory(); TranslateMessage(&msg); DispatchMessage(&msg); } @@ -306,6 +311,7 @@ while (!PeekMessage(&msg, NULL, NULL, NULL, PM_NOREMOVE)) { // \x83\x81\x83b\x83Z\x81[\x83W\x82\xAA\x82Ȃ\xA2 + _CrtCheckMemory(); if (!OnIdle(lCount)) { // idle\x95s\x97v if (SleepTick < 500) { // \x8Dő\xE5 501ms\x96\xA2\x96\x9E @@ -318,6 +324,7 @@ SleepTick = 0; lCount++; } + _CrtCheckMemory(); } } delete m_pMainWnd; Modified: branches/unicode_buf/teraterm/teraterm/vtterm.c =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtterm.c 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/teraterm/vtterm.c 2019-08-15 14:05:04 UTC (rev 7969) @@ -791,7 +791,7 @@ Special = FALSE; } -#if 1 +#if UNICODE_INTERNAL_BUFF { // codepage\x88ꗗ // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-ucoderef/28fefe92-d66c-4b03-90a9-97b473223d43 @@ -5417,7 +5417,7 @@ static void ParseASCII(BYTE b) { -#if 0 +#if !UNICODE_INTERNAL_BUFF if (ts.Language == IdJapanese) { ParseFirstJP(b); return; @@ -5829,7 +5829,7 @@ // returns if b is processed { if (b>=128) { -#if 0 +#if !UNICODE_INTERNAL_BUFF b = RussConv(ts.RussHost,ts.RussClient,b); PutChar(b); #else Modified: branches/unicode_buf/teraterm/teraterm/vtwin.cpp =================================================================== --- branches/unicode_buf/teraterm/teraterm/vtwin.cpp 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/teraterm/vtwin.cpp 2019-08-15 14:05:04 UTC (rev 7969) @@ -849,7 +849,11 @@ } if (Paste) { +#if UNICODE_INTERNAL_BUFF + CBStartPasteW(HVTWin, FALSE, BracketedPasteMode()); +#else CBStartPaste(HVTWin, FALSE, BracketedPasteMode()); +#endif // \x83X\x83N\x83\x8D\x81[\x83\x8B\x88ʒu\x82\xF0\x83\x8A\x83Z\x83b\x83g if (WinOrgY != 0) { DispVScroll(SCROLL_BOTTOM, 0); @@ -4392,8 +4396,12 @@ void CVTWindow::OnEditPaste() { +#if UNICODE_INTERNAL_BUFF + CBStartPasteW(HVTWin, FALSE, BracketedPasteMode()); +#else // add confirm (2008.2.4 yutaka) CBStartPaste(HVTWin, FALSE, BracketedPasteMode()); +#endif // \x83X\x83N\x83\x8D\x81[\x83\x8B\x88ʒu\x82\xF0\x83\x8A\x83Z\x83b\x83g if (WinOrgY != 0) { DispVScroll(SCROLL_BOTTOM, 0); @@ -4402,8 +4410,12 @@ void CVTWindow::OnEditPasteCR() { +#if UNICODE_INTERNAL_BUFF + CBStartPasteW(HVTWin, TRUE, BracketedPasteMode()); +#else // add confirm (2008.3.11 maya) CBStartPaste(HVTWin, TRUE, BracketedPasteMode()); +#endif // \x83X\x83N\x83\x8D\x81[\x83\x8B\x88ʒu\x82\xF0\x83\x8A\x83Z\x83b\x83g if (WinOrgY != 0) { DispVScroll(SCROLL_BOTTOM, 0); Modified: branches/unicode_buf/teraterm/ttpmacro/fileread.cpp =================================================================== --- branches/unicode_buf/teraterm/ttpmacro/fileread.cpp 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/ttpmacro/fileread.cpp 2019-08-15 14:05:04 UTC (rev 7969) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 TeraTerm Project + * Copyright (C) 2018-2019 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,6 +68,7 @@ * \x83t\x83@\x83C\x83\x8B\x82̍Ō\xE3\x82\xCD '\0'\x82Ń^\x81[\x83~\x83l\x81[\x83g\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9 * * @param[out] *_len \x83T\x83C\x83Y(\x8DŌ\xE3\x82ɕt\x89\xC1\x82\xB3\x82\xEA\x82\xE9"\0"\x82\xF0\x8A܂\xDE) + * NULL\x82̂Ƃ\xAB\x82͒\xB7\x82\xB3\x82\xF0\x95Ԃ\xB3\x82Ȃ\xA2 * @retval \x83t\x83@\x83C\x83\x8B\x82̒\x86\x90g\x82ւ̃|\x83C\x83\x93\x83^(\x8Eg\x97p\x8C\xE3free()\x82\xB7\x82邱\x82\xC6) * NULL=\x83G\x83\x89\x81[ */ @@ -76,7 +77,9 @@ size_t len; void *vbuf = LoadRawFile(fp, &len); if (vbuf == NULL) { - *_len = 0; + if (_len != NULL) { + *_len = 0; + } return NULL; } @@ -122,7 +125,9 @@ } } - *_len = strlen((char *)buf)+1; // \x89\xFC\x82߂Ē\xB7\x82\xB3\x82\xF0\x8Cv\x82\xE9 + if (_len != NULL) { + *_len = strlen((char *)buf)+1; // \x89\xFC\x82߂Ē\xB7\x82\xB3\x82\xF0\x8Cv\x82\xE9 + } return (char *)buf; } @@ -151,6 +156,47 @@ return u8; } +/** + * \x83t\x83@\x83C\x83\x8B\x82\xF0\x83\x81\x83\x82\x83\x8A\x82ɓǂݍ\x9E\x82\xDE + * \x92\x86\x90g\x82\xCDwchar_t\x82ɕϊ\xB7\x82\xB3\x82\xEA\x82\xE9 + * + * @param[out] *_len \x83T\x83C\x83Y(\x8DŌ\xE3\x82ɕt\x89\xC1\x82\xB3\x82\xEA\x82\xE9"\0"\x82\xF0\x8A܂\xDE) + * NULL\x82̂Ƃ\xAB\x82͒\xB7\x82\xB3\x82\xF0\x95Ԃ\xB3\x82Ȃ\xA2 + * @retval \x83t\x83@\x83C\x83\x8B\x82̒\x86\x90g\x82ւ̃|\x83C\x83\x93\x83^(\x8Eg\x97p\x8C\xE3free()\x82\xB7\x82邱\x82\xC6) + * NULL=\x83G\x83\x89\x81[ + */ +wchar_t *LoadFileWA(const char *FileName, size_t *_len) +{ + if (_len != NULL) { + *_len = 0; + } + FILE *fp = fopen(FileName, "rb"); + if (fp == NULL) { + return NULL; + } + char *u8 = LoadFileU8(fp, NULL); + if (u8 == NULL) { + return NULL; + } + const wchar_t *u16 = ToWcharU8(u8); + free(u8); + if (u16 == NULL) { + return NULL; + } + if (_len != NULL) { + *_len = wcslen(u16); + } + return (wchar_t *)u16; +} + +/** + * \x83t\x83@\x83C\x83\x8B\x82\xF0\x83\x81\x83\x82\x83\x8A\x82ɓǂݍ\x9E\x82\xDE + * \x92\x86\x90g\x82\xCDANSI Codepage\x82ɕϊ\xB7\x82\xB3\x82\xEA\x82\xE9 + * + * @param[out] *_len \x83T\x83C\x83Y(\x8DŌ\xE3\x82ɕt\x89\xC1\x82\xB3\x82\xEA\x82\xE9"\0"\x82\xF0\x8A܂\xDE) + * @retval \x83t\x83@\x83C\x83\x8B\x82̒\x86\x90g\x82ւ̃|\x83C\x83\x93\x83^(\x8Eg\x97p\x8C\xE3free()\x82\xB7\x82邱\x82\xC6) + * NULL=\x83G\x83\x89\x81[ + */ char *LoadFileAA(const char *FileName, size_t *_len) { *_len = 0; Modified: branches/unicode_buf/teraterm/ttpmacro/fileread.h =================================================================== --- branches/unicode_buf/teraterm/ttpmacro/fileread.h 2019-08-15 14:04:51 UTC (rev 7968) +++ branches/unicode_buf/teraterm/ttpmacro/fileread.h 2019-08-15 14:05:04 UTC (rev 7969) @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 TeraTerm Project + * Copyright (C) 2018-2019 TeraTerm Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ char *LoadFileU8A(const char *FileName, size_t *_len); char *LoadFileU8T(const TCHAR *FileName, size_t *_len); +wchar_t *LoadFileWA(const char *FileName, size_t *_len); char *LoadFileAA(const char *FileName, size_t *_len); #ifdef __cplusplus