Revision: 10782 https://osdn.net/projects/ttssh2/scm/svn/commits/10782 Author: zmatsuo Date: 2023-06-27 22:36:25 +0900 (Tue, 27 Jun 2023) Log Message: ----------- charset.cppのワークを動的に確保するようにした - charset.cpp からの出力関数を設定できるようにした - charset.h の CharSetOp - PutU32() - ParseControl() Modified Paths: -------------- trunk/teraterm/teraterm/charset.cpp trunk/teraterm/teraterm/charset.h trunk/teraterm/teraterm/keyboard.c trunk/teraterm/teraterm/ttdde.c trunk/teraterm/teraterm/vtterm.c trunk/teraterm/teraterm/vtterm.h -------------- next part -------------- Modified: trunk/teraterm/teraterm/charset.cpp =================================================================== --- trunk/teraterm/teraterm/charset.cpp 2023-06-27 13:28:58 UTC (rev 10781) +++ trunk/teraterm/teraterm/charset.cpp 2023-06-27 13:36:25 UTC (rev 10782) @@ -52,35 +52,40 @@ //#define REPLACEMENT_CHARACTER 0x20 //#define REPLACEMENT_CHARACTER 0xfffd -static BOOL KanjiIn; // TRUE = MBCS\x82\xCC1byte\x96ڂ\xF0\x8E\xF3\x90M\x82\xB5\x82Ă\xA2\x82\xE9 -static BOOL EUCkanaIn, EUCsupIn; -static int EUCcount; - -/* GL for single shift 2/3 */ -static int GLtmp; -/* single shift 2/3 flag */ -static BOOL SSflag; -/* JIS -> SJIS conversion flag */ -static BOOL ConvJIS; -static WORD Kanji; -static BOOL Fallbacked; - -static BYTE DebugFlag = DEBUG_FLAG_NONE; - -typedef struct { +typedef struct CharSetDataTag { /* GL, GR code group */ int Glr[2]; /* G0, G1, G2, G3 code group */ int Gn[4]; + /* GL for single shift 2/3 */ + int GLtmp; + /* single shift 2/3 flag */ + BOOL SSflag; // char32_t replacement_char; // UTF-8 work BYTE buf[4]; int count; -} VttermKanjiWork; + BOOL Fallbacked; -static VttermKanjiWork KanjiWork; + // MBCS + BOOL KanjiIn; // TRUE = MBCS\x82\xCC1byte\x96ڂ\xF0\x8E\xF3\x90M\x82\xB5\x82Ă\xA2\x82\xE9 + WORD Kanji; + // EUC + BOOL EUCkanaIn; + BOOL EUCsupIn; + int EUCcount; + + /* JIS -> SJIS conversion flag */ + BOOL ConvJIS; + BYTE DebugFlag; + + // Operations + CharSetOp Op; + void *ClientData; +} CharSetData; + static BOOL IsC0(char32_t b) { return (b <= US); @@ -92,18 +97,9 @@ } /** - * PutU32() wrapper - * Unicode\x83x\x81[\x83X\x82ɐ\xE8\x91ւ\xA6 - */ -static void PutChar(BYTE b) -{ - PutU32(b); -} - -/** * ISO2022\x97p\x83\x8F\x81[\x83N\x82\xF0\x8F\x89\x8A\x{227B0B7}\x82\xE9 */ -static void CharSetInit2(VttermKanjiWork *w) +static void CharSetInit2(CharSetData *w) { if (ts.Language==IdJapanese) { w->Gn[0] = IdASCII; @@ -129,22 +125,40 @@ /** * \x8A\xBF\x8E\x9A\x8A֘A\x83\x8F\x81[\x83N\x82\xF0\x8F\x89\x8A\x{227B0B7}\x82\xE9 */ -void CharSetInit(void) +CharSetData *CharSetInit(const CharSetOp *op, void *client_data) { - VttermKanjiWork *w = &KanjiWork; + CharSetData *w = (CharSetData *)calloc(sizeof(*w), 1); + if (w == NULL) { + return NULL; + } + w->Op = *op; + w->ClientData = client_data; + CharSetInit2(w); + w->GLtmp = 0; + w->SSflag = FALSE; + w->DebugFlag = DEBUG_FLAG_NONE; + w->replacement_char = REPLACEMENT_CHARACTER; - SSflag = FALSE; + w->SSflag = FALSE; - KanjiIn = FALSE; - EUCkanaIn = FALSE; - EUCsupIn = FALSE; - ConvJIS = FALSE; - Fallbacked = FALSE; + w->KanjiIn = FALSE; + w->EUCkanaIn = FALSE; + w->EUCsupIn = FALSE; + w->ConvJIS = FALSE; + w->Fallbacked = FALSE; + + return w; } +void CharSetFinish(CharSetData *w) +{ + assert(w != NULL); + free(w); +} + /** * 1byte\x96ڃ`\x83F\x83b\x83N */ @@ -188,20 +202,19 @@ * ts.Language == IdJapanese \x8E\x9E * 1byte\x96ڃ`\x83F\x83b\x83N */ -static BOOL CheckKanji(BYTE b) +static BOOL CheckKanji(CharSetData *w, BYTE b) { - VttermKanjiWork *w = &KanjiWork; BOOL Check; if (ts.Language!=IdJapanese) return FALSE; - ConvJIS = FALSE; + w->ConvJIS = FALSE; if (ts.KanjiCode==IdSJIS || (ts.FallbackToCP932 && ts.KanjiCode==IdUTF8)) { if (((0x80<b) && (b<0xa0)) || ((0xdf<b) && (b<0xfd))) { - Fallbacked = TRUE; + w->Fallbacked = TRUE; return TRUE; // SJIS kanji } if ((0xa1<=b) && (b<=0xdf)) { @@ -211,7 +224,7 @@ if ((b>=0x21) && (b<=0x7e)) { Check = (w->Gn[w->Glr[0]] == IdKanji); - ConvJIS = Check; + w->ConvJIS = Check; } else if ((b>=0xA1) && (b<=0xFE)) { Check = (w->Gn[w->Glr[1]] == IdKanji); @@ -221,7 +234,7 @@ else if (ts.KanjiCode==IdJIS && ((ts.TermFlag & TF_FIXEDJIS)!=0) && (ts.JIS7Katakana==0)) { Check = FALSE; // 8-bit katakana } - ConvJIS = Check; + w->ConvJIS = Check; } else { Check = FALSE; @@ -230,97 +243,96 @@ return Check; } -static BOOL ParseFirstJP(BYTE b) +static BOOL ParseFirstJP(CharSetData *w, BYTE b) // returns TRUE if b is processed // (actually allways returns TRUE) { - VttermKanjiWork *w = &KanjiWork; - if (KanjiIn) { - if (((! ConvJIS) && (0x3F<b) && (b<0xFD)) || - (ConvJIS && ( ((0x20<b) && (b<0x7f)) || + if (w->KanjiIn) { + if (((! w->ConvJIS) && (0x3F<b) && (b<0xFD)) || + (w->ConvJIS && ( ((0x20<b) && (b<0x7f)) || ((0xa0<b) && (b<0xff)) )) ) { unsigned long u32; - Kanji = Kanji + b; - if (ConvJIS) { + w->Kanji = w->Kanji + b; + if (w->ConvJIS) { // JIS -> Shift_JIS(CP932) - Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f)); + w->Kanji = JIS2SJIS((WORD)(w->Kanji & 0x7f7f)); } - u32 = CP932ToUTF32(Kanji); - PutU32(u32); - KanjiIn = FALSE; + u32 = CP932ToUTF32(w->Kanji); + w->Op.PutU32(u32, w->ClientData); + w->KanjiIn = FALSE; return TRUE; } else if ((ts.TermFlag & TF_CTRLINKANJI)==0) { - KanjiIn = FALSE; + w->KanjiIn = FALSE; } } - if (SSflag) { - if (w->Gn[GLtmp] == IdKanji) { - Kanji = b << 8; - KanjiIn = TRUE; - SSflag = FALSE; + if (w->SSflag) { + if (w->Gn[w->GLtmp] == IdKanji) { + w->Kanji = b << 8; + w->KanjiIn = TRUE; + w->SSflag = FALSE; return TRUE; } - else if (w->Gn[GLtmp] == IdKatakana) { + else if (w->Gn[w->GLtmp] == IdKatakana) { b = b | 0x80; } - PutChar(b); - SSflag = FALSE; + w->Op.PutU32(b, w->ClientData); + w->SSflag = FALSE; return TRUE; } - if ((!EUCsupIn) && (!EUCkanaIn) && (!KanjiIn) && CheckKanji(b)) { - Kanji = b << 8; - KanjiIn = TRUE; + if ((!w->EUCsupIn) && (!w->EUCkanaIn) && (!w->KanjiIn) && CheckKanji(w, b)) { + w->Kanji = b << 8; + w->KanjiIn = TRUE; return TRUE; } if (b<=US) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0x20) { - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else if ((b>=0x21) && (b<=0x7E)) { - if (EUCsupIn) { - EUCcount--; - EUCsupIn = (EUCcount==0); + if (w->EUCsupIn) { + w->EUCcount--; + w->EUCsupIn = (w->EUCcount==0); return TRUE; } - if ((w->Gn[w->Glr[0]] == IdKatakana) || EUCkanaIn) { + if ((w->Gn[w->Glr[0]] == IdKatakana) || w->EUCkanaIn) { b = b | 0x80; - EUCkanaIn = FALSE; + w->EUCkanaIn = FALSE; { // b\x82\xCDsjis\x82̔\xBC\x8Ap\x83J\x83^\x83J\x83i unsigned long u32 = CP932ToUTF32(b); - PutU32(u32); + w->Op.PutU32(u32, w->ClientData); } return TRUE; } - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else if (b==0x7f) { return TRUE; } else if ((b>=0x80) && (b<=0x8D)) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0x8E) { // SS2 switch (ts.KanjiCode) { case IdEUC: if (ts.ISO2022Flag & ISO2022_SS2) { - EUCkanaIn = TRUE; + w->EUCkanaIn = TRUE; } break; case IdUTF8: - PutU32(REPLACEMENT_CHARACTER); + w->Op.PutU32(REPLACEMENT_CHARACTER, w->ClientData); break; default: - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } } else if (b==0x8F) { // SS3 @@ -327,32 +339,32 @@ switch (ts.KanjiCode) { case IdEUC: if (ts.ISO2022Flag & ISO2022_SS3) { - EUCcount = 2; - EUCsupIn = TRUE; + w->EUCcount = 2; + w->EUCsupIn = TRUE; } break; case IdUTF8: - PutU32(REPLACEMENT_CHARACTER); + w->Op.PutU32(REPLACEMENT_CHARACTER, w->ClientData); break; default: - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } } else if ((b>=0x90) && (b<=0x9F)) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0xA0) { - PutChar(0x20); + w->Op.PutU32(0x20, w->ClientData); } else if ((b>=0xA1) && (b<=0xFE)) { - if (EUCsupIn) { - EUCcount--; - EUCsupIn = (EUCcount==0); + if (w->EUCsupIn) { + w->EUCcount--; + w->EUCsupIn = (w->EUCcount==0); return TRUE; } if ((w->Gn[w->Glr[1]] != IdASCII) || - ((ts.KanjiCode==IdEUC) && EUCkanaIn) || + ((ts.KanjiCode==IdEUC) && w->EUCkanaIn) || (ts.KanjiCode==IdSJIS) || ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0) && @@ -359,28 +371,27 @@ ((ts.TermFlag & TF_FIXEDJIS)!=0))) { // b\x82\xCDsjis\x82̔\xBC\x8Ap\x83J\x83^\x83J\x83i unsigned long u32 = CP932ToUTF32(b); - PutU32(u32); + w->Op.PutU32(u32, w->ClientData); } else { if (w->Gn[w->Glr[1]] == IdASCII) { b = b & 0x7f; } - PutChar(b); + w->Op.PutU32(b, w->ClientData); } - EUCkanaIn = FALSE; + w->EUCkanaIn = FALSE; } else { - PutChar(b); + w->Op.PutU32(b, w->ClientData); } return TRUE; } -static BOOL ParseFirstKR(BYTE b) +static BOOL ParseFirstKR(CharSetData *w, BYTE b) // returns TRUE if b is processed // (actually allways returns TRUE) { - VttermKanjiWork *w = &KanjiWork; - if (KanjiIn) { + if (w->KanjiIn) { if (((0x41<=b) && (b<=0x5A)) || ((0x61<=b) && (b<=0x7A)) || ((0x81<=b) && (b<=0xFE))) @@ -388,151 +399,150 @@ unsigned long u32 = 0; if (ts.KanjiCode == IdKoreanCP949) { // CP949 - Kanji = Kanji + b; - u32 = MBCP_UTF32(Kanji, 949); + w->Kanji = w->Kanji + b; + u32 = MBCP_UTF32(w->Kanji, 949); } else { assert(FALSE); } - PutU32(u32); - KanjiIn = FALSE; + w->Op.PutU32(u32, w->ClientData); + w->KanjiIn = FALSE; return TRUE; } else if ((ts.TermFlag & TF_CTRLINKANJI)==0) { - KanjiIn = FALSE; + w->KanjiIn = FALSE; } } - if ((!KanjiIn) && CheckFirstByte(b, ts.Language, ts.KanjiCode)) { - Kanji = b << 8; - KanjiIn = TRUE; + if ((!w->KanjiIn) && CheckFirstByte(b, ts.Language, ts.KanjiCode)) { + w->Kanji = b << 8; + w->KanjiIn = TRUE; return TRUE; } if (b<=US) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0x20) { - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else if ((b>=0x21) && (b<=0x7E)) { // if (Gn[Glr[0]] == IdKatakana) { // b = b | 0x80; // } - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else if (b==0x7f) { return TRUE; } else if ((0x80<=b) && (b<=0x9F)) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0xA0) { - PutChar(0x20); + w->Op.PutU32(0x20, w->ClientData); } else if ((b>=0xA1) && (b<=0xFE)) { if (w->Gn[w->Glr[1]] == IdASCII) { b = b & 0x7f; } - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else { - PutChar(b); + w->Op.PutU32(b, w->ClientData); } return TRUE; } -static BOOL ParseFirstCn(BYTE b) +static BOOL ParseFirstCn(CharSetData *w, BYTE b) // returns TRUE if b is processed // (actually allways returns TRUE) { - VttermKanjiWork *w = &KanjiWork; - if (KanjiIn) { + if (w->KanjiIn) { // TODO if (((0x40<=b) && (b<=0x7e)) || ((0xa1<=b) && (b<=0xFE))) { unsigned long u32 = 0; - Kanji = Kanji + b; + w->Kanji = w->Kanji + b; if (ts.KanjiCode == IdCnGB2312) { // CP936 GB2312 - u32 = MBCP_UTF32(Kanji, 936); + u32 = MBCP_UTF32(w->Kanji, 936); } else if (ts.KanjiCode == IdCnBig5) { // CP950 Big5 - u32 = MBCP_UTF32(Kanji, 950); + u32 = MBCP_UTF32(w->Kanji, 950); } else { assert(FALSE); } - PutU32(u32); - KanjiIn = FALSE; + w->Op.PutU32(u32, w->ClientData); + w->KanjiIn = FALSE; return TRUE; } else if ((ts.TermFlag & TF_CTRLINKANJI)==0) { - KanjiIn = FALSE; + w->KanjiIn = FALSE; } } - if ((!KanjiIn) && CheckFirstByte(b, ts.Language, ts.KanjiCode)) { - Kanji = b << 8; - KanjiIn = TRUE; + if ((!w->KanjiIn) && CheckFirstByte(b, ts.Language, ts.KanjiCode)) { + w->Kanji = b << 8; + w->KanjiIn = TRUE; return TRUE; } if (b<=US) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0x20) { - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else if ((b>=0x21) && (b<=0x7E)) { // if (Gn[Glr[0]] == IdKatakana) { // b = b | 0x80; // } - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else if (b==0x7f) { return TRUE; } else if ((0x80<=b) && (b<=0x9F)) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b==0xA0) { - PutChar(0x20); + w->Op.PutU32(0x20, w->ClientData); } else if ((b>=0xA1) && (b<=0xFE)) { if (w->Gn[w->Glr[1]] == IdASCII) { b = b & 0x7f; } - PutChar(b); + w->Op.PutU32(b, w->ClientData); } else { - PutChar(b); + w->Op.PutU32(b, w->ClientData); } return TRUE; } -static void ParseASCII(BYTE b) +static void ParseASCII(CharSetData *w, BYTE b) { - if (SSflag) { - PutChar(b); - SSflag = FALSE; + if (w->SSflag) { + w->Op.PutU32(b, w->ClientData); + w->SSflag = FALSE; return; } if (b<=US) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if ((b>=0x20) && (b<=0x7E)) { - PutU32(b); + w->Op.PutU32(b, w->ClientData); } else if ((b==0x8E) || (b==0x8F)) { - PutU32(REPLACEMENT_CHARACTER); + w->Op.PutU32(REPLACEMENT_CHARACTER, w->ClientData); } else if ((b>=0x80) && (b<=0x9F)) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); } else if (b>=0xA0) { - PutU32(b); + w->Op.PutU32(b, w->ClientData); } } @@ -540,7 +550,7 @@ * REPLACEMENT_CHARACTER \x82̕\\x8E\xA6 * UTF-8 \x83f\x83R\x81[\x83h\x82\xA9\x82\xE7\x8Eg\x97p */ -static void PutReplacementChr(VttermKanjiWork *w, const BYTE *ptr, size_t len, BOOL fallback) +static void PutReplacementChr(CharSetData *w, const BYTE *ptr, size_t len, BOOL fallback) { const char32_t replacement_char = w->replacement_char; int i; @@ -549,7 +559,7 @@ assert(IsC0(c)); if (fallback) { // fallback ISO8859-1 - PutU32(c); + w->Op.PutU32(c, w->ClientData); } else { // fallback\x82\xB5\x82Ȃ\xA2 @@ -556,10 +566,10 @@ if (c < 0x80) { // \x95s\x90\xB3\x82\xC8UTF-8\x95\xB6\x8E\x9A\x97\xF1\x82̂Ȃ\xA9\x82\xC90x80\x96\xA2\x96\x9E\x82\xAA\x82\xA0\x82\xEA\x82A // 1\x95\xB6\x8E\x9A\x82\xCCUTF-8\x95\xB6\x8E\x9A\x82Ƃ\xB5\x82Ă\xBB\x82̂܂ܕ\\x8E\xA6\x82\xB7\x82\xE9 - PutU32(c); + w->Op.PutU32(c, w->ClientData); } else { - PutU32(replacement_char); + w->Op.PutU32(replacement_char, w->ClientData); } } } @@ -570,14 +580,13 @@ * * returns TRUE if b is processed */ -static BOOL ParseFirstUTF8(BYTE b) +static BOOL ParseFirstUTF8(CharSetData *w, BYTE b) { - VttermKanjiWork *w = &KanjiWork; char32_t code; - if (Fallbacked) { - BOOL r = ParseFirstJP(b); - Fallbacked = FALSE; + if (w->Fallbacked) { + BOOL r = ParseFirstJP(w, b); + w->Fallbacked = FALSE; return r; } @@ -614,12 +623,12 @@ if (IsC0(b)) { // U+0000 .. U+001f // C0\x90\xA7\x8C䕶\x8E\x9A, C0 Coontrols - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); return TRUE; } else if (b <= 0x7f) { // 0x7f\x88ȉ\xBA, \x82̂Ƃ\xAB\x81A\x82\xBB\x82̂܂o\x97\xCD - PutU32(b); + w->Op.PutU32(b, w->ClientData); return TRUE; } else if (0xc2 <= b && b <= 0xf4) { @@ -635,14 +644,14 @@ if ((ts.Language == IdJapanese) && ismbbleadSJIS(b)) { // \x93\xFA\x96{\x8C\xEA\x82̏ꍇ && Shift_JIS 1byte\x96\xDA // Shift_JIS \x82\xC9 fallback - Fallbacked = TRUE; - ConvJIS = FALSE; - Kanji = b << 8; - KanjiIn = TRUE; + w->Fallbacked = TRUE; + w->ConvJIS = FALSE; + w->Kanji = b << 8; + w->KanjiIn = TRUE; return TRUE; } // fallback ISO8859-1 - PutU32(b); + w->Op.PutU32(b, w->ClientData); return TRUE; } else { @@ -672,10 +681,10 @@ if (IsC1(code)) { // U+0080 .. u+009f // C1\x90\xA7\x8C䕶\x8E\x9A, C1 Controls - ParseControl((BYTE)code); + w->Op.ParseControl((BYTE)code, w->ClientData); } else { - PutU32(code); + w->Op.PutU32(code, w->ClientData); } w->count = 0; return TRUE; @@ -697,7 +706,7 @@ code = ((w->buf[0] & 0xf) << 12); code |= ((w->buf[1] & 0x3f) << 6); code |= ((w->buf[2] & 0x3f)); - PutU32(code); + w->Op.PutU32(code, w->ClientData); w->count = 0; return TRUE; } @@ -719,16 +728,16 @@ code |= ((w->buf[1] & 0x3f) << 12); code |= ((w->buf[2] & 0x3f) << 6); code |= (w->buf[3] & 0x3f); - PutU32(code); + w->Op.PutU32(code, w->ClientData); w->count = 0; return TRUE; } -static BOOL ParseFirstRus(BYTE b) +static BOOL ParseFirstRus(CharSetData *w, BYTE b) // returns if b is processed { if (IsC0(b)) { - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); return TRUE; } // CP1251\x82ɕϊ\xB7 @@ -735,11 +744,11 @@ BYTE c = RussConv(ts.KanjiCode, IdWindows, b); // CP1251->Unicode unsigned long u32 = MBCP_UTF32(c, 1251); - PutU32(u32); + w->Op.PutU32(u32, w->ClientData); return TRUE; } -static BOOL ParseEnglish(BYTE b) +static BOOL ParseEnglish(CharSetData *w, BYTE b) { unsigned short u16 = 0; int part = KanjiCodeToISO8859Part(ts.KanjiCode); @@ -748,15 +757,15 @@ return FALSE; } if (u16 < 0x100) { - ParseASCII((BYTE)u16); + ParseASCII(w, (BYTE)u16); } else { - PutU32(u16); + w->Op.PutU32(u16, w->ClientData); } return TRUE; } -static void PutDebugChar(BYTE b) +static void PutDebugChar(CharSetData *w, BYTE b) { int i; BOOL svInsertMode, svAutoWrapMode; @@ -773,15 +782,15 @@ char_attr.Attr = AttrDefault; TermSetAttr(&char_attr); - if (DebugFlag==DEBUG_FLAG_HEXD) { + if (w->DebugFlag==DEBUG_FLAG_HEXD) { char buff[3]; _snprintf(buff, 3, "%02X", (unsigned int) b); for (i=0; i<2; i++) - PutChar(buff[i]); - PutChar(' '); + w->Op.PutU32(buff[i], w->ClientData); + w->Op.PutU32(' ', w->ClientData); } - else if (DebugFlag==DEBUG_FLAG_NORM) { + else if (w->DebugFlag==DEBUG_FLAG_NORM) { if ((b & 0x80) == 0x80) { //UpdateStr(); @@ -791,18 +800,18 @@ } if (b<=US) { - PutChar('^'); - PutChar((char)(b+0x40)); + w->Op.PutU32('^', w->ClientData); + w->Op.PutU32((char)(b + 0x40), w->ClientData); } else if (b==DEL) { - PutChar('<'); - PutChar('D'); - PutChar('E'); - PutChar('L'); - PutChar('>'); + w->Op.PutU32('<', w->ClientData); + w->Op.PutU32('D', w->ClientData); + w->Op.PutU32('E', w->ClientData); + w->Op.PutU32('L', w->ClientData); + w->Op.PutU32('>', w->ClientData); } else - PutChar(b); + w->Op.PutU32(b, w->ClientData); } TermSetAttr(&char_attr); @@ -810,27 +819,31 @@ TermSetAutoWrapMode(svAutoWrapMode); } -void ParseFirst(BYTE b) +void ParseFirst(CharSetData *w, BYTE b) { WORD language = ts.Language; - if (DebugFlag != DEBUG_FLAG_NONE) { + if (w->DebugFlag != DEBUG_FLAG_NONE) { language = IdDebug; } switch (language) { + default: + assert(FALSE); + language = IdUtf8; + // FALLTHROUGH case IdUtf8: - ParseFirstUTF8(b); + ParseFirstUTF8(w, b); return; case IdJapanese: switch (ts.KanjiCode) { case IdUTF8: - if (ParseFirstUTF8(b)) { + if (ParseFirstUTF8(w, b)) { return; } break; default: - if (ParseFirstJP(b)) { + if (ParseFirstJP(w, b)) { return; } } @@ -839,12 +852,12 @@ case IdKorean: switch (ts.KanjiCode) { case IdUTF8: - if (ParseFirstUTF8(b)) { + if (ParseFirstUTF8(w, b)) { return; } break; default: - if (ParseFirstKR(b)) { + if (ParseFirstKR(w, b)) { return; } } @@ -851,7 +864,7 @@ break; case IdRussian: - if (ParseFirstRus(b)) { + if (ParseFirstRus(w, b)) { return; } break; @@ -859,42 +872,42 @@ case IdChinese: switch (ts.KanjiCode) { case IdUTF8: - if (ParseFirstUTF8(b)) { + if (ParseFirstUTF8(w, b)) { return; } break; default: - if (ParseFirstCn(b)) { + if (ParseFirstCn(w, b)) { return; } } break; case IdEnglish: { - if (ParseEnglish(b)) { + if (ParseEnglish(w, b)) { return; } break; } case IdDebug: { - PutDebugChar(b); + PutDebugChar(w, b); return; } } - if (SSflag) { - PutChar(b); - SSflag = FALSE; + if (w->SSflag) { + w->Op.PutU32(b, w->ClientData); + w->SSflag = FALSE; return; } if (b<=US) - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); else if ((b>=0x20) && (b<=0x7E)) - PutChar(b); + w->Op.PutU32(b, w->ClientData); else if ((b>=0x80) && (b<=0x9F)) - ParseControl(b); + w->Op.ParseControl(b, w->ClientData); else if (b>=0xA0) - PutChar(b); + w->Op.PutU32(b, w->ClientData); } /** @@ -906,9 +919,8 @@ * IdKanji 2 * IdSpecial 3 */ -void CharSet2022Designate(int gn, int cs) +void CharSet2022Designate(CharSetData *w, int gn, int cs) { - VttermKanjiWork *w = &KanjiWork; w->Gn[gn] = cs; } @@ -916,9 +928,8 @@ * \x8CĂяo\x82\xB5(Invoke) * @param shift */ -void CharSet2022Invoke(CharSet2022Shift shift) +void CharSet2022Invoke(CharSetData *w, CharSet2022Shift shift) { - VttermKanjiWork *w = &KanjiWork; switch (shift) { case CHARSET_LS0: // Locking Shift 0 (G0->GL) @@ -950,13 +961,13 @@ break; case CHARSET_SS2: // Single Shift 2 - GLtmp = 2; - SSflag = TRUE; + w->GLtmp = 2; + w->SSflag = TRUE; break; case CHARSET_SS3: // Single Shift 3 - GLtmp = 3; - SSflag = TRUE; + w->GLtmp = 3; + w->SSflag = TRUE; break; default: assert(FALSE); @@ -975,20 +986,19 @@ * @retval TRUE IdSpecial * @retval FALSE IdSpecial\x82ł͂Ȃ\xA2 */ -BOOL CharSetIsSpecial(BYTE b) +BOOL CharSetIsSpecial(CharSetData *w, BYTE b) { - VttermKanjiWork *w = &KanjiWork; BOOL SpecialNew = FALSE; if ((b>0x5F) && (b<0x80)) { - if (SSflag) - SpecialNew = (w->Gn[GLtmp]==IdSpecial); + if (w->SSflag) + SpecialNew = (w->Gn[w->GLtmp]==IdSpecial); else SpecialNew = (w->Gn[w->Glr[0]]==IdSpecial); } else if (b>0xDF) { - if (SSflag) - SpecialNew = (w->Gn[GLtmp]==IdSpecial); + if (w->SSflag) + SpecialNew = (w->Gn[w->GLtmp]==IdSpecial); else SpecialNew = (w->Gn[w->Glr[1]]==IdSpecial); } @@ -996,7 +1006,7 @@ return SpecialNew; } -static void CharSetSaveStateLow(CharSetState *state, const VttermKanjiWork *w) +static void CharSetSaveStateLow(CharSetState *state, const CharSetData *w) { int i; state->infos[0] = w->Glr[0]; @@ -1009,9 +1019,8 @@ /** * \x8F\xF3\x91Ԃ\xF0\x95ۑ\xB6\x82\xB7\x82\xE9 */ -void CharSetSaveState(CharSetState *state) +void CharSetSaveState(CharSetData *w, CharSetState *state) { - VttermKanjiWork *w = &KanjiWork; CharSetSaveStateLow(state, w); } @@ -1018,9 +1027,8 @@ /** * \x8F\xF3\x91ԂA\x82\xB7\x82\xE9 */ -void CharSetLoadState(const CharSetState *state) +void CharSetLoadState(CharSetData *w, const CharSetState *state) { - VttermKanjiWork *w = &KanjiWork; int i; w->Glr[0] = state->infos[0]; w->Glr[1] = state->infos[1]; @@ -1034,28 +1042,28 @@ * \x8E\xF3\x90M\x83f\x81[\x83^UTF-8\x8E\x9E\x82ɁAShift_JIS\x8Fo\x97͒\x86(fallback\x8F\xF3\x91\xD4)\x82𒆒f\x82\xB7\x82\xE9 * */ -void CharSetFallbackFinish(void) +void CharSetFallbackFinish(CharSetData *w) { - Fallbacked = FALSE; + w->Fallbacked = FALSE; } /** * \x83f\x83o\x83O\x8Fo\x97͂\xF0\x8E\x9F\x82̃\x82\x81[\x83h\x82ɕύX\x82\xB7\x82\xE9 */ -void CharSetSetNextDebugMode(void) +void CharSetSetNextDebugMode(CharSetData *w) { // ts.DebugModes \x82ɂ\xCD tttypes.h \x82\xCC DBGF_* \x82\xAA OR \x82œ\xFC\x82\xC1\x82Ă\xE9 do { - DebugFlag = (DebugFlag + 1) % DEBUG_FLAG_MAXD; - } while (DebugFlag != DEBUG_FLAG_NONE && !((ts.DebugModes >> (DebugFlag - 1)) & 1)); + w->DebugFlag = (w->DebugFlag + 1) % DEBUG_FLAG_MAXD; + } while (w->DebugFlag != DEBUG_FLAG_NONE && !((ts.DebugModes >> (w->DebugFlag - 1)) & 1)); } -BYTE CharSetGetDebugMode(void) +BYTE CharSetGetDebugMode(CharSetData *w) { - return DebugFlag; + return w->DebugFlag; } -void CharSetSetDebugMode(BYTE mode) +void CharSetSetDebugMode(CharSetData *w, BYTE mode) { - DebugFlag = mode; + w->DebugFlag = mode % DEBUG_FLAG_MAXD; } Modified: trunk/teraterm/teraterm/charset.h =================================================================== --- trunk/teraterm/teraterm/charset.h 2023-06-27 13:28:58 UTC (rev 10781) +++ trunk/teraterm/teraterm/charset.h 2023-06-27 13:36:25 UTC (rev 10782) @@ -26,21 +26,29 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "ttcstd.h" + #ifdef __cplusplus extern "C" { #endif +typedef struct CharSetDataTag CharSetData; + typedef struct { int infos[6]; } CharSetState; +// \x95\xB6\x8E\x9A\x82̏o\x97\xCD +typedef struct CharSetOpTag { + // \x8Fo\x97͂\xB3\x82\xEA\x82\xE9 Unicode \x95\xB6\x8E\x9A + void (*PutU32)(char32_t code, void *client_data); + // \x8Fo\x97͂\xB3\x82\xEA\x82\xE9 Control \x95\xB6\x8E\x9A + void (*ParseControl)(BYTE b, void *client_data); +} CharSetOp; + // input -void ParseFirst(BYTE b); +void ParseFirst(CharSetData *w, BYTE b); -// output buffer -void PutU32(unsigned int code); -void ParseControl(BYTE b); - // control typedef enum { CHARSET_LS0, // Locking Shift 0, SI, 0F (G0->GL) @@ -53,14 +61,16 @@ CHARSET_SS2, // Single Shift 2, SS2, 8E, ESC N, 1B 4E CHARSET_SS3, // Single Shift 3, SS3, 8F, ESC O, 1B 4F } CharSet2022Shift; -void CharSetInit(void); -void CharSet2022Designate(int gn, int cs); -void CharSet2022Invoke(CharSet2022Shift shift); -BOOL CharSetIsSpecial(BYTE b); -void CharSetSaveState(CharSetState *state); -void CharSetLoadState(const CharSetState *state); -void CharSetFallbackFinish(void); +CharSetData *CharSetInit(const CharSetOp *op, void *client_data); +void CharSetFinish(CharSetData *w); +void CharSet2022Designate(CharSetData *w, int gn, int cs); +void CharSet2022Invoke(CharSetData *w, CharSet2022Shift shift); +BOOL CharSetIsSpecial(CharSetData *w, BYTE b); +void CharSetSaveState(CharSetData *w, CharSetState *state); +void CharSetLoadState(CharSetData *w, const CharSetState *state); +void CharSetFallbackFinish(CharSetData *w); + // debug mode #define DEBUG_FLAG_NONE 0 #define DEBUG_FLAG_NORM 1 @@ -67,9 +77,9 @@ #define DEBUG_FLAG_HEXD 2 #define DEBUG_FLAG_NOUT 3 #define DEBUG_FLAG_MAXD 4 -void CharSetSetNextDebugMode(void); -//BYTE CharSetGetDebugMode(void); -void CharSetSetDebugMode(BYTE mode); +void CharSetSetNextDebugMode(CharSetData *w); +//BYTE CharSetGetDebugMode(CharSetData *w); +void CharSetSetDebugMode(CharSetData *w, BYTE mode); #ifdef __cplusplus } Modified: trunk/teraterm/teraterm/keyboard.c =================================================================== --- trunk/teraterm/teraterm/keyboard.c 2023-06-27 13:28:58 UTC (rev 10781) +++ trunk/teraterm/teraterm/keyboard.c 2023-06-27 13:36:25 UTC (rev 10782) @@ -44,7 +44,7 @@ #include "ttwinman.h" #include "ttdde.h" #include "codeconv.h" -#include "charset.h" +#include "vtterm.h" #include "keyboard.h" #include "keyboard_i.h" @@ -1374,7 +1374,7 @@ /* debug mode */ if (ts.Debug && (VKey == VK_ESCAPE) && ShiftKey()) { MessageBeep(0); - CharSetSetNextDebugMode(); + TermSetNextDebugMode(); CodeCount = 0; PeekMessage((LPMSG)&M, HWin, WM_CHAR, WM_CHAR, PM_REMOVE); return KEYDOWN_CONTROL; Modified: trunk/teraterm/teraterm/ttdde.c =================================================================== --- trunk/teraterm/teraterm/ttdde.c 2023-06-27 13:28:58 UTC (rev 10781) +++ trunk/teraterm/teraterm/ttdde.c 2023-06-27 13:36:25 UTC (rev 10782) @@ -50,7 +50,7 @@ #include "codeconv.h" #include "scp.h" #include "asprintf.h" -#include "charset.h" +#include "vtterm.h" #define ServiceName "TERATERM" #define ItemName "DATA" @@ -664,7 +664,7 @@ TelChangeEcho(); break; case CmdSetDebug: - CharSetSetDebugMode((Command[1] - '0') % DEBUG_FLAG_MAXD); + TermSetDebugMode(Command[1] - '0'); break; case CmdSetTitle: strncpy_s(ts.Title, sizeof(ts.Title),ParamFileName, _TRUNCATE); Modified: trunk/teraterm/teraterm/vtterm.c =================================================================== --- trunk/teraterm/teraterm/vtterm.c 2023-06-27 13:28:58 UTC (rev 10781) +++ trunk/teraterm/teraterm/vtterm.c 2023-06-27 13:36:25 UTC (rev 10782) @@ -203,6 +203,7 @@ int log_cr_type; } vtterm_work_t; +static CharSetData *charset_data; static vtterm_work_t vtterm_work; static void ClearParams(void) @@ -220,7 +221,7 @@ Buff->CursorY = CursorY; Buff->Attr = CharAttr; - CharSetSaveState(&Buff->CharSetState); + CharSetSaveState(charset_data, &Buff->CharSetState); Buff->AutoWrapMode = AutoWrapMode; Buff->RelativeOrgMode = RelativeOrgMode; } @@ -260,7 +261,7 @@ CharAttr = Buff->Attr; BuffSetCurCharAttr(CharAttr); - CharSetLoadState(&Buff->CharSetState); + CharSetLoadState(charset_data, &Buff->CharSetState); AutoWrapMode = Buff->AutoWrapMode; RelativeOrgMode = Buff->RelativeOrgMode; @@ -358,6 +359,8 @@ } } +static CharSetData *CharSetInitTerm(void); + void ResetCharSet() { if (ts.Language != IdJapanese) { @@ -374,7 +377,10 @@ cv.KanjiIn = ts.KanjiIn; cv.KanjiOut = ts.KanjiOut; - CharSetInit(); + if (charset_data != NULL) { + CharSetFinish(charset_data); + } + charset_data = CharSetInitTerm(); } void ResetKeypadMode(BOOL DisabledModeOnly) @@ -653,7 +659,7 @@ else if (CursorX < CursorLeftM) MoveCursor(0, CursorY); - CharSetFallbackFinish(); + CharSetFallbackFinish(charset_data); } static void LineFeed(BYTE b, BOOL logFlag) @@ -676,7 +682,7 @@ if (LFMode) CarriageReturn(logFlag); - CharSetFallbackFinish(); + CharSetFallbackFinish(charset_data); } static void Tab(void) @@ -716,7 +722,7 @@ BOOL SpecialNew = FALSE; if (code <= 0xff) { - SpecialNew = CharSetIsSpecial(code); + SpecialNew = CharSetIsSpecial(charset_data, code); if (SpecialNew) { code = code & 0x7F; } @@ -843,7 +849,7 @@ * * PutChar() \x82\xCC UTF-32\x94\xC5 */ -void PutU32(unsigned int code) +static void PutU32(unsigned int code) { PutU32NoLog(code); @@ -979,10 +985,10 @@ (ts.JIS7Katakana==1) && ((ts.TermFlag & TF_FIXEDJIS)!=0)) { - CharSet2022Designate(1, IdKatakana); + CharSet2022Designate(charset_data, 1, IdKatakana); } /* LS1 */ - CharSet2022Invoke(CHARSET_LS1); + CharSet2022Invoke(charset_data, CHARSET_LS1); return; } break; @@ -989,7 +995,7 @@ case SI: if ((ts.ISO2022Flag & ISO2022_SI) && ! DirectPrn) { /* LS0 */ - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Invoke(charset_data, CHARSET_LS0); return; } break; @@ -1018,7 +1024,7 @@ WriteToPrnFile(PrintFile_, b, TRUE); } -void ParseControl(BYTE b) +static void ParseControl(BYTE b) { if (PrinterMode) { // printer mode PrnParseControl(b); @@ -1121,15 +1127,15 @@ (ts.JIS7Katakana==1) && ((ts.TermFlag & TF_FIXEDJIS)!=0)) { - CharSet2022Designate(1, IdKatakana); + CharSet2022Designate(charset_data, 1, IdKatakana); } - CharSet2022Invoke(CHARSET_LS1); + CharSet2022Invoke(charset_data, CHARSET_LS1); } break; case SI: /* LS0 */ if (ts.ISO2022Flag & ISO2022_SI) { - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Invoke(charset_data, CHARSET_LS0); } break; case DLE: @@ -1179,12 +1185,12 @@ break; case SS2: if (ts.ISO2022Flag & ISO2022_SS2) { - CharSet2022Invoke(CHARSET_SS2); + CharSet2022Invoke(charset_data, CHARSET_SS2); } break; case SS3: if (ts.ISO2022Flag & ISO2022_SS3) { - CharSet2022Invoke(CHARSET_SS3); + CharSet2022Invoke(charset_data, CHARSET_SS3); } break; case DCS: @@ -1213,6 +1219,26 @@ } } +static void csPutU32(char32_t code, void *client_data) +{ + (void)client_data; + PutU32(code); +} + +static void csParseControl(BYTE b, void *client_data) +{ + (void)client_data; + ParseControl(b); +} + +static CharSetData *CharSetInitTerm(void) +{ + CharSetOp op; + op.PutU32 = csPutU32; + op.ParseControl = csParseControl; + return CharSetInit(&op, NULL); +} + static void AnswerTerminalType(void) { char Tmp[50]; @@ -1313,10 +1339,10 @@ if ((b=='@') || (b=='B')) { /* Kanji -> G0 */ - CharSet2022Designate(0, IdKanji); + CharSet2022Designate(charset_data, 0, IdKanji); if ((ts.TermFlag & TF_AUTOINVOKE)!=0) { /* G0->GL */ - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Invoke(charset_data, CHARSET_LS0); } } break; @@ -1339,10 +1365,10 @@ (b=='@') || (b=='B')) { /* Kanji -> G0-3 */ - CharSet2022Designate(Dist, IdKanji); + CharSet2022Designate(charset_data, Dist, IdKanji); if (((ts.TermFlag & TF_AUTOINVOKE)!=0) && (Dist==0)) { /* G0->GL */ - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Invoke(charset_data, CHARSET_LS0); } } break; @@ -1369,7 +1395,7 @@ switch (b) { case '0': - CharSet2022Designate(Dist, IdSpecial); + CharSet2022Designate(charset_data, Dist, IdSpecial); break; case '<': case '>': @@ -1376,20 +1402,20 @@ case 'A': case 'B': case 'H': - CharSet2022Designate(Dist, IdASCII); + CharSet2022Designate(charset_data, Dist, IdASCII); break; case 'I': if (ts.Language==IdJapanese) - CharSet2022Designate(Dist, IdKatakana); + CharSet2022Designate(charset_data, Dist, IdKatakana); break; case 'J': - CharSet2022Designate(Dist, IdASCII); + CharSet2022Designate(charset_data, Dist, IdASCII); break; } if (((ts.TermFlag & TF_AUTOINVOKE)!=0) && (Dist==0)) { /* G0->GL */ - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Invoke(charset_data, CHARSET_LS0); } } @@ -1498,12 +1524,12 @@ break; case 'N': /* SS2 */ if (ts.ISO2022Flag & ISO2022_SS2) { - CharSet2022Invoke(CHARSET_SS2); + CharSet2022Invoke(charset_data, CHARSET_SS2); } break; case 'O': /* SS3 */ if (ts.ISO2022Flag & ISO2022_SS3) { - CharSet2022Invoke(CHARSET_SS3); + CharSet2022Invoke(charset_data, CHARSET_SS3); } break; case 'P': /* DCS */ @@ -1543,27 +1569,27 @@ break; case 'n': /* LS2 */ if (ts.ISO2022Flag & ISO2022_LS2) { - CharSet2022Invoke(CHARSET_LS2); + CharSet2022Invoke(charset_data, CHARSET_LS2); } break; case 'o': /* LS3 */ if (ts.ISO2022Flag & ISO2022_LS3) { - CharSet2022Invoke(CHARSET_LS3); + CharSet2022Invoke(charset_data, CHARSET_LS3); } break; case '|': /* LS3R */ if (ts.ISO2022Flag & ISO2022_LS3R) { - CharSet2022Invoke(CHARSET_LS3R); + CharSet2022Invoke(charset_data, CHARSET_LS3R); } break; case '}': /* LS2R */ if (ts.ISO2022Flag & ISO2022_LS2R) { - CharSet2022Invoke(CHARSET_LS2R); + CharSet2022Invoke(charset_data, CHARSET_LS2R); } break; case '~': /* LS1R */ if (ts.ISO2022Flag & ISO2022_LS1R) { - CharSet2022Invoke(CHARSET_LS1R); + CharSet2022Invoke(charset_data, CHARSET_LS1R); } break; } @@ -1611,7 +1637,7 @@ ParseControl(b); else if (b>=0xA0) { ParseMode=ModeFirst; - ParseFirst(b); + ParseFirst(charset_data, b); } JustAfterESC = FALSE; @@ -1984,7 +2010,7 @@ else MoveCursor(CursorX,Param[1]-1); } - CharSetFallbackFinish(); + CharSetFallbackFinish(charset_data); } static void CSMoveToXY() // CUP / HVP @@ -2015,7 +2041,7 @@ } MoveCursor(NewX, NewY); - CharSetFallbackFinish(); + CharSetFallbackFinish(charset_data); } static void CSDeleteTabStop() @@ -2936,16 +2962,16 @@ case 59: if (ts.Language==IdJapanese) { /* kanji terminal */ - CharSet2022Designate(0, IdASCII); - CharSet2022Designate(1, IdKatakana); - CharSet2022Designate(2, IdKatakana); - CharSet2022Designate(3, IdKanji); - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Designate(charset_data, 0, IdASCII); + CharSet2022Designate(charset_data, 1, IdKatakana); + CharSet2022Designate(charset_data, 2, IdKatakana); + CharSet2022Designate(charset_data, 3, IdKanji); + CharSet2022Invoke(charset_data, CHARSET_LS0); if ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0)) // 8-bit katakana - CharSet2022Invoke(CHARSET_LS2R); + CharSet2022Invoke(charset_data, CHARSET_LS2R); else - CharSet2022Invoke(CHARSET_LS3R); + CharSet2022Invoke(charset_data, CHARSET_LS3R); } break; case 66: AppliKeyMode = TRUE; break; // DECNKM @@ -3106,16 +3132,16 @@ case 59: if (ts.Language==IdJapanese) { /* katakana terminal */ - CharSet2022Designate(0, IdASCII); - CharSet2022Designate(1, IdKatakana); - CharSet2022Designate(2, IdKatakana); - CharSet2022Designate(3, IdKanji); - CharSet2022Invoke(CHARSET_LS0); + CharSet2022Designate(charset_data, 0, IdASCII); + CharSet2022Designate(charset_data, 1, IdKatakana); + CharSet2022Designate(charset_data, 2, IdKatakana); + CharSet2022Designate(charset_data, 3, IdKanji); + CharSet2022Invoke(charset_data, CHARSET_LS0); if ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0)) // 8-bit katakana - CharSet2022Invoke(CHARSET_LS2R); + CharSet2022Invoke(charset_data, CHARSET_LS2R); else - CharSet2022Invoke(CHARSET_LS3R); + CharSet2022Invoke(charset_data, CHARSET_LS3R); } break; case 66: AppliKeyMode = FALSE; break; // DECNKM @@ -4152,7 +4178,7 @@ } else if (b>0xA0) { ParseMode=ModeFirst; - ParseFirst(b); + ParseFirst(charset_data, b); } } FirstPrm = FALSE; @@ -5353,7 +5379,7 @@ #endif switch (ParseMode) { case ModeFirst: - ParseFirst(b); + ParseFirst(charset_data, b); break; case ModeESC: EscapeSequence(b); @@ -5384,7 +5410,7 @@ break; default: ParseMode = ModeFirst; - ParseFirst(b); + ParseFirst(charset_data, b); } PrevCharacter = b; // memorize previous character for AUTO CR/LF-receive mode @@ -5756,6 +5782,8 @@ _free_locale(CLocale); } CLocale = NULL; + CharSetFinish(charset_data); + charset_data = NULL; } BOOL BracketedPasteMode() { @@ -5858,3 +5886,13 @@ { AutoWrapMode = auto_wrap_mode; } + +void TermSetNextDebugMode(void) +{ + CharSetSetNextDebugMode(charset_data); +} + +void TermSetDebugMode(BYTE mode) +{ + CharSetSetDebugMode(charset_data, mode); +} Modified: trunk/teraterm/teraterm/vtterm.h =================================================================== --- trunk/teraterm/teraterm/vtterm.h 2023-06-27 13:28:58 UTC (rev 10781) +++ trunk/teraterm/teraterm/vtterm.h 2023-06-27 13:36:25 UTC (rev 10782) @@ -60,6 +60,8 @@ void TermSetInsertMode(BOOL insert_mode); BOOL TermGetAutoWrapMode(void); void TermSetAutoWrapMode(BOOL auto_wrap_mode); +void TermSetNextDebugMode(void); +void TermSetDebugMode(BYTE mode); #ifdef __cplusplus }