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