[Ttssh2-commit] [7472] unicode表示対応

scmno****@osdn***** scmno****@osdn*****
2019年 3月 10日 (日) 23:33:22 JST


Revision: 7472
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/7472
Author:   zmatsuo
Date:     2019-03-10 23:33:21 +0900 (Sun, 10 Mar 2019)
Log Message:
-----------
unicode表示対応

# Conflicts:
#	teraterm/teraterm/CMakeLists.txt

Modified Paths:
--------------
    branches/cmake/teraterm/common/ttlib.c
    branches/cmake/teraterm/common/ttlib.h
    branches/cmake/teraterm/teraterm/CMakeLists.txt
    branches/cmake/teraterm/teraterm/buffer.c
    branches/cmake/teraterm/teraterm/buffer.h
    branches/cmake/teraterm/teraterm/vtdisp.c
    branches/cmake/teraterm/teraterm/vtdisp.h
    branches/cmake/teraterm/teraterm/vtterm.c

-------------- next part --------------
Modified: branches/cmake/teraterm/common/ttlib.c
===================================================================
--- branches/cmake/teraterm/common/ttlib.c	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/common/ttlib.c	2019-03-10 14:33:21 UTC (rev 7472)
@@ -1145,14 +1145,26 @@
 }
 #endif
 
-void OutputDebugPrintf(const char *fmt, ...) {
+void OutputDebugPrintf(const char *fmt, ...)
+{
 	char tmp[1024];
 	va_list arg;
 	va_start(arg, fmt);
 	_vsnprintf(tmp, sizeof(tmp), fmt, arg);
+	va_end(arg);
 	OutputDebugStringA(tmp);
 }
 
+void OutputDebugPrintfW(const wchar_t *fmt, ...)
+{
+	wchar_t tmp[1024];
+	va_list arg;
+	va_start(arg, fmt);
+	_vsnwprintf(tmp, _countof(tmp), fmt, arg);
+	va_end(arg);
+	OutputDebugStringW(tmp);
+}
+
 #if (_MSC_VER < 1800)
 BOOL vercmp(
 	DWORD cond_val,

Modified: branches/cmake/teraterm/common/ttlib.h
===================================================================
--- branches/cmake/teraterm/common/ttlib.h	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/common/ttlib.h	2019-03-10 14:33:21 UTC (rev 7472)
@@ -96,6 +96,7 @@
 DllExport BOOL doSelectFolderW(HWND hWnd, wchar_t *path, int pathlen, const wchar_t *def, const wchar_t *msg);
 #endif
 DllExport void OutputDebugPrintf(const char *fmt, ...);
+DllExport void OutputDebugPrintfW(const wchar_t *fmt, ...);
 DllExport DWORD get_OPENFILENAME_SIZEA();
 DllExport DWORD get_OPENFILENAME_SIZEW();
 DllExport BOOL IsWindows95();

Modified: branches/cmake/teraterm/teraterm/CMakeLists.txt
===================================================================
--- branches/cmake/teraterm/teraterm/CMakeLists.txt	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/teraterm/CMakeLists.txt	2019-03-10 14:33:21 UTC (rev 7472)
@@ -3,22 +3,18 @@
 include(${CMAKE_CURRENT_SOURCE_DIR}/../../libs/lib_SFMT.cmake)
 include(${CMAKE_CURRENT_SOURCE_DIR}/../../libs/lib_oniguruma.cmake)
 
-if (MSVC)
-  string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_DEBUG            ${CMAKE_C_FLAGS_DEBUG})
-  string(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE          ${CMAKE_C_FLAGS_RELEASE})
-  string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_DEBUG          ${CMAKE_CXX_FLAGS_DEBUG})
-  string(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE        ${CMAKE_CXX_FLAGS_RELEASE})
-endif ()
+# UNICODE API を使用して文字描画を行う
+#	- 内部文字コードを unicodeとする
+#	- unicode api時のみ有効
+#	- 描画に ExtTextOutW() API を使用する
+option(USE_UNICODE_API_FOR_DISPLAY "unicode" ON)
 
-
 if(USE_UNICODE_API)
   add_definitions(-DUNICODE -D_UNICODE)
+  if(USE_UNICODE_API_FOR_DISPLAY)
+	add_definitions(-DUNICODE_DISPLAY=1)
+  endif()
 endif()
