[Ttssh2-commit] [7969] Unicodeクリップボードからのペースト

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2019年 8月 15日 (木) 23:05:04 JST


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\x97񂪁Atext\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\x97񂪁Atext\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


Ttssh2-commit メーリングリストの案内
Back to archive index