[Ttssh2-commit] [7837] 文字化けすることがあったので修正

scmno****@osdn***** scmno****@osdn*****
2019年 7月 9日 (火) 00:32:30 JST


Revision: 7837
          https://osdn.net/projects/ttssh2/scm/svn/commits/7837
Author:   zmatsuo
Date:     2019-07-09 00:32:29 +0900 (Tue, 09 Jul 2019)
Log Message:
-----------
文字化けすることがあったので修正

- vtwin.cpp 文字情報ポップアップの表示/消去の改善
- buffer.c 文字情報生成時にクラッシュすることがあったので修正
- asprintf()系を作成(今のところbuffer.c内)
- 文字選択表示を可能にした(クリップボードへのペーストは未実装)

Modified Paths:
--------------
    branches/unicode_buf/teraterm/teraterm/buffer.c
    branches/unicode_buf/teraterm/teraterm/buffer.h
    branches/unicode_buf/teraterm/teraterm/vtterm.c
    branches/unicode_buf/teraterm/teraterm/vtwin.cpp
    branches/unicode_buf/teraterm/teraterm/vtwin.h

-------------- next part --------------
Modified: branches/unicode_buf/teraterm/teraterm/buffer.c
===================================================================
--- branches/unicode_buf/teraterm/teraterm/buffer.c	2019-07-08 15:32:18 UTC (rev 7836)
+++ branches/unicode_buf/teraterm/teraterm/buffer.c	2019-07-08 15:32:29 UTC (rev 7837)
@@ -32,7 +32,6 @@
 #undef _UNICODE
 
 #include "teraterm.h"
-#include "tttypes.h"
 #include <string.h>
 #include <stdio.h>
 #include <windows.h>
@@ -39,7 +38,9 @@
 #include <crtdbg.h>
 #include <mbstring.h>
 #include <assert.h>
+#include <errno.h>
 
+#include "tttypes.h"
 #include "ttwinman.h"
 #include "teraprn.h"
 #include "vtdisp.h"
@@ -68,8 +69,8 @@
 	char32_t u32;
 	char32_t u32_last;
 	char WidthProperty;		// 'W' or 'H' or 'A'
-	char CombinationCharCount16;
-	char CombinationCharSize16;
+	char CombinationCharCount16;	// charactor count
+	char CombinationCharSize16;		// buffer size
 	char CombinationCharCount32;
 	char CombinationCharSize32;
 	wchar_t *pCombinationChars16;
@@ -205,7 +206,23 @@
 
 static void memcpyW(buff_char_t *dest, const buff_char_t *src, size_t count)
 {
+	size_t i;
 	memcpy(dest, src, count * sizeof(buff_char_t));
+	for (i=0; i<count; i++) {
+		buff_char_t *p = &dest[i];
+		size_t size = p->CombinationCharSize16;
+		if (size > 0) {
+			wchar_t *new_buf = malloc(sizeof(wchar_t) * size);
+			memcpy(new_buf, p->pCombinationChars16, sizeof(wchar_t) * size);
+			p->pCombinationChars16 = new_buf;
+		}
+		size = p->CombinationCharSize32;
+		if (size > 0) {
+			char32_t *new_buf = malloc(sizeof(char32_t) * size);
+			memcpy(new_buf, p->pCombinationChars32, sizeof(char32_t) * size);
+			p->pCombinationChars32 = new_buf;
+		}
+	}
 }
 
 static void memsetW(buff_char_t *dest, wchar_t ch, size_t count)
@@ -2273,30 +2290,25 @@
 
 /**
  *	\x83\x86\x83j\x83R\x81[\x83h\x83L\x83\x83\x83\x89\x83N\x83^\x82\xF01\x95\xB6\x8E\x9A\x83o\x83b\x83t\x83@\x82֓\xFC\x97͂\xB7\x82\xE9
- *	@param[in]	uc		unicode character
+ *	@param[in]	u32		unicode character(UTF-32)
  *	@param[in]	Attr	attributes
  *	@param[in]	Insert	Insert flag
  */
 #if UNICODE_INTERNAL_BUFF