-if(LINK_UNICOWS)
-#  set(UNICOWS_LIB "${CMAKE_SOURCE_DIR}/libs/unicows_mingw/liblibunicows.a")
-  set(UNICOWS_LIB "${CMAKE_SOURCE_DIR}/libs/libunicows-1.1.2-msvc6/unicows.lib")
-endif()
-
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/")
 
 set(COMMON_SRC
@@ -26,6 +22,7 @@
   ../common/ttcommon.h
   ../common/ttddecmnd.h
   ../common/tttypes.h
+  ../common/tektypes.h
   ../common/ttftypes.h
   ../common/ttplugin.h
   ../common/tt-version.h
@@ -35,6 +32,8 @@
   ../common/dlglib.c
   ../common/dlglib_cpp.cpp
   ../common/dlglib.h
+  ../common/win16api.h
+  ../common/win16api.c
   ../common/dlglib_tmpl.cpp
   ../common/compat_win.cpp
   ../common/compat_win.h
@@ -45,8 +44,13 @@
   ../common/i18n.h
   ../common/win16api.h
   ../common/win16api.c
+  ../ttpcmn/language.h
   ../common/codeconv.h
   ../common/codeconv.cpp
+  #
+  ../teraterm/uni2sjis.map
+  ../ttpcmn/sjis2uni.map
+  ../teraterm/unisym2decsp.map
   )
 
 source_group(
@@ -131,6 +135,8 @@
   ttutil.c
   ttutil.h
   #
+  uni_combining.map
+  #
   teraterm.manifest
   #
   ${CMAKE_CURRENT_BINARY_DIR}/svnversion.h

Modified: branches/cmake/teraterm/teraterm/buffer.c
===================================================================
--- branches/cmake/teraterm/teraterm/buffer.c	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/teraterm/buffer.c	2019-03-10 14:33:21 UTC (rev 7472)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1994-1998 T. Teranishi
- * (C) 2004-2017 TeraTerm Project
+ * (C) 2004-2019 TeraTerm Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <windows.h>
+#include <crtdbg.h>
 
 #include "ttwinman.h"
 #include "teraprn.h"
@@ -43,9 +44,15 @@
 #include "clipboar.h"
 #include "telnet.h"
 #include "ttplug.h" /* TTPLUG */
+#include "codeconv.h"
 
 #include "buffer.h"
 
+#ifdef _DEBUG
+#define malloc(l)	_malloc_dbg((l), _NORMAL_BLOCK, __FILE__, __LINE__)
+#define free(p)		_free_dbg((p), _NORMAL_BLOCK)
+#endif
+
 // URL\x82\xF0\x8B\xAD\x92\xB2\x82\xB7\x82\xE9\x81i\x90΍莁\x83p\x83b\x83` 2005/4/2\x81j
 #define URL_EMPHASIS 1
 
@@ -83,6 +90,10 @@
 static PCHAR AttrLine2;
 static PCHAR AttrLineFG;
 static PCHAR AttrLineBG;
+#if 1
+static wchar_t *CodeBuffW;
+static wchar_t *CodeLineW;
+#endif
 static LONG LinePtr;
 static LONG BufferSize;
 static int NumOfLinesInBuff;
@@ -101,6 +112,24 @@
 int SaveBuffX;
 int SaveBuffY;
 
+void memcpyW(wchar_t *dest, const wchar_t *src, size_t count)
+{
+	memcpy(dest, src, count * sizeof(wchar_t));
+}
+
+void memsetW(wchar_t *dest, wchar_t ch, size_t count)
+{
+	size_t i;
+	for (i=0; i<count; i++) {
+		*dest++ = ch;
+	}
+}
+
+void memmoveW(wchar_t *dest, const wchar_t *src, size_t count)
+{
+	memmove(dest, src, count * sizeof(wchar_t));
+}
+
 LONG GetLinePtr(int Line)
 {
 	LONG Ptr;
@@ -136,8 +165,10 @@
 	LONG NewSize;
 	int NxCopy, NyCopy, i;
 	PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG;
+	wchar_t *CodeDestW;
 	LONG SrcPtr, DestPtr;
 	WORD LockOld;
+	wchar_t *CodeWNew;
 
 	if (Nx > BuffXMax) {
 		Nx = BuffXMax;
@@ -160,6 +191,7 @@
 	HAttr2New = NULL;
 	HAttrFGNew = NULL;
 	HAttrBGNew = NULL;
+	CodeWNew = NULL;
 
 	if ((HCodeNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (CodeDest=GlobalLock(HCodeNew)) == NULL) {
 		goto allocate_error;
@@ -176,8 +208,11 @@
 	if ((HAttrBGNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (AttrDestBG=GlobalLock(HAttrBGNew)) == NULL) {
 		goto allocate_error;
 	}
+	CodeWNew = malloc(NewSize * sizeof(wchar_t));
+	CodeDestW = CodeWNew;
 
 	memset(&CodeDest[0], 0x20, NewSize);
+	memsetW(&CodeDestW[0], 0x20, NewSize);
 	memset(&AttrDest[0], AttrDefault, NewSize);
 	memset(&AttrDest2[0], AttrDefault, NewSize);
 	memset(&AttrDestFG[0], AttrDefaultFG, NewSize);
@@ -202,6 +237,7 @@
 		DestPtr = 0;
 		for (i = 1 ; i <= NyCopy ; i++) {
 			memcpy(&CodeDest[DestPtr],&CodeBuff[SrcPtr],NxCopy);
+			memcpyW(&CodeDestW[DestPtr],&CodeBuffW[SrcPtr],NxCopy);
 			memcpy(&AttrDest[DestPtr],&AttrBuff[SrcPtr],NxCopy);
 			memcpy(&AttrDest2[DestPtr],&AttrBuff2[SrcPtr],NxCopy);
 			memcpy(&AttrDestFG[DestPtr],&AttrBuffFG[SrcPtr],NxCopy);
@@ -243,6 +279,7 @@
 	HAttrBuff2 = HAttr2New;
 	HAttrBuffFG = HAttrFGNew;
 	HAttrBuffBG = HAttrBGNew;
+	CodeBuffW = CodeWNew;
 	BufferSize = NewSize;
 	NumOfLinesInBuff = Ny;
 	BuffStartAbs = 0;
@@ -265,6 +302,7 @@
 		AttrBuffFG = (PCHAR)GlobalLock(HAttrBuffFG);
 		AttrBuffBG = (PCHAR)GlobalLock(HAttrBuffBG);
 		CodeLine = CodeBuff;
+		CodeLineW = CodeBuffW;
 		AttrLine = AttrBuff;
 		AttrLine2 = AttrBuff2;
 		AttrLineFG = AttrBuffFG;
@@ -288,6 +326,7 @@
 	if (AttrDestFG) GlobalUnlock(HAttrFGNew);
 	if (AttrDestBG) GlobalUnlock(HAttrBGNew);
 	if (HCodeNew)   GlobalFree(HCodeNew);
+	if (CodeWNew)   free(CodeWNew);
 	if (HAttrNew)   GlobalFree(HAttrNew);
 	if (HAttr2New)  GlobalFree(HAttr2New);
 	if (HAttrFGNew) GlobalFree(HAttrFGNew);
@@ -343,6 +382,7 @@
 	AttrLine2 = &AttrBuff2[LinePtr];
 	AttrLineFG = &AttrBuffFG[LinePtr];
 	AttrLineBG = &AttrBuffBG[LinePtr];
+	CodeLineW = &CodeBuffW[LinePtr];
 }
 
 void LockBuffer()
@@ -393,6 +433,10 @@
 		GlobalFree(HCodeBuff);
 		HCodeBuff = NULL;
 	}
+	if (CodeBuffW != NULL) {
+		free(CodeBuffW);
+		CodeBuffW = NULL;
+	}
 	if (HAttrBuff!=NULL) {
 		GlobalFree(HAttrBuff);
 		HAttrBuff = NULL;
@@ -499,11 +543,13 @@
 		SrcPtr = GetLinePtr(PageStart+NumOfLines-1);
 		for (i=NumOfLines-1; i>=Bottom+1; i--) {
 			memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
+			memcpyW(&(CodeBuffW[DestPtr]),&(CodeBuffW[SrcPtr]),NumOfColumns);
 			memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
 			memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
 			memcpy(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
 			memcpy(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
 			memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
+			memsetW(&(CodeBuffW[SrcPtr]),0x20,NumOfColumns);
 			memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
 			memset(&(AttrBuff2[SrcPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
 			memset(&(AttrBuffFG[SrcPtr]),CurCharAttr.Fore,NumOfColumns);
@@ -515,6 +561,7 @@
 	}
 	for (i = 1 ; i <= n ; i++) {
 		memset(&CodeBuff[DestPtr],0x20,NumOfColumns);
+		memsetW(&CodeBuffW[DestPtr],0x20,NumOfColumns);
 		memset(&AttrBuff[DestPtr],AttrDefault,NumOfColumns);
 		memset(&AttrBuff2[DestPtr],CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
 		memset(&AttrBuffFG[DestPtr],CurCharAttr.Fore,NumOfColumns);
@@ -561,6 +608,7 @@
 	AttrLine2 = &AttrBuff2[LinePtr];
 	AttrLineFG = &AttrBuffFG[LinePtr];
 	AttrLineBG = &AttrBuffBG[LinePtr];
+	CodeLineW = &CodeBuffW[LinePtr];
 }
 
 void PrevLine()
@@ -571,6 +619,7 @@
 	AttrLine2 = &AttrBuff2[LinePtr];
 	AttrLineFG = &AttrBuffFG[LinePtr];
 	AttrLineBG = &AttrBuffBG[LinePtr];
+	CodeLineW = &CodeBuffW[LinePtr];
 }
 
 void EraseKanji(int LR)
@@ -607,17 +656,21 @@
 		pos = ptr + CursorLeftM-1;
 		if (CursorLeftM>0 && (AttrBuff[pos] & AttrKanji)) {
 			CodeBuff[pos] = 0x20;
+			CodeBuffW[pos] = 0x20;
 			AttrBuff[pos] &= ~AttrKanji;
 			pos++;
 			CodeBuff[pos] = 0x20;
+			CodeBuffW[pos] = 0x20;
 			AttrBuff[pos] &= ~AttrKanji;
 		}
 		pos = ptr + CursorRightM;
 		if (CursorRightM < NumOfColumns-1 && (AttrBuff[pos] & AttrKanji)) {
 			CodeBuff[pos] = 0x20;
+			CodeBuffW[pos] = 0x20;
 			AttrBuff[pos] &= ~AttrKanji;
 			pos++;
 			CodeBuff[pos] = 0x20;
+			CodeBuffW[pos] = 0x20;
 			AttrBuff[pos] &= ~AttrKanji;
 		}
 		ptr = NextLinePtr(ptr);
@@ -641,6 +694,7 @@
 
 	if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) {
 		CodeLine[CursorRightM+1] = 0x20;
+		CodeLineW[CursorRightM+1] = 0x20;
 		AttrLine[CursorRightM+1] &= ~AttrKanji;
 		extr = 1;
 	}
@@ -652,6 +706,7 @@
 
 	if (MoveLen > 0) {
 		memmove(&(CodeLine[CursorX+Count]), &(CodeLine[CursorX]), MoveLen);
+		memmoveW(&(CodeLineW[CursorX+Count]), &(CodeLineW[CursorX]), MoveLen);
 		memmove(&(AttrLine[CursorX+Count]), &(AttrLine[CursorX]), MoveLen);
 		memmove(&(AttrLine2[CursorX+Count]), &(AttrLine2[CursorX]), MoveLen);
 		memmove(&(AttrLineFG[CursorX+Count]), &(AttrLineFG[CursorX]), MoveLen);
@@ -658,6 +713,7 @@
 		memmove(&(AttrLineBG[CursorX+Count]), &(AttrLineBG[CursorX]), MoveLen);
 	}
 	memset(&(CodeLine[CursorX]), 0x20, Count);
+	memsetW(&(CodeLineW[CursorX]), 0x20, Count);
 	memset(&(AttrLine[CursorX]), AttrDefault, Count);
 	memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
 	memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
@@ -666,6 +722,7 @@
 	if ((AttrLine[CursorRightM] & AttrKanji) != 0) {
 		/* then delete it */
 		CodeLine[CursorRightM] = 0x20;
+		CodeLineW[CursorRightM] = 0x20;
 		AttrLine[CursorRightM] &= ~AttrKanji;
 	}
 	BuffUpdateRect(CursorX, CursorY, CursorRightM+extr, CursorY);
@@ -690,6 +747,7 @@
 	}
 	for (i = CursorY ; i <= YEnd ; i++) {
 		memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset);
+		memsetW(&(CodeBuffW[TmpPtr+offset]),0x20,NumOfColumns-offset);
 		memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset);
 		memset(&(AttrBuff2[TmpPtr+offset]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset);
 		memset(&(AttrBuffFG[TmpPtr+offset]),CurCharAttr.Fore,NumOfColumns-offset);
@@ -725,6 +783,7 @@
 			offset = CursorX+1;
 		}
 		memset(&(CodeBuff[TmpPtr]),0x20,offset);
+		memsetW(&(CodeBuffW[TmpPtr]),0x20,offset);
 		memset(&(AttrBuff[TmpPtr]),AttrDefault,offset);
 		memset(&(AttrBuff2[TmpPtr]),CurCharAttr.Attr2 & Attr2ColorMask, offset);
 		memset(&(AttrBuffFG[TmpPtr]),CurCharAttr.Fore,offset);
@@ -759,6 +818,7 @@
 	linelen = CursorRightM - CursorLeftM + 1;
 	for (i= YEnd-Count ; i>=CursorY ; i--) {
 		memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
+		memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
 		memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
 		memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
 		memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
@@ -768,6 +828,7 @@
 	}
 	for (i = 1 ; i <= Count ; i++) {
 		memset(&(CodeBuff[DestPtr]), 0x20, linelen);
+		memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
 		memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
 		memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
 		memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
@@ -797,6 +858,7 @@
 
 	NewLine(PageStart+CursorY);
 	memset(&(CodeLine[XStart]),0x20,Count);
+	memsetW(&(CodeLineW[XStart]),0x20,Count);
 	memset(&(AttrLine[XStart]),AttrDefault,Count);
 	memset(&(AttrLine2[XStart]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
 	memset(&(AttrLineFG[XStart]),CurCharAttr.Fore,Count);
@@ -838,6 +900,7 @@
 	linelen = CursorRightM - CursorLeftM + 1;
 	for (i=CursorY ; i<= YEnd-Count ; i++) {
 		memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
+		memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
 		memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
 		memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
 		memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
@@ -847,6 +910,7 @@
 	}
 	for (i = YEnd+1-Count ; i<=YEnd ; i++) {
 		memset(&(CodeBuff[DestPtr]), 0x20, linelen);
+		memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
 		memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
 		memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask,  linelen);
 		memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
@@ -878,6 +942,7 @@
 
 	if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) {
 		CodeLine[CursorRightM] = 0x20;
+		CodeLineW[CursorRightM] = 0x20;
 		AttrLine[CursorRightM] &= ~AttrKanji;
 		CodeLine[CursorRightM+1] = 0x20;
 		AttrLine[CursorRightM+1] &= ~AttrKanji;
@@ -891,6 +956,7 @@
 
 	if (MoveLen > 0) {
 		memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX+Count]), MoveLen);
+		memmoveW(&(CodeLineW[CursorX]), &(CodeLineW[CursorX+Count]), MoveLen);
 		memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX+Count]), MoveLen);
 		memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX+Count]), MoveLen);
 		memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX+Count]), MoveLen);
@@ -897,6 +963,7 @@
 		memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX+Count]), MoveLen);
 	}
 	memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count);
+	memsetW(&(CodeLineW[CursorX + MoveLen]), 0x20, Count);
 	memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count);
 	memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
 	memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count);
@@ -920,6 +987,7 @@
 		Count = NumOfColumns-CursorX;
 	}
 	memset(&(CodeLine[CursorX]),0x20,Count);
+	memsetW(&(CodeLineW[CursorX]),0x20,Count);
 	memset(&(AttrLine[CursorX]),AttrDefault,Count);
 	memset(&(AttrLine2[CursorX]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
 	memset(&(AttrLineFG[CursorX]),CurCharAttr.Fore,Count);
@@ -938,6 +1006,7 @@
 	TmpPtr = GetLinePtr(PageStart);
 	for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) {
 		memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns);
+		memsetW(&(CodeBuffW[TmpPtr]),'E',NumOfColumns);
 		memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns);
 		memset(&(AttrBuff2[TmpPtr]),AttrDefault,NumOfColumns);
 		memset(&(AttrBuffFG[TmpPtr]),AttrDefaultFG,NumOfColumns);
@@ -977,6 +1046,7 @@
 			}
 			Ptr = GetLinePtr(PageStart+Y);
 			memset(&(CodeBuff[Ptr+CursorX]),'q',C);
+			memsetW(&(CodeBuffW[Ptr+CursorX]),'q',C);
 			memset(&(AttrBuff[Ptr+CursorX]),Attr.Attr,C);
 			memset(&(AttrBuff2[Ptr+CursorX]),Attr.Attr2,C);
 			memset(&(AttrBuffFG[Ptr+CursorX]),Attr.Fore,C);
@@ -1005,6 +1075,7 @@
 			}
 			for (i=1; i<=C; i++) {
 				CodeBuff[Ptr+X] = 'x';
+				CodeBuffW[Ptr+X] = 'x';
 				AttrBuff[Ptr+X] = Attr.Attr;
 				AttrBuff2[Ptr+X] = Attr.Attr2;
 				AttrBuffFG[Ptr+X] = Attr.Fore;
@@ -1040,6 +1111,7 @@
 		if ((XStart>0) &&
 		    ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
 			CodeBuff[Ptr+XStart-1] = 0x20;
+			CodeBuffW[Ptr+XStart-1] = 0x20;
 			AttrBuff[Ptr+XStart-1] = CurCharAttr.Attr;
 			AttrBuff2[Ptr+XStart-1] = CurCharAttr.Attr2;
 			AttrBuffFG[Ptr+XStart-1] = CurCharAttr.Fore;
@@ -1048,6 +1120,7 @@
 		if ((XStart+C<NumOfColumns) &&
 		    ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0)) {
 			CodeBuff[Ptr+XStart+C] = 0x20;
+			CodeBuffW[Ptr+XStart+C] = 0x20;
 			AttrBuff[Ptr+XStart+C] = CurCharAttr.Attr;
 			AttrBuff2[Ptr+XStart+C] = CurCharAttr.Attr2;
 			AttrBuffFG[Ptr+XStart+C] = CurCharAttr.Fore;
@@ -1054,6 +1127,7 @@
 			AttrBuffBG[Ptr+XStart+C] = CurCharAttr.Back;
 		}
 		memset(&(CodeBuff[Ptr+XStart]),0x20,C);
+		memsetW(&(CodeBuffW[Ptr+XStart]),0x20,C);
 		memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C);
 		memset(&(AttrBuff2[Ptr+XStart]),CurCharAttr.Attr2 & Attr2ColorMask, C);
 		memset(&(AttrBuffFG[Ptr+XStart]),CurCharAttr.Fore,C);
@@ -1086,13 +1160,16 @@
 		if ((XStart>0) &&
 		    ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
 			CodeBuff[Ptr+XStart-1] = 0x20;
+			CodeBuffW[Ptr+XStart-1] = 0x20;
 			AttrBuff[Ptr+XStart-1] ^= AttrKanji;
 		}
 		if ((XStart+Cols<NumOfColumns) &&
 		    ((AttrBuff[Ptr+XStart+Cols-1] & AttrKanji) != 0)) {
 			CodeBuff[Ptr+XStart+Cols] = 0x20;
+			CodeBuffW[Ptr+XStart+Cols] = 0x20;
 		}
 		memset(&(CodeBuff[Ptr+XStart]), ch, Cols);
+		memsetW(&(CodeBuffW[Ptr+XStart]), ch, Cols);
 		memset(&(AttrBuff[Ptr+XStart]), CurCharAttr.Attr, Cols);
 		memset(&(AttrBuff2[Ptr+XStart]), CurCharAttr.Attr2, Cols);
 		memset(&(AttrBuffFG[Ptr+XStart]), CurCharAttr.Fore, Cols);