-char BuffPutUnicode(unsigned int uc, TCharAttr Attr, BOOL Insert)
+char BuffPutUnicode(unsigned int u32, 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;
 	char retval = 'h';
 	BOOL half_width = TRUE;
 
-	if (uc < 0x80) {
-		b1 = (BYTE)uc;
+	if (u32 < 0x80) {
+		b1 = (BYTE)u32;
 		b2 = 0;
 		ret = 1;
 	} else {
 		char mbchar[2];
-		ret = UTF32ToCP932(uc, mbchar, 2);
+		ret = UTF32ToCP932(u32, mbchar, 2);
 		if (ret == 0) {
 			b1 = '?';
 			b2 = 0;
@@ -2313,7 +2325,7 @@
 
 #if 0
 	OutputDebugPrintf("BuffPutUnicode(%06x(%02x,%02x)\n",
-					  uc, b1, b2);
+					  u32, b1, b2);
 #endif
 
 	if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
@@ -2321,8 +2333,8 @@
 	}
 
 	if (Insert) {
-		assert(FALSE);
-#if 0
+		int XStart, LineEnd, MoveLen;
+		int extr = 0;
 		if (CursorX > CursorRightM)
 			LineEnd = NumOfColumns - 1;
 		else
@@ -2330,8 +2342,9 @@
 
 		if (LineEnd < NumOfColumns - 1 && (AttrLine[LineEnd] & AttrKanji)) {
 			CodeLine[LineEnd] = 0x20;
-			CodeLineW[LineEnd].wc = 0x20;
-			CodeLineW[LineEnd].u32 = 0x20;
+#if UNICODE_INTERNAL_BUFF
+			BuffSetChar(&CodeLineW[LineEnd], 0x20, 'H');
+#endif
 			AttrLine[LineEnd] &= ~AttrKanji;
 			CodeLine[LineEnd+1] = 0x20;
 			AttrLine[LineEnd+1] &= ~AttrKanji;
@@ -2341,7 +2354,9 @@
 		MoveLen = LineEnd - CursorX - 1;
 		if (MoveLen > 0) {
 			memmove(&CodeLine[CursorX+2], &CodeLine[CursorX], MoveLen);
-			memmove(&CodeLineW[CursorX+2], &CodeLineW[CursorX], MoveLen * sizeof(wchar_t));
+#if UNICODE_INTERNAL_BUFF
+			memmoveW(&(CodeLineW[CursorX+2]), &(CodeLineW[CursorX]), MoveLen);
+#endif
 			memmove(&AttrLine[CursorX+2], &AttrLine[CursorX], MoveLen);
 			memmove(&AttrLine2[CursorX+2], &AttrLine2[CursorX], MoveLen);
 			memmove(&AttrLineFG[CursorX+2], &AttrLineFG[CursorX], MoveLen);
@@ -2348,36 +2363,38 @@
 			memmove(&AttrLineBG[CursorX+2], &AttrLineBG[CursorX], MoveLen);
 		}
 
-		if (HIBYTE(w) == 0) {
-			int a = 0;
-		}
-		CodeLine[CursorX] = HIBYTE(w);
-		CodeLineW[CursorX].wc = u16_high;
-		CodeLineW[CursorX].u32 = u32;
+		CodeLine[CursorX] = b1;
+#if UNICODE_INTERNAL_BUFF
+		BuffSetChar(&CodeLineW[CursorX], u32, 'H');
+#endif
 		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].wc = u16_low;
-			CodeLineW[CursorX + 1].u32 = 0;
-			//			CodeLineW[CursorX+1] = 0;
+			CodeLine[CursorX+1] = 0;
+#if UNICODE_INTERNAL_BUFF
+			BuffSetChar(&CodeLineW[CursorX + 1], 0, 'H');
+#endif
 			AttrLine[CursorX+1] = Attr.Attr;
 			AttrLine2[CursorX+1] = Attr.Attr2;
 			AttrLineFG[CursorX+1] = Attr.Fore;
 			AttrLineBG[CursorX+1] = Attr.Back;
 		}
+#if 0
 		/* begin - ishizaki */
 		markURL(CursorX);
 		markURL(CursorX+1);
 		/* end - ishizaki */
+#endif
 
 		/* last char in current line is kanji first? */
 		if ((AttrLine[LineEnd] & AttrKanji) != 0) {
 			/* then delete it */
 			CodeLine[LineEnd] = 0x20;
+#if UNICODE_INTERNAL_BUFF
 			BuffSetChar(&CodeLineW[LineEnd], 0x20, 'H');
+#endif
 			AttrLine[LineEnd] = CurCharAttr.Attr;
 			AttrLine2[LineEnd] = CurCharAttr.Attr2;
 			AttrLineFG[LineEnd] = CurCharAttr.Fore;
@@ -2392,7 +2409,6 @@
 		}
 		StrChangeCount = 0;
 		BuffUpdateRect(XStart, CursorY, LineEnd+extr, CursorY);
-#endif
 	} else {
 		buff_char_t *p;
 
@@ -2419,14 +2435,14 @@
 		}
 
 		if (retval == 'V' || retval == '0') {
-			// \x91O\x82̕\xB6\x8E\x9A\x82ɂ\xAD\x82\xC1\x82‚\xAF\x82\xE9
-			// VariationSelector or
-			// CombiningCharacter or
-			// ZERO WIDTH JOINER(ZWJ)
+			// Combining
+			// 		VariationSelector or
+			// 		CombiningCharacter or
+			// 		ZERO WIDTH JOINER(ZWJ)
 
 			if (p != NULL) {
 				// \x91O\x82̕\xB6\x8E\x9A\x82ɂ\xAD\x82\xC1\x82‚\xAF\x82\xE9
-				BuffAddChar(p, uc, retval);
+				BuffAddChar(p, u32, retval);
 				AttrLine[CursorX] = Attr.Attr; // | AttrKanji; /* DBCS first byte */
 				AttrLine2[CursorX] = Attr.Attr2;
 				AttrLineFG[CursorX] = Attr.Fore;
@@ -2436,7 +2452,7 @@
 				// \x82Ƃ肠\x82\xA6\x82\xB8\x83X\x83y\x81[\x83X\x82ɂ\xAD\x82\xC1\x82‚\xAF\x82\xE9
 				p = &CodeLineW[CursorX];
 				BuffSetChar(p, ' ', 'H');
-				BuffAddChar(p, uc, retval);
+				BuffAddChar(p, u32, retval);
 				AttrLine[CursorX] = Attr.Attr;
 				AttrLine2[CursorX] = Attr.Attr2;
 				AttrLineFG[CursorX] = Attr.Fore;
@@ -2446,7 +2462,12 @@
 			// \x90V\x82\xB5\x82\xA2\x95\xB6\x8E\x9A\x92lj\xC1
 			CodeLine[CursorX] = b1;
 			BuffSetChar(&CodeLineW[CursorX], u32, retval);
-			AttrLine[CursorX] = Attr.Attr; // | AttrKanji; /* DBCS first byte */
+			if (half_width) {
+				AttrLine[CursorX] = Attr.Attr;
+			} else {
+				 /* DBCS first byte */
+				AttrLine[CursorX] = Attr.Attr | AttrKanji;
+			}
 			AttrLine2[CursorX] = Attr.Attr2;
 			AttrLineFG[CursorX] = Attr.Fore;
 			AttrLineBG[CursorX] = Attr.Back;
@@ -2507,7 +2528,7 @@
 }
 #endif
 
-BOOL CheckSelect(int x, int y)
+static BOOL CheckSelect(int x, int y)
 //  subroutine called by BuffUpdateRect
 {
 	LONG L, L1, L2;
@@ -2531,13 +2552,19 @@
 
 #if UNICODE_INTERNAL_BUFF
 /*
- *	DrawX,Y			Clint\x97̈\xE6\x95`\x89\xE6\x88ʒu(pixel)
- *	SY				\x83X\x83N\x83\x8A\x81[\x83\x93\x8F\xE3\x82̈ʒu(Charactor)
- *					PageStart + YStart \x82Ȃ\xC7
- *	IStart,IEnd		\x83X\x83N\x83\x8A\x81[\x83\x93\x8F\xE3\x82̈ʒu(Charactor)
+ *	1\x8Ds\x95`\x89\xE6
+ *
+ *	@param	DrawX,Y			Clint\x97̈\xE6\x95`\x89\xE6\x88ʒu(pixel)
+ *	@param	SY				\x83X\x83N\x83\x8A\x81[\x83\x93\x8F\xE3\x82̈ʒu(Charactor)
+ *							PageStart + YStart \x82Ȃ\xC7
+ *	@param	IStart,IEnd		\x83X\x83N\x83\x8A\x81[\x83\x93\x8F\xE3\x82̈ʒu(Charactor)
+ *							\x8Ew\x92肵\x82\xBD\x8AԂ\xF0\x95`\x89悷\x82\xE9
  */
 static void BuffDrawLineI(int DrawX, int DrawY, int SY, int IStart, int IEnd)
 {
+#if 0
+	OutputDebugPrintf("BuffDrawLineI(%d,%d, %d,%d-%d)\n", DrawX, DrawY, SY, IStart, IEnd);
+#endif
 	int X = DrawX;
 	int Y = DrawY;
 	const LONG TmpPtr = GetLinePtr(SY);
@@ -2548,11 +2575,11 @@
 	int lenW = 0;
 	int lenA = 0;
 	TCharAttr CurAttr;
-	BOOL ConbinationCharInclude = FALSE;
-
-	int count = 0;		// index;
-	while (istart + count <= IEnd) {
-		buff_char_t *b;
+	BOOL CurSelected;
+	BOOL EndFlag = FALSE;
+	int count = 0;		// \x8C\xBB\x8Dݒ\x8D\x96ڂ\xB5\x82Ă\xA2\x82镶\x8E\x9A,IStart\x82\xA9\x82\xE7
+	while (!EndFlag) {
+		const buff_char_t *b;
 		TCharAttr TempAttr;
 		BOOL DrawFlag = FALSE;
 		BOOL Conbination = FALSE;
@@ -2567,12 +2594,18 @@
 		lenA++;
 
 		b = &CodeBuffW[TmpPtr + istart + count];
-		if (b->u32 != 0) {
+		if (b->u32 == 0x1a1) {
+			int a = 0;
+		}
+		if (b->u32 == 0) {
+			// \x91S\x8Ap\x82̎\x9F\x82̕\xB6\x8E\x9A,\x8F\x88\x97\x9D\x95s\x97v
+		} else {
 			if (b->u32 < 0x10000) {
 				bufW[lenW] = b->wc2[0];
 				bufWW[lenW] = b->WidthProperty;
 				lenW++;
 			} else {
+				// UTF-16\x82ŃT\x83\x8D\x83Q\x81[\x83g\x83y\x83A
 				bufW[lenW] = b->wc2[0];
 				bufWW[lenW] = b->WidthProperty;
 				lenW++;
@@ -2580,11 +2613,12 @@
 				bufWW[lenW] = '0';
 				lenW++;
 				Conbination = TRUE;
-				DrawFlag = TRUE;
+				DrawFlag = TRUE;	// \x82\xB7\x82\xAE\x82ɕ`\x89悷\x82\xE9
 			}
 			if ((b->WidthProperty == 'W' || b->WidthProperty == 'H') &&
 				b->CombinationCharCount16 != 0)
 			{
+				// \x83R\x83\x93\x83r\x83l\x81[\x83V\x83\x87\x83\x93
 				int i;
 				for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
 					bufW[lenW+i] = b->pCombinationChars16[i];
@@ -2592,7 +2626,7 @@
 				}
 				lenW += b->CombinationCharCount16;
 				Conbination = TRUE;
-				DrawFlag = TRUE;
+				DrawFlag = TRUE;	// \x83R\x83\x93\x83r\x83l\x81[\x83V\x83\x87\x83\x93\x82\xAA\x82\xA0\x82\xE9\x8Fꍇ\x82͂\xB7\x82\xAE\x95`\x89\xE6
 			}
 		}
 
@@ -2599,39 +2633,27 @@
 		if (count == 0) {
 			// \x8Dŏ\x89\x82\xCC1\x95\xB6\x8E\x9A\x96\xDA
 			CurAttr = TempAttr;
+			CurSelected = CheckSelect(istart+count,SY);
 		}
 
-		if (DrawFlag) {
-			;
-		} else if (istart + count == IEnd) {
+		if (istart + count >= IEnd) {
 			// \x8DŌ\xE3\x82܂ŃX\x83L\x83\x83\x83\x93\x82\xB5\x82\xBD
 			DrawFlag = TRUE;
-		} else if (b->u32 != 0) {
-			// \x8E\x9F\x82̕\xB6\x8E\x9A\x82ŃA\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x82\xAA\x95ω\xBB\x82\xB7\x82\xE9?
-			if (count > 0 && TCharAttrCmp(CurAttr, TempAttr) != 0) {
+			EndFlag = TRUE;
+		} else if (DrawFlag) {
+			;
+		} else if (b->u32 == 0 || count == 0) {
+			// \x83A\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x82̃`\x83F\x83b\x83N\x95s\x97v
+		} else {
+			// \x82\xB1\x82̕\xB6\x8E\x9A\x82ŃA\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x82\xAA\x95ω\xBB\x82\xB7\x82\xE9?
+			if ((TCharAttrCmp(CurAttr, TempAttr) != 0) ||
+				(CurSelected != CheckSelect(istart+count,SY)))
+			{
 				// \x83A\x83g\x83\x8A\x83r\x83\x85\x81[\x83g\x82\xAA\x95ω\xBB\x82\xB5\x82\xBD
 				DrawFlag = TRUE;
 				lenA--;
 				lenW--;
-			} else if ((b->WidthProperty == 'W' || b->WidthProperty == 'H' )
-					   && b->CombinationCharCount16 != 0)
-			{
-				// \x83A\x83g\x83\x8A\x83r\x83\x85\x81[\x83g(unicode\x8F\xF3\x91\xD4)\x82\xAA\x95ω\xBB\x82\xB5\x82\xBD
-				DrawFlag = TRUE;
-				lenA--;
-				lenW--;
-			} else {
-				if (Conbination == FALSE) {
-					if (ConbinationCharInclude) {
-						// not \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A && \x8C\x8B\x8D\x87\x95\xB6\x8E\x9A\x97\xF1?
-						DrawFlag = TRUE;
-						lenA--;
-						lenW--;
-					}
-				}
-				else {
-					ConbinationCharInclude = TRUE;
-				}
+				count--;
 			}
 		}
 
@@ -2646,7 +2668,7 @@
 			OutputDebugPrintfW(L"W[%d] '%s'\n", lenW, bufW);
 #endif
 
-			DispSetupDC(CurAttr, FALSE);
+			DispSetupDC(CurAttr, CurSelected);
 #if UNICODE_INTERNAL_BUFF && UNICODE_DISPLAY
 			DispStrW(bufW, bufWW, lenW, Y, &X);
 #else
@@ -2656,9 +2678,8 @@
 			lenA = 0;
 			lenW = 0;
 			DrawFlag = FALSE;
-			istart += (count+1);
+			istart += (count + 1);
 			count = 0;
-			ConbinationCharInclude = FALSE;
 		} else {
 			count++;
 		}
@@ -2674,7 +2695,10 @@
 //   XEnd: x position of the lower-right corner (last character)
 //   YEnd: y position
 {
-	int i, j, count;
+	int i, j;
+#if !UNICODE_INTERNAL_BUFF
+	int count;
+#endif
 	int IStart, IEnd;
 	int X, Y;
 	LONG TmpPtr;
@@ -2793,7 +2817,9 @@
 #if !UNICODE_INTERNAL_BUFF
 	TCharAttr TempAttr;
 #endif
+#if !UNICODE_INTERNAL_BUFF
 	int pos, len;
+#endif
 
 	if (StrChangeCount==0) {
 		return;
@@ -4470,6 +4496,23 @@
 		CopyX = (SaveBuffX > NumOfColumns) ? NumOfColumns : SaveBuffX;
 		CopyY = (SaveBuffY > NumOfLines) ? NumOfLines : SaveBuffY;
 
+#if UNICODE_INTERNAL_BUFF
+		DestPtr = GetLinePtr(PageStart);
+		for (i=0; i<CopyY; i++) {
+			buff_char_t *p = &CodeBuffW[DestPtr];
+			int j;
+			for (j=0; j<CopyX; j++) {
+				if (p->CombinationCharSize16 > 0) {
+					free(p->pCombinationChars16);
+				}
+				if (p->CombinationCharSize32 > 0) {
+					free(p->pCombinationChars32);
+				}
+			}
+			DestPtr = NextLinePtr(DestPtr);
+		}
+#endif
+
 		SrcPtr = 0;
 		DestPtr = GetLinePtr(PageStart);
 
@@ -4871,9 +4914,118 @@
 	return Result;
 }
 
-/* \x83f\x83o\x83O\x97p */
-void BuffCheckMouse(int Xw, int Yw, wchar_t *buf, size_t buf_size)
+
+/**
+ *	\x97̈\xE6\x82\xF0\x8Am\x95ۂ\xB5\x82āA\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x83t\x83H\x81[\x83}\x83b\x83g\x82\xB5\x82āA\x83|\x83C\x83\x93\x83^\x95Ԃ\xB7
+ *	\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7 free() \x82\xB7\x82邱\x82\xC6
+ *	@retval	\x8Fo\x97͕\xB6\x8E\x9A\x90\x94(\x8FI\x92[\x82\xCC'\0'\x82\xF0\x8A܂\xDE)
+ *			\x83t\x83H\x81[\x83}\x83b\x83g\x95\xB6\x8E\x9A\x97񂪂\xA8\x82\xA9\x82\xB5\x82\xA2\x82Ƃ\xAB\x82\xCD"EILSEQ"
+ *			\x82\xBB\x82̑\xBC\x83G\x83\x89\x81[\x8E\x9E\x82\xCD -1
+ */
+int vasprintf(char **strp, const char *fmt, va_list ap)
 {
+	char *tmp_ptr = NULL;
+	size_t tmp_size = 128;
+	while(1) {
+		int len;
+		int err;
+		tmp_ptr = realloc(tmp_ptr, tmp_size);
+		assert(tmp_ptr != NULL);
+		if (tmp_ptr == NULL) {
+			*strp = NULL;
+			return -1;
+		}
+		len = _vsnprintf_s(tmp_ptr, tmp_size, _TRUNCATE, fmt, ap);
+		if (len != -1) {
+			len++;	// +1 for '\0' (terminator)
+			tmp_ptr = realloc(tmp_ptr, len);
+			*strp = tmp_ptr;
+			return len;
+		}
+		err = errno;
+		if (err == EILSEQ) {
+			*strp = _strdup("EILSEQ");
+			return 7;
+		}
+		tmp_size *= 2;
+	}
+}
+
+/**
+ *	\x97̈\xE6\x82\xF0\x8Am\x95ۂ\xB5\x82āA\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x83t\x83H\x81[\x83}\x83b\x83g\x82\xB5\x82āA\x83|\x83C\x83\x93\x83^\x95Ԃ\xB7
+ *	\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7 free() \x82\xB7\x82邱\x82\xC6
+ *	@retval	\x8Fo\x97͕\xB6\x8E\x9A\x90\x94(\x8FI\x92[\x82\xCCL'\0'\x82\xF0\x8A܂\xDE)
+ *			\x83t\x83H\x81[\x83}\x83b\x83g\x95\xB6\x8E\x9A\x97񂪂\xA8\x82\xA9\x82\xB5\x82\xA2\x82Ƃ\xAB\x82\xCDL"EILSEQ"
+ *			\x82\xBB\x82̑\xBC\x83G\x83\x89\x81[\x8E\x9E\x82\xCD -1
+ */
+int vaswprintf(wchar_t **strp, const wchar_t *fmt, va_list ap)
+{
+	wchar_t *tmp_ptr = NULL;
+	size_t tmp_size = 128;
+	while(1) {
+		int len;
+		int err;
+		tmp_ptr = realloc(tmp_ptr, sizeof(wchar_t) * tmp_size);
+		assert(tmp_ptr != NULL);
+		len = _vsnwprintf_s(tmp_ptr, tmp_size, _TRUNCATE, fmt, ap);
+		if (len != -1) {
+			len++;	// +1 for '\0' (terminator)
+			tmp_ptr = realloc(tmp_ptr, sizeof(wchar_t) * len);
+			*strp = tmp_ptr;
+			return len;
+		}
+		err = errno;
+		if (err == EILSEQ) {
+			*strp = _wcsdup(L"EILSEQ");
+			return 7;
+		}
+		tmp_size *= 2;
+	}
+}
+
+/**
+ *	\x97̈\xE6\x82\xF0\x8Am\x95ۂ\xB5\x82āA\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x83t\x83H\x81[\x83}\x83b\x83g\x82\xB5\x82āA\x83|\x83C\x83\x93\x83^\x95Ԃ\xB7
+ *	\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7 free() \x82\xB7\x82邱\x82\xC6
+ *	@retval	\x8Fo\x97͕\xB6\x8E\x9A\x90\x94(\x8FI\x92[\x82\xCC'\0'\x82\xF0\x8A܂\xDE)
+ *			\x83t\x83H\x81[\x83}\x83b\x83g\x95\xB6\x8E\x9A\x97񂪂\xA8\x82\xA9\x82\xB5\x82\xA2\x82Ƃ\xAB\x82\xCD"EILSEQ"
+ *			\x82\xBB\x82̑\xBC\x83G\x83\x89\x81[\x8E\x9E\x82\xCD -1
+ */
+int asprintf(char **strp, const char *fmt, ...)
+{
+	int r;
+	va_list ap;
+	va_start(ap, fmt);
+	r = vasprintf(strp, fmt, ap);
+	va_end(ap);
+	return r;
+}
+
+/**
+ *	\x97̈\xE6\x82\xF0\x8Am\x95ۂ\xB5\x82āA\x95\xB6\x8E\x9A\x97\xF1\x82\xF0\x83t\x83H\x81[\x83}\x83b\x83g\x82\xB5\x82āA\x83|\x83C\x83\x93\x83^\x95Ԃ\xB7
+ *	\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7 free() \x82\xB7\x82邱\x82\xC6
+ *	@retval	\x8Fo\x97͕\xB6\x8E\x9A\x90\x94(\x8FI\x92[\x82\xCC'\0'\x82\xF0\x8A܂\xDE)
+ *			\x83t\x83H\x81[\x83}\x83b\x83g\x95\xB6\x8E\x9A\x97񂪂\xA8\x82\xA9\x82\xB5\x82\xA2\x82Ƃ\xAB\x82\xCDL"EILSEQ"
+ *			\x82\xBB\x82̑\xBC\x83G\x83\x89\x81[\x8E\x9E\x82\xCD -1
+ */
+int aswprintf(wchar_t **strp, const wchar_t *fmt, ...)
+{
+	int r;
+	va_list ap;
+	va_start(ap, fmt);
+	r = vaswprintf(strp, fmt, ap);
+	va_end(ap);
+	return r;
+}
+
+/**
+ *	\x8Ew\x92\xE8\x88ʒu\x82̕\xB6\x8E\x9A\x8F\xEE\x95\xF1\x82𕶎\x9A\x97\xF1\x82ŕԂ\xB7
+ *	\x83f\x83o\x83O\x97p\x93r
+ *
+ *	@param	Xw, Yw	\x83E\x83B\x83\x93\x83h\x83E\x8F\xE3\x82\xCCX,Y(pixel),\x83}\x83E\x83X\x83|\x83C\x83\x93\x83^\x82̈ʒu
+ *	@reterm	\x95\xB6\x8E\x9A\x97\xF1(\x95s\x97v\x82ɂȂ\xC1\x82\xBD\x82\xE7free()\x82\xB7\x82邱\x82\xC6)
+ */
+wchar_t *BuffGetCharInfo(int Xw, int Yw)
+{
 	int X, Y;
 	int ScreenY;
 	LONG TmpPtr;
@@ -4880,10 +5032,10 @@
 	BOOL Right;
 	unsigned char c;
 	char cs[4];
-#if UNICODE_INTERNAL_BUFF
-	char32_t u32;
-	wchar_t wcs[4];
-#endif
+	wchar_t *str_ptr;
+	size_t str_len;
+	unsigned char mb[2];
+	wchar_t *mb_str;
 
 	DispConvWinToScreen(Xw, Yw, &X, &ScreenY, &Right);
 	Y = PageStart + ScreenY;
@@ -4904,63 +5056,128 @@
 	if (c < 0x20) {
 		cs[0] = '.';
 		cs[1] = 0;
-	} else if (!_ismbblead(c)) {
+		mb[0] = c;
+		mb[1] = 0;
+	} else if ((AttrBuff[TmpPtr+X] & AttrKanji) == 0) {
+		// not DBCS(?TODO)
 		cs[0] = c;
 		cs[1] = 0;
+		mb[0] = c;
+		mb[1] = 0;
 	} else {
-		cs[0] = c;
-		cs[1] = CodeBuff[TmpPtr+X+1];
-		cs[2] = 0;
+		if (X+1 < NumOfColumns) {
+			cs[0] = c;
+			cs[1] = CodeBuff[TmpPtr+X+1];
+			cs[2] = 0;
+			mb[0] = c;
+			mb[1] = CodeBuff[TmpPtr+X+1];
+		} else {
+			mb[0] = c;
+			mb[1] = 0;
+			if (_ismbblead(c)) {
+				cs[0] = '*';
+				cs[1] = 0;
+			} else {
+				cs[0] = c;
+				cs[1] = 0;
+			}
+		}
 	}
 
+	if (mb[1] == 0) {
+		aswprintf(&mb_str, L"0x%02x", mb[0]);
+	} else {
+		aswprintf(&mb_str, L"0x%02x%02x", mb[0], mb[1]);
+	}
+	str_len =
+		aswprintf(&str_ptr,
+				  L"ch(%d,%d(%d)) px(%d,%d)\n"
+				  L"attr      0x%02x\n"
+				  L"attr2     0x%02x\n"
+				  L"attrFore  0x%02x\n"
+				  L"attrBack  0x%02x\n"
+				  L"CodeLine  %s('%S')",
+				  X, ScreenY, Y,
+				  Xw, Yw,
+				  (unsigned char)AttrBuff[TmpPtr+X],
+				  (unsigned char)AttrBuff2[TmpPtr+X],
+				  (unsigned char)AttrBuffFG[TmpPtr+X],
+				  (unsigned char)AttrBuffBG[TmpPtr+X],
+				  mb_str, cs
+			);
+	free(mb_str);
+
 #if UNICODE_INTERNAL_BUFF
 	{
-		const wchar_t wc1 = CodeBuffW[TmpPtr+X].wc2[0];
-		const wchar_t wc2 = CodeBuffW[TmpPtr+X+1].wc2[1];
-		u32 = CodeBuffW[TmpPtr+X].u32;
-		if (u32 < 0x20) {
-			wcs[0] = '.';
-			wcs[1] = 0;
-			wcs[2] = 0;
-		} else if (u32 < 0x10000) {
-			wcs[0] = wc1;
-			wcs[1] = 0;
-			wcs[2] = 0;
+		const buff_char_t *b = &CodeBuffW[TmpPtr+X];
+		const char32_t u32 = b->u32;
+		wchar_t *wcs = malloc(sizeof(wchar_t) * (b->CombinationCharCount16 + 3));
+		wchar_t *codes_ptr;
+		wchar_t *str2_ptr;
+		size_t str2_len;
+		int i;
+
+		if (b->CombinationCharCount16 == 0) {
+			// \x83R\x83\x93\x83r\x83l\x81[\x83V\x83\x87\x83\x93\x82Ȃ\xB5
+			if (u32 < 0x20) {
+				wcs[0] = '.';
+				wcs[1] = 0;
+				wcs[2] = 0;
+			} else if (u32 < 0x10000) {
+				wcs[0] = b->wc2[0];
+				wcs[1] = 0;
+				wcs[2] = 0;
+			} else {
+				// \x83T\x83\x8D\x83Q\x81[\x83g\x83y\x83A
+				wcs[0] = b->wc2[0];
+				wcs[1] = b->wc2[1];
+				wcs[2] = 0;
+			}
 		} else {
-			// \x83T\x83\x8D\x83Q\x81[\x83g\x83y\x83A
-			wcs[0] = wc1;
-			wcs[1] = wc2;
-			wcs[2] = 0;
+			int n = 0;
+			wcs[n++] = b->wc2[0];
+			if (b->wc2[1] != 0) {
+				wcs[n++] = b->wc2[1];
+			}
+			for (i=0; i<b->CombinationCharCount16; i++) {
+				wcs[n++] = b->pCombinationChars16[i];
+			}
+			wcs[n] = L'\0';
 		}
+
+		{
+			size_t codes_len = 10 * (b->CombinationCharCount16 + 1);
+			codes_ptr = malloc(sizeof(wchar_t) * codes_len);
+			_snwprintf_s(codes_ptr, codes_len, _TRUNCATE, L"U+%06x", b->u32);
+			for (i=0; i<b->CombinationCharCount32; i++) {
+				wchar_t *code_str;
+				aswprintf(&code_str, L"U+%06x", b->pCombinationChars16[i]);
+				wcscat_s(codes_ptr, codes_len, L"\n");
+				wcscat_s(codes_ptr, codes_len, code_str);
+				free(code_str);
+			}
+		}
+
+		str2_len = aswprintf(&str2_ptr,
+					  L"\n"
+					  L"%s\n"
+					  L"'%s'\n"
+					  L"width %c",
+					  codes_ptr,
+					  wcs,
+					  b->WidthProperty
+				);
+		free(codes_ptr);
+		free(wcs);
+
+		str_len = str_len + str2_len - 1;	// -1 = remove one '\0'
+		str_ptr = realloc(str_ptr, sizeof(wchar_t) * str_len);
+		wcscat_s(str_ptr, str_len, str2_ptr);
+		free(str2_ptr);
 	}
 #endif
 
-	swprintf_s(buf, buf_size,
-			   L"ch(%d,%d(%d)) px(%d,%d)\n"
-			   L"attr      0x%02x\n"
-			   L"attr2     0x%02x\n"
-			   L"attrFore  0x%02x\n"
-			   L"attrBack  0x%02x\n"
-			   L"CodeLine  0x%02x('%S')"
-#if UNICODE_INTERNAL_BUFF
-			   L"\n"
-			   L"CodeLineW 0+%06x('%s')"
-#endif
-			   ,
-			   X, ScreenY, Y,
-			   Xw, Yw,
-			   AttrBuff[TmpPtr+X],
-			   AttrBuff2[TmpPtr+X],
-			   AttrBuffFG[TmpPtr+X],
-			   AttrBuffBG[TmpPtr+X],
-			   c, cs
-#if UNICODE_INTERNAL_BUFF
-			   , u32, wcs
-#endif
-		);
-#if 0
-	OutputDebugPrintfW(buf);
-#endif
+	UnlockBuffer();
 
-	UnlockBuffer();
+	return str_ptr;
 }

Modified: branches/unicode_buf/teraterm/teraterm/buffer.h
===================================================================
--- branches/unicode_buf/teraterm/teraterm/buffer.h	2019-07-08 15:32:18 UTC (rev 7836)
+++ branches/unicode_buf/teraterm/teraterm/buffer.h	2019-07-08 15:32:29 UTC (rev 7837)
@@ -109,7 +109,7 @@
 int BuffGetCurrentLineData(char *buf, int bufsize);
 int BuffGetAnyLineData(int offset_y, char *buf, int bufsize);
 BOOL BuffCheckMouseOnURL(int Xw, int Yw);
-void BuffCheckMouse(int Xw, int Yw, wchar_t *buf, size_t buf_size);
+wchar_t *BuffGetCharInfo(int Xw, int Yw);
 
 extern int StatusLine;
 extern int CursorTop, CursorBottom, CursorLeftM, CursorRightM;

Modified: branches/unicode_buf/teraterm/teraterm/vtterm.c
===================================================================
--- branches/unicode_buf/teraterm/teraterm/vtterm.c	2019-07-08 15:32:18 UTC (rev 7836)
+++ branches/unicode_buf/teraterm/teraterm/vtterm.c	2019-07-08 15:32:29 UTC (rev 7837)
@@ -554,7 +554,7 @@
 	}
 }
 
-void CarriageReturn(BOOL logFlag)
+static void CarriageReturn(BOOL logFlag)
 {
 	if (!ts.EnableContinuedLineCopy || logFlag)
 		if (cv.HLogBuf!=0) Log1Byte(CR);
@@ -567,7 +567,7 @@
 	Fallbacked = FALSE;
 }
 
-void LineFeed(BYTE b, BOOL logFlag)
+static void LineFeed(BYTE b, BOOL logFlag)
 {
 	/* for auto print mode */
 	if ((AutoPrintMode) &&
@@ -604,7 +604,7 @@
 	if (cv.HLogBuf!=0) Log1Byte(HT);
 }
 
-void PutChar(BYTE b)
+static void PutChar(BYTE b)
 {
 	BOOL SpecialNew;
 	TCharAttr CharAttrTmp;

Modified: branches/unicode_buf/teraterm/teraterm/vtwin.cpp
===================================================================
--- branches/unicode_buf/teraterm/teraterm/vtwin.cpp	2019-07-08 15:32:18 UTC (rev 7836)
+++ branches/unicode_buf/teraterm/teraterm/vtwin.cpp	2019-07-08 15:32:29 UTC (rev 7837)
@@ -148,10 +148,6 @@
 #define WM_IME_COMPOSITION              0x010F
 #endif
 
-#if UNICODE_DEBUG
-static TipWin *TipWinCodeDebug;
-#endif
-
 /////////////////////////////////////////////////////////////////////////////
 // CVTWindow
 
@@ -665,6 +661,9 @@
 	ScrollLock = FALSE;  // \x8F\x89\x8A\xFA\x92l\x82͖\xB3\x8C\xF8 (2006.11.14 yutaka)
 	Alpha = 255;
 	IgnoreSizeMessage = FALSE;
+#if UNICODE_DEBUG
+	TipWinCodeDebug = NULL;
+#endif
 
 	/* Initialize scroll buffer */
 	InitBuffer();
@@ -2242,6 +2241,14 @@
 	BYTE KeyState[256];
 	MSG M;
 
+#if UNICODE_DEBUG
+	if (nChar == VK_CONTROL && GetAsyncKeyState(VK_RCONTROL) != 0 && (nFlags & 0x4000) == 0){
+		POINT pos;
+		GetCursorPos(&pos);
+		ScreenToClient(m_hWnd, &pos);
+		CodePopup(pos.x, pos.y);
+	}
+#endif
 	switch (KeyDown(HVTWin,nChar,nRepCnt,nFlags & 0x1ff)) {
 	case KEYDOWN_OTHER:
 		break;
@@ -2275,9 +2282,11 @@
 {
 	KeyUp(nChar);
 #if UNICODE_DEBUG
-	if (TipWinCodeDebug != NULL) {
-		TipWinDestroy(TipWinCodeDebug);
-		TipWinCodeDebug = NULL;
+	if (nChar == VK_CONTROL) {
+		if (TipWinCodeDebug != NULL) {
+			TipWinDestroy(TipWinCodeDebug);
+			TipWinCodeDebug = NULL;
+		}
 	}
 #endif
 }
@@ -2387,6 +2396,21 @@
 	}
 }
 
+
+void CVTWindow::CodePopup(int client_x, int client_y)
+{
+	wchar_t *buf = BuffGetCharInfo(client_x, client_y);
+	if (TipWinCodeDebug == NULL) {
+		TipWinCodeDebug = TipWinCreateW(m_hWnd, client_x, client_y, buf);
+	} else {
+		POINT pos = { client_x, client_y };
+		ClientToScreen(m_hWnd, &pos);
+		TipWinSetPos(TipWinCodeDebug, pos.x, pos.y);
+		TipWinSetTextW(TipWinCodeDebug, buf);
+	}
+	free(buf);
+}
+
 void CVTWindow::OnMouseMove(UINT nFlags, POINTS point)
 {
 	int i;
@@ -2393,18 +2417,8 @@
 	BOOL mousereport;
 
 #if UNICODE_DEBUG
-    if (GetAsyncKeyState(VK_RCONTROL) != 0) {
-		wchar_t buf[128];
-		BuffCheckMouse(point.x, point.y, buf, _countof(buf));
-		POINT TipWinPos = { point.x, point.y };
-		ClientToScreen(m_hWnd, &TipWinPos);
-		if (TipWinCodeDebug == NULL) {
-			TipWinCodeDebug = TipWinCreate(m_hWnd, TipWinPos.x, TipWinPos.y, "test");
-			TipWinSetTextW(TipWinCodeDebug, buf);
-		} else {
-			TipWinSetPos(TipWinCodeDebug, TipWinPos.x, TipWinPos.y);
-			TipWinSetTextW(TipWinCodeDebug, buf);
-		}
+	if (TipWinCodeDebug != NULL) {
+		CodePopup(point.x, point.y);
 	}
 #endif
 

Modified: branches/unicode_buf/teraterm/teraterm/vtwin.h
===================================================================
--- branches/unicode_buf/teraterm/teraterm/vtwin.h	2019-07-08 15:32:18 UTC (rev 7836)
+++ branches/unicode_buf/teraterm/teraterm/vtwin.h	2019-07-08 15:32:29 UTC (rev 7837)
@@ -32,6 +32,8 @@
 #ifdef __cplusplus
 
 #include "tmfc.h"
+#include "unicode_test.h"
+#include "tipwin.h"
 
 class CVTWindow : public TTCFrameWnd
 {
@@ -64,6 +66,12 @@
   // DPI
   BOOL IgnoreSizeMessage;
 
+  // for debug
+#if UNICODE_DEBUG
+  TipWin *TipWinCodeDebug;
+  
+#endif
+
 public:
 	CVTWindow();
 	int Parse();
@@ -218,6 +226,9 @@
 	LRESULT OnDpiChanged(WPARAM wParam, LPARAM lParam);
 	void Disconnect(BOOL confirm);
 	virtual LRESULT Proc(UINT msg, WPARAM wp, LPARAM lp);
+
+private:
+	void CodePopup(int client_x, int client_y);
 };
 #endif
 


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