@@ -1148,6 +1225,7 @@
 		DPtr = GetLinePtr(PageStart+DstY);
 		for (i=0; i<L; i++) {
 			memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
+			memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
 			memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
 			memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
 			memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
@@ -1161,6 +1239,7 @@
 		DPtr = GetLinePtr(PageStart+DstY+L-1);
 		for (i=L; i>0; i--) {
 			memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
+			memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
 			memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
 			memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
 			memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
@@ -1174,6 +1253,7 @@
 		DPtr = GetLinePtr(PageStart+DstY);
 		for (i=0; i<L; i++) {
 			memmove(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
+			memmoveW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
 			memmove(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
 			memmove(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
 			memmove(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
@@ -2005,6 +2085,194 @@
 	}
 }
 
+// Put a kanji character in the buffer at the current position
+//   b: character
+//   Attr: attributes
+//   Insert: Insert flag
+// @@
+void BuffPutUnicode(unsigned int uc, TCharAttr Attr, BOOL Insert)
+{
+	int XStart, LineEnd, MoveLen;
+	int extr = 0;
+	unsigned int w = uc;
+	int ret;
+	wchar_t wchar = (wchar_t)uc;
+	BYTE b1, b2;
+	unsigned int u32 = uc;
+	unsigned short u16_high;
+	unsigned short u16_low;
+	wchar_t wstr[2];
+	size_t wstr_len;
+
+	wstr_len = UTF32ToUTF16(u32, wstr, 2);
+	switch (wstr_len) {
+	case 0:
+	default:
+		u16_high = '?';
+		u16_low = 0;
+		break;
+	case 1:
+		u16_high = wstr[0];
+		u16_low = 0;
+		break;
+	case 2:
+		u16_high = wstr[0];
+		u16_low = wstr[1];
+		break;
+	}
+
+	if (uc < 0x80) {
+		b1 = (BYTE)uc;
+		b2 = 0;
+		ret = 1;
+	} else {
+		char mbchar[2];
+		ret = UTF32ToCP932(uc, mbchar, 2);
+		if (ret == 0) {
+			b1 = '?';
+			b2 = '?';
+			ret = 2;
+		} else if (ret == 1) {
+			b1 = mbchar[0];
+			b2 = 0;
+		} else {	// ret == 2
+			b1 = mbchar[0];
+			b2 = mbchar[1];
+			ret = 2;
+		}
+	}
+
+#if 0
+	OutputDebugPrintf("BuffPutUnicode(%06x(%04x,%04x)(%02x,%02x)\n",
+					  uc,
+					  u16_high, u16_low, b1, b2);
+#endif
+
+	if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
+		Attr.Attr |= AttrLineContinued;
+	}
+
+	if (Insert) {
+		if (CursorX > CursorRightM)
+			LineEnd = NumOfColumns - 1;
+		else
+			LineEnd = CursorRightM;
+
+		if (LineEnd < NumOfColumns - 1 && (AttrLine[LineEnd] & AttrKanji)) {
+			CodeLine[LineEnd] = 0x20;
+			CodeLineW[LineEnd] = 0x20;
+			AttrLine[LineEnd] &= ~AttrKanji;
+			CodeLine[LineEnd+1] = 0x20;
+			AttrLine[LineEnd+1] &= ~AttrKanji;
+			extr = 1;
+		}
+
+		MoveLen = LineEnd - CursorX - 1;
+		if (MoveLen > 0) {
+			memmove(&CodeLine[CursorX+2], &CodeLine[CursorX], MoveLen);
+			memmove(&CodeLineW[CursorX+2], &CodeLineW[CursorX], MoveLen * sizeof(wchar_t));
+			memmove(&AttrLine[CursorX+2], &AttrLine[CursorX], MoveLen);
+			memmove(&AttrLine2[CursorX+2], &AttrLine2[CursorX], MoveLen);
+			memmove(&AttrLineFG[CursorX+2], &AttrLineFG[CursorX], MoveLen);
+			memmove(&AttrLineBG[CursorX+2], &AttrLineBG[CursorX], MoveLen);
+		}
+
+		CodeLine[CursorX] = HIBYTE(w);
+		CodeLineW[CursorX] = u16_high;
+		AttrLine[CursorX] = Attr.Attr;
+		AttrLine2[CursorX] = Attr.Attr2;
+		AttrLineFG[CursorX] = Attr.Fore;
+		AttrLineBG[CursorX] = Attr.Back;
+		if (CursorX < LineEnd) {
+			CodeLine[CursorX+1] = LOBYTE(w);
+			CodeLineW[CursorX+1] = u16_low;
+//			CodeLineW[CursorX+1] = 0;
+			AttrLine[CursorX+1] = Attr.Attr;
+			AttrLine2[CursorX+1] = Attr.Attr2;
+			AttrLineFG[CursorX+1] = Attr.Fore;
+			AttrLineBG[CursorX+1] = Attr.Back;
+		}
+		/* begin - ishizaki */
+		markURL(CursorX);
+		markURL(CursorX+1);
+		/* end - ishizaki */
+
+		/* last char in current line is kanji first? */
+		if ((AttrLine[LineEnd] & AttrKanji) != 0) {
+			/* then delete it */
+			CodeLine[LineEnd] = 0x20;
+			CodeLineW[LineEnd] = 0x20;
+			AttrLine[LineEnd] = CurCharAttr.Attr;
+			AttrLine2[LineEnd] = CurCharAttr.Attr2;
+			AttrLineFG[LineEnd] = CurCharAttr.Fore;
+			AttrLineBG[LineEnd] = CurCharAttr.Back;
+		}
+
+		if (StrChangeCount==0) {
+			XStart = CursorX;
+		}
+		else {
+			XStart = StrChangeStart;
+		}
+		StrChangeCount = 0;
+		BuffUpdateRect(XStart, CursorY, LineEnd+extr, CursorY);
+	}
+	else {
+		CodeLine[CursorX] = b1;
+		CodeLineW[CursorX] = u16_high;
+		AttrLine[CursorX] = Attr.Attr; // | AttrKanji; /* DBCS first byte */
+		AttrLine2[CursorX] = Attr.Attr2;
+		AttrLineFG[CursorX] = Attr.Fore;
+		AttrLineBG[CursorX] = Attr.Back;
+#if 0
+		if (b2 != 0) {
+			if (CursorX < NumOfColumns-1) {
+				CodeLine[CursorX+1] = b2;
+				CodeLineW[CursorX+1] = 0;
+				AttrLine[CursorX+1] = Attr.Attr;
+				AttrLine2[CursorX+1] = Attr.Attr2;
+				AttrLineFG[CursorX+1] = Attr.Fore;
+				AttrLineBG[CursorX+1] = Attr.Back;
+			}
+		}
+#else
+		if (CursorX < NumOfColumns-1) {
+			CodeLine[CursorX+1] = b2;
+			CodeLineW[CursorX+1] = u16_low;
+			AttrLine[CursorX+1] = Attr.Attr;
+			AttrLine2[CursorX+1] = Attr.Attr2;
+			AttrLineFG[CursorX+1] = Attr.Fore;
+			AttrLineBG[CursorX+1] = Attr.Back;
+		}
+#endif
+		/* begin - ishizaki */
+//		markURL(CursorX);
+//		markURL(CursorX+1);
+		/* end - ishizaki */
+
+		if (StrChangeCount==0) {
+			StrChangeStart = CursorX;
+		}
+		StrChangeCount = StrChangeCount + (b2 == 0 ? 1 : 2);
+#if 0
+		{
+			char ba[128];
+			memcpy(ba, &CodeLine[0], _countof(ba)-1);
+			ba[127] = 0;
+			OutputDebugPrintf("A '%s'\n", ba);
+			wchar_t bb[128];
+			memcpy(bb, &CodeLineW[0], _countof(bb)-1);
+			bb[127] = 0;
+			OutputDebugPrintfW(L"W '%s'\n", bb);
+		}
+#endif
+	}
+
+#if 0
+	OutputDebugPrintf("BuffPutUnicode leave\n");
+#endif
+}
+
 BOOL CheckSelect(int x, int y)
 //  subroutine called by BuffUpdateRect
 {
@@ -2027,6 +2295,7 @@
 	}
 }
 
+// @@
 void BuffUpdateRect
   (int XStart, int YStart, int XEnd, int YEnd)
 // Display text in a rectangular region in the screen
@@ -2041,6 +2310,10 @@
 	LONG TmpPtr;
 	TCharAttr CurAttr, TempAttr;
 	BOOL CurSel, TempSel, Caret;
+	char bufA[128];
+	wchar_t bufW[128];
+	int lenW = 0;
+	int lenA = 0;
 
 	if (XStart >= WinOrgX+WinWidth) {
 		return;
@@ -2068,6 +2341,13 @@
 		YEnd = WinOrgY+WinHeight-1;
 	}
 
+#if 0
+	OutputDebugPrintf("BuffUpdateRect (%d,%d)-(%d,%d) [%d,%d]\n",
+					  XStart, YStart,
+					  XEnd, YEnd,
+					  XEnd - XStart + 1, YEnd - YStart + 1);
+#endif
+
 	TempAttr = DefCharAttr;
 	TempSel = FALSE;
 
@@ -2095,6 +2375,15 @@
 			CurAttr.Fore = AttrBuffFG[TmpPtr+i];
 			CurAttr.Back = AttrBuffBG[TmpPtr+i];
 			CurSel = CheckSelect(i,j);
+			{
+				bufA[lenA] = CodeBuff[TmpPtr + i];
+				lenA++;
+				wchar_t wc = CodeBuffW[TmpPtr + i];
+				if (wc != 0) {
+					bufW[lenW] = wc;
+					lenW++;
+				}
+			}
 			count = 1;
 			while ( (i+count <= IEnd) &&
 			        (CurAttr.Attr == (AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
@@ -2104,6 +2393,15 @@
 			        (CurSel==CheckSelect(i+count,j)) ||
 			        (i+count<NumOfColumns) &&
 			        ((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0) ) {
+				{
+					bufA[lenA] = CodeBuff[TmpPtr + i + count];
+					lenA++;
+					wchar_t wc = CodeBuffW[TmpPtr + i + count];
+					if (wc != 0) {
+						bufW[lenW] = wc;
+						lenW++;
+					}
+				}
 				count++;
 			}
 
@@ -2112,7 +2410,22 @@
 				TempAttr = CurAttr;
 				TempSel = CurSel;
 			}
-			DispStr(&CodeBuff[TmpPtr+i],count,Y, &X);
+#if 1
+			{
+				OutputDebugPrintf("(%d,%d)[%d],%d\n", i, j - PageStart, count, CurAttr.Attr);
+				bufA[lenA] = 0;
+				OutputDebugPrintf("A[%d] '%s'\n", lenA, bufA);
+				bufW[lenW] = 0;
+				OutputDebugPrintfW(L"W[%d] '%s'\n", lenW, bufW);
+			}
+#endif
+			lenA = 0;
+			lenW = 0;
+#if defined(UNICODE_DISPLAY)
+			DispStrW(&CodeBuffW[TmpPtr + i], count, Y, &X);
+#else
+			DispStr(&CodeBuff[TmpPtr + i], count, Y, &X);
+#endif
 			i = i+count;
 		}
 		while (i<=IEnd);
@@ -2122,6 +2435,9 @@
 	if (Caret) {
 		CaretOn();
 	}
+#if 0
+	OutputDebugPrintf("BuffUpdateRect leave\n");
+#endif
 }
 
 void UpdateStr()
@@ -2159,7 +2475,11 @@
 			len++;
 		}
 		DispSetupDC(TempAttr, FALSE);
+#if defined(UNICODE_DISPLAY)
+		DispStrW(&CodeLineW[StrChangeStart], len, Y, &X);
+#else
 		DispStr(&CodeLine[StrChangeStart], len, Y, &X);
+#endif
 
 		/* \x8Ec\x82\xE8\x82̕\xB6\x8E\x9A\x97񂪂\xA0\x82\xEA\x82΁A\x82ӂ‚\xA4\x82ɕ`\x89\xE6\x82\xF0\x8Ds\x82\xA4\x81B*/
 		if (len < StrChangeCount) {
@@ -2169,42 +2489,24 @@
 			TempAttr.Back = AttrLineBG[StrChangeStart + pos];
 
 			DispSetupDC(TempAttr, FALSE);
+#if defined(UNICODE_DISPLAY)
+			DispStrW(&CodeLineW[StrChangeStart + pos], (StrChangeCount - len), Y, &X);
+#else
 			DispStr(&CodeLine[StrChangeStart + pos], (StrChangeCount - len), Y, &X);
+#endif
 		}
 	} else {
 		DispSetupDC(TempAttr, FALSE);
+#if defined(UNICODE_DISPLAY)
+		DispStrW(&CodeLineW[StrChangeStart],StrChangeCount,Y, &X);
+#else
 		DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
+#endif
 	}
 
 	StrChangeCount = 0;
 }
 
-#if 0
-void UpdateStrUnicode(void)
-// Display not-yet-displayed string
-{
-  int X, Y;
-  TCharAttr TempAttr;
-
-  if (StrChangeCount==0) return;
-  X = StrChangeStart;
-  Y = CursorY;
-  if (! IsLineVisible(&X, &Y))
-  {
-    StrChangeCount = 0;
-    return;
-  }
-
-  TempAttr.Attr = AttrLine[StrChangeStart];
-  TempAttr.Attr2 = AttrLine2[StrChangeStart];
-  TempAttr.Fore = AttrLineFG[StrChangeStart];
-  TempAttr.Back = AttrLineBG[StrChangeStart];
-  DispSetupDC(TempAttr, FALSE);
-  DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
-  StrChangeCount = 0;
-}
-#endif
-
 void MoveCursor(int Xnew, int Ynew)
 {
 	UpdateStr();
@@ -2264,6 +2566,7 @@
 		for (i = CursorBottom-1 ; i >= CursorTop ; i--) {
 			SrcPtr = PrevLinePtr(DestPtr);
 			memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
+			memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
 			memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
 			memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
 			memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
@@ -2271,6 +2574,7 @@
 			DestPtr = SrcPtr;
 		}
 		memset(&(CodeBuff[SrcPtr]), 0x20, linelen);
+		memsetW(&(CodeBuffW[SrcPtr]), 0x20, linelen);
 		memset(&(AttrBuff[SrcPtr]), AttrDefault, linelen);
 		memset(&(AttrBuff2[SrcPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
 		memset(&(AttrBuffFG[SrcPtr]), CurCharAttr.Fore, linelen);
@@ -2335,6 +2639,7 @@
 			SrcPtr = GetLinePtr(PageStart+CursorTop+n) + (LONG)CursorLeftM;
 			for (i = CursorTop+n ; i<=CursorBottom ; i++) {
 				memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
+				memmoveW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
 				memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
 				memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
 				memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
@@ -2348,6 +2653,7 @@
 		}
 		for (i = CursorBottom+1-n ; i<=CursorBottom; i++) {
 			memset(&(CodeBuff[DestPtr]), 0x20, linelen);
+			memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
 			memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
 			memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
 			memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
@@ -2396,6 +2702,7 @@
 			SrcPtr = GetLinePtr(PageStart+CursorTop+n) + CursorLeftM;
 			for (i = CursorTop+n ; i<=CursorBottom ; i++) {
 				memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
+				memmoveW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
 				memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
 				memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
 				memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
@@ -2409,6 +2716,7 @@
 		}
 		for (i = CursorBottom+1-n ; i<=CursorBottom; i++) {
 			memset(&(CodeBuff[DestPtr]), 0x20, linelen);
+			memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
 			memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
 			memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
 			memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
@@ -2448,6 +2756,7 @@
 		SrcPtr = GetLinePtr(PageStart+CursorBottom-n) + CursorLeftM;
 		for (i=CursorBottom-n ; i>=CursorTop ; i--) {
 			memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
+			memmoveW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
 			memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
 			memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
 			memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
@@ -2461,6 +2770,7 @@
 	}
 	for (i = CursorTop+n-1; i>=CursorTop; i--) {
 		memset(&(CodeBuff[DestPtr]), 0x20, linelen);
+		memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
 		memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
 		memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
 		memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
@@ -3476,6 +3786,7 @@
 
 	NewLine(0);
 	memset(&CodeBuff[0],0x20,BufferSize);
+	memsetW(&CodeBuffW[0],0x20,BufferSize);
 	memset(&AttrBuff[0],AttrDefault,BufferSize);
 	memset(&AttrBuff2[0],CurCharAttr.Attr2 & Attr2ColorMask, BufferSize);
 	memset(&AttrBuffFG[0],CurCharAttr.Fore,BufferSize);
@@ -3700,6 +4011,7 @@
 void BuffSaveScreen()
 {
 	PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG;
+	wchar_t *CodeDestW;
 	LONG ScrSize;
 	LONG SrcPtr, DestPtr;
 	int i;
@@ -3706,12 +4018,13 @@
 
 	if (SaveBuff == NULL) {
 		ScrSize = NumOfColumns * NumOfLines;
-		if ((SaveBuff=GlobalAlloc(GMEM_MOVEABLE, ScrSize * 5)) != NULL) {
+		if ((SaveBuff=GlobalAlloc(GMEM_MOVEABLE, ScrSize * (5+2))) != NULL) {
 			if ((CodeDest=GlobalLock(SaveBuff)) != NULL) {
 				AttrDest = CodeDest + ScrSize;
 				AttrDest2 = AttrDest + ScrSize;
 				AttrDestFG = AttrDest2 + ScrSize;
 				AttrDestBG = AttrDestFG + ScrSize;
+				CodeDestW = (wchar_t *)(AttrDestBG + ScrSize);
 
 				SaveBuffX = NumOfColumns;
 				SaveBuffY = NumOfLines;
@@ -3721,6 +4034,7 @@
 
 				for (i=0; i<NumOfLines; i++) {
 					memcpy(&CodeDest[DestPtr], &CodeBuff[SrcPtr], NumOfColumns);
+					memcpyW(&CodeDestW[DestPtr], &CodeBuffW[SrcPtr], NumOfColumns);
 					memcpy(&AttrDest[DestPtr], &AttrBuff[SrcPtr], NumOfColumns);
 					memcpy(&AttrDest2[DestPtr], &AttrBuff2[SrcPtr], NumOfColumns);
 					memcpy(&AttrDestFG[DestPtr], &AttrBuffFG[SrcPtr], NumOfColumns);
@@ -3741,6 +4055,7 @@
 void BuffRestoreScreen()
 {
 	PCHAR CodeSrc, AttrSrc, AttrSrc2, AttrSrcFG, AttrSrcBG;
+	wchar_t *CodeSrcW;
 	LONG ScrSize;
 	LONG SrcPtr, DestPtr;
 	int i, CopyX, CopyY;
@@ -3753,6 +4068,7 @@
 			AttrSrc2 = AttrSrc + ScrSize;
 			AttrSrcFG = AttrSrc2 + ScrSize;
 			AttrSrcBG = AttrSrcFG + ScrSize;
+			CodeSrcW = (wchar_t *)(AttrSrcBG + ScrSize);
 
 			CopyX = (SaveBuffX > NumOfColumns) ? NumOfColumns : SaveBuffX;
 			CopyY = (SaveBuffY > NumOfLines) ? NumOfLines : SaveBuffY;
@@ -3762,6 +4078,7 @@
 
 			for (i=0; i<CopyY; i++) {
 				memcpy(&CodeBuff[DestPtr], &CodeSrc[SrcPtr], CopyX);
+				memcpyW(&CodeBuffW[DestPtr], &CodeSrcW[SrcPtr], CopyX);
 				memcpy(&AttrBuff[DestPtr], &AttrSrc[SrcPtr], CopyX);
 				memcpy(&AttrBuff2[DestPtr], &AttrSrc2[SrcPtr], CopyX);
 				memcpy(&AttrBuffFG[DestPtr], &AttrSrcFG[SrcPtr], CopyX);
@@ -3768,6 +4085,7 @@
 				memcpy(&AttrBuffBG[DestPtr], &AttrSrcBG[SrcPtr], CopyX);
 				if (AttrBuff[DestPtr+CopyX-1] & AttrKanji) {
 					CodeBuff[DestPtr+CopyX-1] = ' ';
+					CodeBuffW[DestPtr+CopyX-1] = ' ';
 					AttrBuff[DestPtr+CopyX-1] ^= AttrKanji;
 				}
 				SrcPtr += SaveBuffX;
@@ -3812,6 +4130,7 @@
 		for (j = TmpPtr + offset; j < TmpPtr + NumOfColumns - offset; j++) {
 			if (!(AttrBuff2[j] & Attr2Protect)) {
 				CodeBuff[j] = 0x20;
+				CodeBuffW[j] = 0x20;
 				AttrBuff[j] &= AttrSgrMask;
 			}
 		}
@@ -3850,6 +4169,7 @@
 		for (j = TmpPtr; j < TmpPtr + offset; j++) {
 			if (!(AttrBuff2[j] & Attr2Protect)) {
 				CodeBuff[j] = 0x20;
+				CodeBuffW[j] = 0x20;
 				AttrBuff[j] &= AttrSgrMask;
 			}
 		}
@@ -3890,6 +4210,7 @@
 		    ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0) &&
 		    ((AttrBuff2[Ptr+XStart-1] & Attr2Protect) == 0)) {
 			CodeBuff[Ptr+XStart-1] = 0x20;
+			CodeBuffW[Ptr+XStart-1] = 0x20;
 			AttrBuff[Ptr+XStart-1] &= AttrSgrMask;
 		}
 		if ((XStart+C<NumOfColumns) &&
@@ -3896,11 +4217,13 @@
 		    ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0) &&
 		    ((AttrBuff2[Ptr+XStart+C-1] & Attr2Protect) == 0)) {
 			CodeBuff[Ptr+XStart+C] = 0x20;
+			CodeBuffW[Ptr+XStart+C] = 0x20;
 			AttrBuff[Ptr+XStart+C] &= AttrSgrMask;
 		}
 		for (j=Ptr+XStart; j<Ptr+XStart+C; j++) {
 			if (!(AttrBuff2[j] & Attr2Protect)) {
 				CodeBuff[j] = 0x20;
+				CodeBuffW[j] = 0x20;
 				AttrBuff[j] &= AttrSgrMask;
 			}
 		}
@@ -3962,22 +4285,27 @@
 
 		if (AttrBuff[LPtr+CursorRightM] & AttrKanji) {
 			CodeBuff[LPtr+CursorRightM] = 0x20;
+			CodeBuffW[LPtr+CursorRightM] = 0x20;
 			AttrBuff[LPtr+CursorRightM] &= ~AttrKanji;
 			if (CursorRightM < NumOfColumns-1) {
 				CodeBuff[LPtr+CursorRightM+1] = 0x20;
+				CodeBuffW[LPtr+CursorRightM+1] = 0x20;
 			}
 		}
 
 		if (AttrBuff[Ptr+count-1] & AttrKanji) {
 			CodeBuff[Ptr+count] = 0x20;
+			CodeBuffW[Ptr+count] = 0x20;
 		}
 
 		if (CursorLeftM > 0 && AttrBuff[Ptr-1] & AttrKanji) {
 			CodeBuff[Ptr-1] = 0x20;
+			CodeBuffW[Ptr-1] = 0x20;
 			AttrBuff[Ptr-1] &= ~AttrKanji;
 		}
 
 		memmove(&(CodeBuff[Ptr]),   &(CodeBuff[Ptr+count]),   MoveLen);
+		memmoveW(&(CodeBuffW[Ptr]),   &(CodeBuffW[Ptr+count]),   MoveLen);
 		memmove(&(AttrBuff[Ptr]),   &(AttrBuff[Ptr+count]),   MoveLen);
 		memmove(&(AttrBuff2[Ptr]),  &(AttrBuff2[Ptr+count]),  MoveLen);
 		memmove(&(AttrBuffFG[Ptr]), &(AttrBuffFG[Ptr+count]), MoveLen);
@@ -3984,6 +4312,7 @@
 		memmove(&(AttrBuffBG[Ptr]), &(AttrBuffBG[Ptr+count]), MoveLen);
 
 		memset(&(CodeBuff[Ptr+MoveLen]),   0x20,             count);
+		memsetW(&(CodeBuffW[Ptr+MoveLen]),   0x20,             count);
 		memset(&(AttrBuff[Ptr+MoveLen]),   AttrDefault,      count);
 		memset(&(AttrBuff2[Ptr+MoveLen]),  CurCharAttr.Attr2 & Attr2ColorMask, count);
 		memset(&(AttrBuffFG[Ptr+MoveLen]), CurCharAttr.Fore, count);
@@ -4009,15 +4338,19 @@
 
 		if (CursorRightM < NumOfColumns-1 && AttrBuff[LPtr+CursorRightM] & AttrKanji) {
 			CodeBuff[LPtr+CursorRightM+1] = 0x20;
+			CodeBuffW[LPtr+CursorRightM+1] = 0x20;
 		}
 
 		if (CursorLeftM > 0 && AttrBuff[Ptr-1] & AttrKanji) {
 			CodeBuff[Ptr-1] = 0x20;
+			CodeBuffW[Ptr-1] = 0x20;
 			AttrBuff[Ptr-1] &= ~AttrKanji;
 			CodeBuff[Ptr] = 0x20;
+			CodeBuffW[Ptr] = 0x20;
 		}
 
 		memmove(&(CodeBuff[Ptr+count]),   &(CodeBuff[Ptr]),   MoveLen);
+		memmoveW(&(CodeBuffW[Ptr+count]),   &(CodeBuffW[Ptr]),   MoveLen);
 		memmove(&(AttrBuff[Ptr+count]),   &(AttrBuff[Ptr]),   MoveLen);
 		memmove(&(AttrBuff2[Ptr+count]),  &(AttrBuff2[Ptr]),  MoveLen);
 		memmove(&(AttrBuffFG[Ptr+count]), &(AttrBuffFG[Ptr]), MoveLen);
@@ -4024,6 +4357,7 @@
 		memmove(&(AttrBuffBG[Ptr+count]), &(AttrBuffBG[Ptr]), MoveLen);
 
 		memset(&(CodeBuff[Ptr]),   0x20,             count);
+		memsetW(&(CodeBuffW[Ptr]),   0x20,             count);
 		memset(&(AttrBuff[Ptr]),   AttrDefault,      count);
 		memset(&(AttrBuff2[Ptr]),  CurCharAttr.Attr2 & Attr2ColorMask, count);
 		memset(&(AttrBuffFG[Ptr]), CurCharAttr.Fore, count);
@@ -4031,6 +4365,7 @@
 
 		if (AttrBuff[LPtr+CursorRightM] & AttrKanji) {
 			CodeBuff[LPtr+CursorRightM] = 0x20;
+			CodeBuffW[LPtr+CursorRightM] = 0x20;
 			AttrBuff[LPtr+CursorRightM] &= ~AttrKanji;
 		}
 

Modified: branches/cmake/teraterm/teraterm/buffer.h
===================================================================
--- branches/cmake/teraterm/teraterm/buffer.h	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/teraterm/buffer.h	2019-03-10 14:33:21 UTC (rev 7472)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1994-1998 T. Teranishi
- * (C) 2005-2017 TeraTerm Project
+ * (C) 2005-2019 TeraTerm Project
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -63,9 +63,9 @@
 void BuffDumpCurrentLine(BYTE TERM);
 void BuffPutChar(BYTE b, TCharAttr Attr, BOOL Insert);
 void BuffPutKanji(WORD w, TCharAttr Attr, BOOL Insert);
+void BuffPutUnicode(unsigned int uc, TCharAttr Attr, BOOL Insert);
 void BuffUpdateRect(int XStart, int YStart, int XEnd, int YEnd);
 void UpdateStr();
-void UpdateStrUnicode(void);
 void MoveCursor(int Xnew, int Ynew);
 void MoveRight();
 void BuffSetCaretWidth();

Modified: branches/cmake/teraterm/teraterm/vtdisp.c
===================================================================
--- branches/cmake/teraterm/teraterm/vtdisp.c	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/teraterm/vtdisp.c	2019-03-10 14:33:21 UTC (rev 7472)
@@ -2717,9 +2717,37 @@
   }
 }
 
-#if 1
-// \x93\x96\x96ʂ͂\xB1\x82\xBF\x82\xE7\x82̊֐\x94\x82\xF0\x8Eg\x82\xA4\x81B(2004.11.4 yutaka)
-void DispStr(PCHAR Buff, int Count, int Y, int* X)
+static void DrawTextBGImage(HDC hdcBGBuffer, int X, int Y, int width, int height)
+{
+	RECT  rect;
+	SetRect(&rect,0,0,width,height);
+
+	//\x91\x8B\x82̈ړ\xAE\x81A\x83\x8A\x83T\x83C\x83Y\x92\x86\x82͔w\x8Ci\x82\xF0 BGBrushInSizeMove \x82œh\x82\xE8\x82‚Ԃ\xB7
+	if(BGInSizeMove)
+		FillRect(hdcBGBuffer,&rect,BGBrushInSizeMove);
+
+	BitBlt(hdcBGBuffer,0,0,width,height,hdcBG,X,Y,SRCCOPY);
+
+	if(BGReverseText == TRUE)
+	{
+		if(BGReverseTextAlpha < 255)
+		{
+			BLENDFUNCTION bf;
+			HBRUSH hbr;
+
+			hbr = CreateSolidBrush(GetBkColor(hdcBGBuffer));
+			FillRect(hdcBGWork,&rect,hbr);
+			DeleteObject(hbr);
+
+			ZeroMemory(&bf,sizeof(bf));
+			bf.BlendOp             = AC_SRC_OVER;
+			bf.SourceConstantAlpha = BGReverseTextAlpha;
+
+			BGAlphaBlend(hdcBGBuffer,0,0,width,height,hdcBGWork,0,0,width,height,bf);
+		}
+	}
+}
+
 // Display a string
 //   Buff: points the string
 //   Y: vertical position in window cordinate
@@ -2726,159 +2754,124 @@
 //  *X: horizontal position
 // Return:
 //  *X: horizontal position shifted by the width of the string
+void DispStr(PCHAR Buff, int Count, int Y, int* X)
 {
-  RECT RText;
+#ifdef ALPHABLEND_TYPE2
+	const BOOL draw_bg_enable = BGEnable;
+#else
+	const BOOL draw_bg_enable = FALSE;
+#endif
 
-  if ((ts.Language==IdRussian) &&
-      (ts.RussClient!=ts.RussFont))
-    RussConvStr(ts.RussClient,ts.RussFont,Buff,Count);
+	if ((ts.Language==IdRussian) &&
+		(ts.RussClient!=ts.RussFont))
+		RussConvStr(ts.RussClient,ts.RussFont,Buff,Count);
 
-  RText.top = Y;
-  RText.bottom = Y+FontHeight;
-  RText.left = *X;
-  RText.right = *X + Count*FontWidth;
+	if(!draw_bg_enable)
+	{
+		RECT RText;
+		RText.top = Y;
+		RText.bottom = Y+FontHeight;
+		RText.left = *X;
+		RText.right = *X + Count*FontWidth;
 
+		ExtTextOutA(VTDC,*X+ts.FontDX,Y+ts.FontDY,
+					ETO_CLIPPED | ETO_OPAQUE,
+					&RText,Buff,Count,&Dx[0]);
+	}
 #ifdef ALPHABLEND_TYPE2
-//<!--by AKASI
-  if(!BGEnable)
-  {
-    ExtTextOutA(VTDC,*X+ts.FontDX,Y+ts.FontDY,
-               ETO_CLIPPED | ETO_OPAQUE,
-               &RText,Buff,Count,&Dx[0]);
-  }else{
+	else {
+		HFONT hPrevFont;
+		RECT  rect;
+		int   eto_options;
+		const int width  = Count*FontWidth;
+		const int height = FontHeight;
+		SetRect(&rect,0,0,width,height);
 
-    int   width;
-    int   height;
-    int   eto_options = ETO_CLIPPED;
-    RECT  rect;
-    HFONT hPrevFont;
+		//hdcBGBuffer \x82̑\xAE\x90\xAB\x82\xF0\x90ݒ\xE8
+		hPrevFont = SelectObject(hdcBGBuffer,GetCurrentObject(VTDC,OBJ_FONT));
+		SetTextColor(hdcBGBuffer,GetTextColor(VTDC));
+		SetBkColor(hdcBGBuffer,GetBkColor(VTDC));
 
-    width  = Count*FontWidth;
-    height = FontHeight;
-    SetRect(&rect,0,0,width,height);
+		// \x95\xB6\x8E\x9A\x82̔w\x8Ci\x82\xF0\x95`\x89\xE6
+		DrawTextBGImage(hdcBGBuffer, *X, Y, width, height);
 
-    //hdcBGBuffer \x82̑\xAE\x90\xAB\x82\xF0\x90ݒ\xE8
-    hPrevFont = SelectObject(hdcBGBuffer,GetCurrentObject(VTDC,OBJ_FONT));
-    SetTextColor(hdcBGBuffer,GetTextColor(VTDC));
-    SetBkColor(hdcBGBuffer,GetBkColor(VTDC));
+		// \x95\xB6\x8E\x9A\x82\xF0\x95`\x89\xE6
+		eto_options = ETO_CLIPPED;
+		if(BGReverseText == TRUE && BGReverseTextAlpha < 255) {
+			eto_options |= ETO_OPAQUE;
+		}
+		ExtTextOutA(hdcBGBuffer,ts.FontDX,ts.FontDY,eto_options,&rect,Buff,Count,&Dx[0]);
 
-    //\x91\x8B\x82̈ړ\xAE\x81A\x83\x8A\x83T\x83C\x83Y\x92\x86\x82͔w\x8Ci\x82\xF0 BGBrushInSizeMove \x82œh\x82\xE8\x82‚Ԃ\xB7
-    if(BGInSizeMove)
-      FillRect(hdcBGBuffer,&rect,BGBrushInSizeMove);
+		// Window\x82ɓ\\x82\xE8\x95t\x82\xAF
+		BitBlt(VTDC,*X,Y,width,height,hdcBGBuffer,0,0,SRCCOPY);
 
-    BitBlt(hdcBGBuffer,0,0,width,height,hdcBG,*X,Y,SRCCOPY);
+		SelectObject(hdcBGBuffer,hPrevFont);
+	}
+#endif
 
-    if(BGReverseText == TRUE)
-    {
-      if(BGReverseTextAlpha < 255)
-      {
-        BLENDFUNCTION bf;
-        HBRUSH hbr;
+	*X += Count*FontWidth;
 
-        hbr = CreateSolidBrush(GetBkColor(hdcBGBuffer));
-        FillRect(hdcBGWork,&rect,hbr);
-        DeleteObject(hbr);
-
-        ZeroMemory(&bf,sizeof(bf));
-        bf.BlendOp             = AC_SRC_OVER;
-        bf.SourceConstantAlpha = BGReverseTextAlpha;
-
-        BGAlphaBlend(hdcBGBuffer,0,0,width,height,hdcBGWork,0,0,width,height,bf);
-      }else{
-        eto_options |= ETO_OPAQUE;
-      }
-    }
-
-    ExtTextOutA(hdcBGBuffer,ts.FontDX,ts.FontDY,eto_options,&rect,Buff,Count,&Dx[0]);
-    BitBlt(VTDC,*X,Y,width,height,hdcBGBuffer,0,0,SRCCOPY);
-
-    SelectObject(hdcBGBuffer,hPrevFont);
-  }
-//-->
-#else
-  ExtTextOut(VTDC,*X+ts.FontDX,Y+ts.FontDY,
-             ETO_CLIPPED | ETO_OPAQUE,
-             &RText,Buff,Count,&Dx[0]);
-#endif
-  *X = RText.right;
-
-  if ((ts.Language==IdRussian) &&
-      (ts.RussClient!=ts.RussFont))
-    RussConvStr(ts.RussFont,ts.RussClient,Buff,Count);
+	if ((ts.Language==IdRussian) && (ts.RussClient!=ts.RussFont))
+		RussConvStr(ts.RussFont,ts.RussClient,Buff,Count);
 }
 
+// DispStr() \x82\xCC wchar_t\x94\xC5
+#if defined(UNICODE)
+void DispStrW(const wchar_t *Buff, int Count, int Y, int* X)
+{
+#ifdef ALPHABLEND_TYPE2
+	const BOOL draw_bg_enable = BGEnable;
 #else
-void DispStr(PCHAR Buff, int Count, int Y, int* X)
-// Display a string
-//   Buff: points the string
-//   Y: vertical position in window cordinate
-//  *X: horizontal position
-// Return:
-//  *X: horizontal position shifted by the width of the string
-{
-	RECT RText;
-	wchar_t *wc;
-	int len, wclen;
-	CHAR ch;
-
-#if 0
-#include <crtdbg.h>
-	_CrtSetBreakAlloc(52);
-	Buff[0] = 0x82;
-	Buff[1] = 0xe4;
-	Buff[2] = 0x82;
-	Buff[3] = 0xbd;
-	Buff[4] = 0x82;
-	Buff[5] = 0xa9;
-	Count = 6;
+	const BOOL draw_bg_enable = FALSE;
 #endif
 
-	setlocale(LC_ALL, ts.Locale);	// TODO \x83R\x81[\x83h\x95ϊ\xB7\x82\xB1\x82\xB1\x82ł\xB7\x82\xE9?,\x96\xB3\x8C\x{27B0B3}\x82ꂽ\x83R\x81[\x83h
+	if(!draw_bg_enable)
+	{
+		RECT RText;
+		RText.top = Y;
+		RText.bottom = Y+FontHeight;
+		RText.left = *X;
+		RText.right = *X + Count*FontWidth;
 
-	ch = Buff[Count];
-	Buff[Count] = 0;
-	len = mbstowcs(NULL, Buff, 0);
+		ExtTextOutW(VTDC,*X+ts.FontDX,Y+ts.FontDY,
+					ETO_CLIPPED | ETO_OPAQUE,
+					&RText,Buff,Count,&Dx[0]);
+	}
+#ifdef ALPHABLEND_TYPE2
+	else {
+		HFONT hPrevFont;
+		RECT  rect;
+		int   eto_options;
+		const int width  = Count*FontWidth;
+		const int height = FontHeight;
+		SetRect(&rect,0,0,width,height);
 
-	wc = malloc(sizeof(wchar_t) * (len + 1));
-	if (wc == NULL)
-		return;
-	wclen = mbstowcs(wc, Buff, len + 1);
-	Buff[Count] = ch;
+		//hdcBGBuffer \x82̑\xAE\x90\xAB\x82\xF0\x90ݒ\xE8
+		hPrevFont = SelectObject(hdcBGBuffer,GetCurrentObject(VTDC,OBJ_FONT));
+		SetTextColor(hdcBGBuffer,GetTextColor(VTDC));
+		SetBkColor(hdcBGBuffer,GetBkColor(VTDC));
 
-	if ((ts.Language==IdRussian) &&
-		(ts.RussClient!=ts.RussFont))
-		RussConvStr(ts.RussClient,ts.RussFont,Buff,Count);
+		// \x95\xB6\x8E\x9A\x82̔w\x8Ci\x82\xF0\x95`\x89\xE6
+		DrawTextBGImage(hdcBGBuffer, *X, Y, width, height);
 
-	RText.top = Y;
-	RText.bottom = Y+FontHeight;
-	RText.left = *X;
-	RText.right = *X + Count*FontWidth; //
+		// \x95\xB6\x8E\x9A\x82\xF0\x95`\x89\xE6
+		eto_options = ETO_CLIPPED;
+		if(BGReverseText == TRUE && BGReverseTextAlpha < 255) {
+			eto_options |= ETO_OPAQUE;
+		}
+		ExtTextOutW(hdcBGBuffer,ts.FontDX,ts.FontDY,eto_options,&rect,Buff,Count,&Dx[0]);
 
-	// Unicode\x82ŏo\x97͂\xB7\x82\xE9\x81B
-#if 1
-	// UTF-8\x8A‹\xAB\x82ɂ\xA8\x82\xA2\x82āAtcsh\x82\xAAEUC\x8Fo\x97͂\xB5\x82\xBD\x8Fꍇ\x81A\x89\xE6\x96ʂɉ\xBD\x82\xE0\x95\\x8E\xA6\x82\xB3\x82\xEA\x82Ȃ\xA2\x82\xB1\x82Ƃ\xAA\x82\xA0\x82\xE9\x81B
-	// \x83}\x83E\x83X\x82Ńh\x83\x89\x83b\x83O\x82\xB5\x82\xBD\x82\xE8\x81A\x83\x8D\x83O\x83t\x83@\x83C\x83\x8B\x82֕ۑ\xB6\x82\xB5\x82Ă݂\xE9\x82ƁA\x95\xB6\x8E\x9A\x89\xBB\x82\xAF\x82\xB5\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82\xF0
-	// \x8Am\x94F\x82\xB7\x82邱\x82Ƃ\xAA\x82ł\xAB\x82\xE9\x81B(2004.8.6 yutaka)
-	ExtTextOutW(VTDC,*X+ts.FontDX,Y+ts.FontDY,
-		ETO_CLIPPED | ETO_OPAQUE,
-		&RText, wc, wclen, NULL);
-//		&RText, wc, wclen, &Dx[0]);
-#else
-	TextOutW(VTDC, *X+ts.FontDX, Y+ts.FontDY, wc, wclen);
+		// Window\x82ɓ\\x82\xE8\x95t\x82\xAF
+		BitBlt(VTDC,*X,Y,width,height,hdcBGBuffer,0,0,SRCCOPY);
 
+		SelectObject(hdcBGBuffer,hPrevFont);
+	}
 #endif
 
-	*X = RText.right;
-
-	if ((ts.Language==IdRussian) &&
-		(ts.RussClient!=ts.RussFont))
-		RussConvStr(ts.RussFont,ts.RussClient,Buff,Count);
-
-	free(wc);
+	*X += Count*FontWidth;
 }
 #endif
 
-
 void DispEraseCurToEnd(int YEnd)
 {
   RECT R;

Modified: branches/cmake/teraterm/teraterm/vtdisp.h
===================================================================
--- branches/cmake/teraterm/teraterm/vtdisp.h	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/teraterm/vtdisp.h	2019-03-10 14:33:21 UTC (rev 7472)
@@ -80,6 +80,7 @@
 void DispReleaseDC();
 void DispSetupDC(TCharAttr Attr, BOOL Reverse);
 void DispStr(PCHAR Buff, int Count, int Y, int* X);
+void DispStrW(const wchar_t *Buff, int Count, int Y, int* X);
 void DispEraseCurToEnd(int YEnd);
 void DispEraseHomeToCur(int YHome);
 void DispEraseCharsInLine(int XStart, int Count);

Modified: branches/cmake/teraterm/teraterm/vtterm.c
===================================================================
--- branches/cmake/teraterm/teraterm/vtterm.c	2019-03-10 14:32:59 UTC (rev 7471)
+++ branches/cmake/teraterm/teraterm/vtterm.c	2019-03-10 14:33:21 UTC (rev 7472)
@@ -662,7 +662,8 @@
 	else
 		CharAttrTmp.Attr |= CharAttr.Attr;
 
-	BuffPutChar(b, CharAttrTmp, InsertMode);
+	//BuffPutChar(b, CharAttrTmp, InsertMode);
+	BuffPutUnicode(b, CharAttrTmp, InsertMode);
 
 	if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) {
 		UpdateStr();
@@ -849,7 +850,7 @@
 	}
 }
 
-void PrnParseControl(BYTE b) // printer mode
+static void PrnParseControl(BYTE b) // printer mode
 {
 	switch (b) {
 	case NUL:
@@ -898,7 +899,7 @@
 	WriteToPrnFile(b, TRUE);
 }
 
-void ParseControl(BYTE b)
+static void ParseControl(BYTE b)
 {
 	if (PrinterMode) { // printer mode
 		PrnParseControl(b);
@@ -5467,8 +5468,58 @@
 }
 
 // unicode(UTF-32,wchar_t)\x82\xF0\x83o\x83b\x83t\x83@\x82֏\x91\x82\xAB\x8D\x9E\x82\xDE
+// TODO @@
+#if defined(UNICODE_DISPLAY)
+// \x93\xE0\x95\x94\x83R\x81[\x83h unicode\x94\xC5
 static void UnicodeToCP932(unsigned int code)
 {
+	unsigned short cset;
+
+	TCharAttr CharAttrTmp;
+	CharAttrTmp = CharAttr;
+	if (code <= US) {
+		// C0
+		ParseControl(code);
+#if 0
+	} else if ((0x80<=code) && (code<=0x9F)) {
+		// C1
+		ParseControl(code);
+	} else if (code < 0x20) {
+		PutChar(code);
+#endif
+#if 0
+	} else if (code <= 0xff) {
+		PutChar(code);
+#endif
+	} else {
+		// Unicode\x82\xA9\x82\xE7DEC\x93\xC1\x8Eꕶ\x8E\x9A\x82ւ̃}\x83b\x83s\x83\x93\x83O
+		if (ts.UnicodeDecSpMapping) {
+			cset = UTF32ToDecSp(code);
+			if (((cset >> 8) & ts.UnicodeDecSpMapping) != 0) {
+				code = cset & 0xff;
+				CharAttrTmp.Attr |= AttrSpecial;
+			}
+		}
+
+		BuffPutUnicode(code, CharAttrTmp, InsertMode);
+		if (CursorX == CursorRightM || CursorX >= NumOfColumns - 1) {
+			UpdateStr();
+			Wrap = AutoWrapMode;
+		}
+		else {
+			if (code >= 0x80) {
+				MoveRight();
+			}
+			MoveRight();
+		}
+	}
+}
+
+#else
+
+// \x8F]\x97\x88\x94\xC5
+static void UnicodeToCP932(unsigned int code)
+{
 	int ret;
 	char mbchar[2];
 	unsigned short cset;
@@ -5512,9 +5563,28 @@
 	}
 }
 
+#endif
+
 // UTF-8\x82Ŏ\xF3\x90M\x83f\x81[\x83^\x82\xF0\x8F\x88\x97\x9D\x82\xB7\x82\xE9
+
+static BOOL ParseFirstUTF8Sub(BYTE b)
+{
+	if (b<=US)
+		ParseControl(b);
+	else if ((b>=0x20) && (b<=0x7E))
+		PutChar(b);
+	else if ((b>=0x80) && (b<=0x9F))
+		ParseControl(b);
+	else if (b>=0xA0)
+		PutChar(b);
+	return TRUE;
+}
+
+
+// UTF-8\x82Ŏ\xF3\x90M\x83f\x81[\x83^\x82\xF0\x8F\x88\x97\x9D\x82\xB7\x82\xE9
 // returns TRUE if b is processed
 //  (actually allways returns TRUE)
+// TODO:@@
 static BOOL ParseFirstUTF8(BYTE b, int proc_combining)
 {
 	static BYTE buf[4];
@@ -5540,10 +5610,14 @@
 			}
 
 			if (count == 1) {
-				ParseASCII(buf[0]);
+				ParseFirstUTF8Sub(buf[0]);
+				//ParseASCII(buf[0]);
+
 			}
-			ParseASCII(b);
+			//ParseASCII(b);
 
+			ParseFirstUTF8Sub(b);
+			//UnicodeToCP932(b);
 			count = 0;  // reset counter
 			return TRUE;
 		}


Ttssh2-commit メーリングリストの案内