Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2476 - (hide annotations) (download) (as text)
Mon Apr 14 17:35:50 2008 UTC (16 years ago) by maya
Original Path: teraterm/trunk/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 67493 byte(s)
ファイル移動に伴う修正

1 maya 2476 /* Tera Term
2     Copyright(C) 1994-1998 T. Teranishi
3     All rights reserved. */
4    
5     /* TERATERM.EXE, VT terminal emulation */
6     #include "teraterm.h"
7     #include "tttypes.h"
8     #include <stdio.h>
9     #include <string.h>
10     #include <stdlib.h>
11     #include <mbstring.h>
12     #include <locale.h>
13    
14     #include "buffer.h"
15     #include "ttwinman.h"
16     #include "ttcommon.h"
17     #include "commlib.h"
18     #include "vtdisp.h"
19     #include "keyboard.h"
20     #include "ttlib.h"
21     #include "ttftypes.h"
22     #include "filesys.h"
23     #include "teraprn.h"
24     #include "telnet.h"
25    
26     #include "vtterm.h"
27    
28     /* Parsing modes */
29     #define ModeFirst 0
30     #define ModeESC 1
31     #define ModeDCS 2
32     #define ModeDCUserKey 3
33     #define ModeSOS 4
34     #define ModeCSI 5
35     #define ModeXS 6
36     #define ModeDLE 7
37     #define ModeCAN 8
38    
39     #define NParamMax 16
40     #define IntCharMax 5
41    
42     /* character attribute */
43     static TCharAttr CharAttr;
44    
45     /* various modes of VT emulation */
46     static BOOL RelativeOrgMode;
47     static BOOL ReverseColor;
48     static BOOL InsertMode;
49     static BOOL LFMode;
50     static BOOL AutoWrapMode;
51     static BOOL FocusReportMode;
52     int MouseReportMode;
53    
54     // save/restore cursor
55     typedef struct {
56     int CursorX, CursorY;
57     TCharAttr Attr;
58     int Glr[2], Gn[4]; // G0-G3, GL & GR
59     BOOL AutoWrapMode;
60     BOOL RelativeOrgMode;
61     } TStatusBuff;
62     typedef TStatusBuff *PStatusBuff;
63    
64     // status buffer for main screen & status line
65     static TStatusBuff SBuff1, SBuff2;
66    
67     static BOOL ESCFlag, JustAfterESC;
68     static BOOL KanjiIn;
69     static BOOL EUCkanaIn, EUCsupIn;
70     static int EUCcount;
71     static BOOL Special;
72    
73     static int Param[NParamMax+1];
74     static int NParam;
75     static BOOL FirstPrm;
76     static BYTE IntChar[IntCharMax+1];
77     static int ICount;
78     static BYTE Prv;
79     static int ParseMode, SavedMode;
80     static int ChangeEmu;
81    
82     /* user defined keys */
83     static BOOL WaitKeyId, WaitHi;
84    
85     /* GL, GR code group */
86     static int Glr[2];
87     /* G0, G1, G2, G3 code group */
88     static int Gn[4];
89     /* GL for single shift 2/3 */
90     static int GLtmp;
91     /* single shift 2/3 flag */
92     static BOOL SSflag;
93     /* JIS -> SJIS conversion flag */
94     static BOOL ConvJIS;
95     static WORD Kanji;
96    
97     // variables for status line mode
98     static int StatusX=0;
99     static BOOL StatusWrap=FALSE;
100     static BOOL StatusCursor=TRUE;
101     static int MainX, MainY; //cursor registers
102     static int MainTop, MainBottom; // scroll region registers
103     static BOOL MainWrap;
104     static BOOL MainCursor=TRUE;
105    
106     /* status for printer escape sequences */
107     static BOOL PrintEX = TRUE; // printing extent
108     // (TRUE: screen, FALSE: scroll region)
109     static BOOL AutoPrintMode = FALSE;
110     static BOOL PrinterMode = FALSE;
111     static BOOL DirectPrn = FALSE;
112    
113     /* User key */
114     static BYTE NewKeyStr[FuncKeyStrMax];
115     static int NewKeyId, NewKeyLen;
116    
117     static _locale_t CLocale;
118    
119     void ResetSBuffers()
120     {
121     SBuff1.CursorX = 0;
122     SBuff1.CursorY = 0;
123     SBuff1.Attr = DefCharAttr;
124     if (ts.Language==IdJapanese)
125     {
126     SBuff1.Gn[0] = IdASCII;
127     SBuff1.Gn[1] = IdKatakana;
128     SBuff1.Gn[2] = IdKatakana;
129     SBuff1.Gn[3] = IdKanji;
130     SBuff1.Glr[0] = 0;
131     if ((ts.KanjiCode==IdJIS) &&
132     (ts.JIS7Katakana==0))
133     SBuff1.Glr[1] = 2; // 8-bit katakana
134     else
135     SBuff1.Glr[1] = 3;
136     }
137     else {
138     SBuff1.Gn[0] = IdASCII;
139     SBuff1.Gn[1] = IdSpecial;
140     SBuff1.Gn[2] = IdASCII;
141     SBuff1.Gn[3] = IdASCII;
142     SBuff1.Glr[0] = 0;
143     SBuff1.Glr[1] = 0;
144     }
145     SBuff1.AutoWrapMode = TRUE;
146     SBuff1.RelativeOrgMode = FALSE;
147     // copy SBuff1 to SBuff2
148     SBuff2 = SBuff1;
149     }
150    
151     void ResetTerminal() /*reset variables but don't update screen */
152     {
153     DispReset();
154     BuffReset();
155    
156     /* Attribute */
157     CharAttr = DefCharAttr;
158     Special = FALSE;
159     BuffSetCurCharAttr(CharAttr);
160    
161     /* Various modes */
162     InsertMode = FALSE;
163     LFMode = (ts.CRSend == IdCRLF);
164     AutoWrapMode = TRUE;
165     AppliKeyMode = FALSE;
166     AppliCursorMode = FALSE;
167     RelativeOrgMode = FALSE;
168     ReverseColor = FALSE;
169     AutoRepeatMode = TRUE;
170     Send8BitMode = ts.Send8BitCtrl;
171     FocusReportMode = FALSE;
172     MouseReportMode = IdMouseTrackNone;
173    
174     CLocale = _create_locale(LC_ALL, "C");
175    
176     /* Character sets */
177     ResetCharSet();
178    
179     /* ESC flag for device control sequence */
180     ESCFlag = FALSE;
181     /* for TEK sequence */
182     JustAfterESC = FALSE;
183    
184     /* Parse mode */
185     ParseMode = ModeFirst;
186    
187     /* Clear printer mode */
188     PrinterMode = FALSE;
189    
190     // status buffers
191     ResetSBuffers();
192     }
193    
194     void ResetCharSet()
195     {
196     if (ts.Language==IdJapanese)
197     {
198     Gn[0] = IdASCII;
199     Gn[1] = IdKatakana;
200     Gn[2] = IdKatakana;
201     Gn[3] = IdKanji;
202     Glr[0] = 0;
203     if ((ts.KanjiCode==IdJIS) &&
204     (ts.JIS7Katakana==0))
205     Glr[1] = 2; // 8-bit katakana
206     else
207     Glr[1] = 3;
208     }
209     else {
210     Gn[0] = IdASCII;
211     Gn[1] = IdSpecial;
212     Gn[2] = IdASCII;
213     Gn[3] = IdASCII;
214     Glr[0] = 0;
215     Glr[1] = 0;
216     cv.SendCode = IdASCII;
217     cv.SendKanjiFlag = FALSE;
218     cv.EchoCode = IdASCII;
219     cv.EchoKanjiFlag = FALSE;
220     }
221     /* Kanji flag */
222     KanjiIn = FALSE;
223     EUCkanaIn = FALSE;
224     EUCsupIn = FALSE;
225     SSflag = FALSE;
226    
227     cv.Language = ts.Language;
228     cv.CRSend = ts.CRSend;
229     cv.KanjiCodeEcho = ts.KanjiCode;
230     cv.JIS7KatakanaEcho = ts.JIS7Katakana;
231     cv.KanjiCodeSend = ts.KanjiCodeSend;
232     cv.JIS7KatakanaSend = ts.JIS7KatakanaSend;
233     cv.KanjiIn = ts.KanjiIn;
234     cv.KanjiOut = ts.KanjiOut;
235     }
236    
237     void ResetKeypadMode(BOOL DisabledModeOnly)
238     {
239     if (!DisabledModeOnly || ts.DisableAppKeypad) AppliKeyMode = FALSE;
240     if (!DisabledModeOnly || ts.DisableAppCursor) AppliCursorMode = FALSE;
241     }
242    
243     void MoveToMainScreen()
244     {
245     StatusX = CursorX;
246     StatusWrap = Wrap;
247     StatusCursor = IsCaretEnabled();
248    
249     CursorTop = MainTop;
250     CursorBottom = MainBottom;
251     Wrap = MainWrap;
252     DispEnableCaret(MainCursor);
253     MoveCursor(MainX,MainY); // move to main screen
254     }
255    
256     void MoveToStatusLine()
257     {
258     MainX = CursorX;
259     MainY = CursorY;
260     MainTop = CursorTop;
261     MainBottom = CursorBottom;
262     MainWrap = Wrap;
263     MainCursor = IsCaretEnabled();
264    
265     DispEnableCaret(StatusCursor);
266     MoveCursor(StatusX,NumOfLines-1); // move to status line
267     CursorTop = NumOfLines-1;
268     CursorBottom = CursorTop;
269     Wrap = StatusWrap;
270     }
271    
272     void HideStatusLine()
273     {
274     if ((StatusLine>0) &&
275     (CursorY==NumOfLines-1))
276     MoveToMainScreen();
277     StatusX = 0;
278     StatusWrap = FALSE;
279     StatusCursor = TRUE;
280     ShowStatusLine(0); //hide
281     }
282    
283     void ChangeTerminalSize(int Nx, int Ny)
284     {
285     BuffChangeTerminalSize(Nx,Ny);
286     StatusX = 0;
287     MainX = 0;
288     MainY = 0;
289     MainTop = 0;
290     MainBottom = NumOfColumns-1;
291     }
292    
293     void BackSpace()
294     {
295     if (CursorX == 0)
296     {
297     if ((CursorY>0) &&
298     ((ts.TermFlag & TF_BACKWRAP)!=0))
299     {
300     MoveCursor(NumOfColumns-1,CursorY-1);
301     // if (cv.HLogBuf!=0) Log1Byte(BS);
302     // (2005.2.20 yutaka)
303     if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
304     }
305     }
306     else if (CursorX > 0)
307     {
308     MoveCursor(CursorX-1,CursorY);
309     // if (cv.HLogBuf!=0) Log1Byte(BS);
310     // (2005.2.20 yutaka)
311     if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
312     }
313     }
314    
315     void CarriageReturn(BOOL logFlag)
316     {
317     #ifndef NO_COPYLINE_FIX
318     if (!ts.EnableContinuedLineCopy || logFlag)
319     #endif /* NO_COPYLINE_FIX */
320     if (cv.HLogBuf!=0) Log1Byte(CR);
321    
322     if (CursorX>0)
323     MoveCursor(0,CursorY);
324     }
325    
326     void LineFeed(BYTE b, BOOL logFlag)
327     {
328     /* for auto print mode */
329     if ((AutoPrintMode) &&
330     (b>=LF) && (b<=FF))
331     BuffDumpCurrentLine(b);
332    
333     #ifndef NO_COPYLINE_FIX
334     if (!ts.EnableContinuedLineCopy || logFlag)
335     #endif /* NO_COPYLINE_FIX */
336     if (cv.HLogBuf!=0) Log1Byte(LF);
337    
338     if (CursorY < CursorBottom)
339     MoveCursor(CursorX,CursorY+1);
340     else if (CursorY == CursorBottom) BuffScrollNLines(1);
341     else if (CursorY < NumOfLines-StatusLine-1)
342     MoveCursor(CursorX,CursorY+1);
343    
344     if (LFMode) CarriageReturn(logFlag);
345     }
346    
347     void Tab()
348     {
349     if (Wrap && !ts.VTCompatTab) {
350     CarriageReturn(FALSE);
351     LineFeed(LF,FALSE);
352     #ifndef NO_COPYLINE_FIX
353     if (ts.EnableContinuedLineCopy) {
354     SetLineContinued();
355     }
356     #endif /* NO_COPYLINE_FIX */
357     Wrap = FALSE;
358     }
359     MoveToNextTab(AutoWrapMode);
360     if (cv.HLogBuf!=0) Log1Byte(HT);
361     }
362    
363     void PutChar(BYTE b)
364     {
365     BOOL SpecialNew;
366     TCharAttr CharAttrTmp;
367    
368     CharAttrTmp = CharAttr;
369    
370     if (PrinterMode) { // printer mode
371     WriteToPrnFile(b,TRUE);
372     return;
373     }
374    
375     if (Wrap)
376     {
377     CarriageReturn(FALSE);
378     LineFeed(LF,FALSE);
379     #ifndef NO_COPYLINE_FIX
380     CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
381     #endif /* NO_COPYLINE_FIX */
382     }
383    
384     // if (cv.HLogBuf!=0) Log1Byte(b);
385     // (2005.2.20 yutaka)
386     if (ts.LogTypePlainText) {
387     if (__isascii(b) && !isprint(b)) {
388     // ASCII�������A���\�������������O�����������B
389     } else {
390     if (cv.HLogBuf!=0) Log1Byte(b);
391     }
392     } else {
393     if (cv.HLogBuf!=0) Log1Byte(b);
394     }
395    
396     Wrap = FALSE;
397    
398     SpecialNew = FALSE;
399     if ((b>0x5F) && (b<0x80))
400     {
401     if (SSflag)
402     SpecialNew = (Gn[GLtmp]==IdSpecial);
403     else
404     SpecialNew = (Gn[Glr[0]]==IdSpecial);
405     }
406     else if (b>0xDF)
407     {
408     if (SSflag)
409     SpecialNew = (Gn[GLtmp]==IdSpecial);
410     else
411     SpecialNew = (Gn[Glr[1]]==IdSpecial);
412     }
413    
414     if (SpecialNew != Special)
415     {
416     UpdateStr();
417     Special = SpecialNew;
418     }
419    
420     if (Special)
421     {
422     b = b & 0x7F;
423     CharAttrTmp.Attr |= AttrSpecial;
424     }
425     else
426     CharAttrTmp.Attr |= CharAttr.Attr;
427    
428     BuffPutChar(b, CharAttrTmp, InsertMode);
429    
430     if (CursorX < NumOfColumns-1)
431     MoveRight();
432     else {
433     UpdateStr();
434     Wrap = AutoWrapMode;
435     }
436     }
437    
438    
439     void PutKanji(BYTE b)
440     {
441     #ifndef NO_COPYLINE_FIX
442     TCharAttr CharAttrTmp;
443    
444     CharAttrTmp = CharAttr;
445     #endif /* NO_COPYLINE_FIX */
446     Kanji = Kanji + b;
447    
448     if (PrinterMode && DirectPrn)
449     {
450     WriteToPrnFile(HIBYTE(Kanji),FALSE);
451     WriteToPrnFile(LOBYTE(Kanji),TRUE);
452     return;
453     }
454    
455     if (ConvJIS)
456     Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f));
457    
458     if (PrinterMode) { // printer mode
459     WriteToPrnFile(HIBYTE(Kanji),FALSE);
460     WriteToPrnFile(LOBYTE(Kanji),TRUE);
461     return;
462     }
463    
464     if (Wrap)
465     {
466     CarriageReturn(FALSE);
467     LineFeed(LF,FALSE);
468     #ifndef NO_COPYLINE_FIX
469     if (ts.EnableContinuedLineCopy)
470     CharAttrTmp.Attr |= AttrLineContinued;
471     #endif /* NO_COPYLINE_FIX */
472     }
473     else if (CursorX > NumOfColumns-2)
474     if (AutoWrapMode)
475     {
476     #ifndef NO_COPYLINE_FIX
477     if (ts.EnableContinuedLineCopy)
478     {
479     CharAttrTmp.Attr |= AttrLineContinued;
480     if (CursorX == NumOfColumns-1)
481     BuffPutChar(0x20, CharAttr, FALSE);
482     }
483     #endif /* NO_COPYLINE_FIX */
484     CarriageReturn(FALSE);
485     LineFeed(LF,FALSE);
486     }
487     else return;
488    
489     Wrap = FALSE;
490    
491     if (cv.HLogBuf!=0)
492     {
493     Log1Byte(HIBYTE(Kanji));
494     Log1Byte(LOBYTE(Kanji));
495     }
496    
497     if (Special)
498     {
499     UpdateStr();
500     Special = FALSE;
501     }
502    
503     #ifndef NO_COPYLINE_FIX
504     BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
505     #else
506     BuffPutKanji(Kanji, CharAttr, InsertMode);
507     #endif /* NO_COPYLINE_FIX */
508    
509     if (CursorX < NumOfColumns-2)
510     {
511     MoveRight();
512     MoveRight();
513     }
514     else {
515     UpdateStr();
516     Wrap = AutoWrapMode;
517     }
518     }
519    
520     void PutDebugChar(BYTE b)
521     {
522     InsertMode = FALSE;
523     AutoWrapMode = TRUE;
524    
525     if ((b & 0x80) == 0x80)
526     {
527     UpdateStr();
528     CharAttr.Attr = AttrReverse;
529     b = b & 0x7f;
530     }
531    
532     if (b<=US)
533     {
534     PutChar('^');
535     PutChar((char)(b+0x40));
536     }
537     else if (b==DEL)
538     {
539     PutChar('<');
540     PutChar('D');
541     PutChar('E');
542     PutChar('L');
543     PutChar('>');
544     }
545     else
546     PutChar(b);
547    
548     if (CharAttr.Attr != AttrDefault)
549     {
550     UpdateStr();
551     CharAttr.Attr = AttrDefault;
552     }
553     }
554    
555     void PrnParseControl(BYTE b) // printer mode
556     {
557     switch (b) {
558     case NUL: return;
559     case SO:
560     if (! DirectPrn)
561     {
562     if ((ts.Language==IdJapanese) &&
563     (ts.KanjiCode==IdJIS) &&
564     (ts.JIS7Katakana==1) &&
565     ((ts.TermFlag & TF_FIXEDJIS)!=0))
566     Gn[1] = IdKatakana;
567     Glr[0] = 1; /* LS1 */
568     return;
569     }
570     break;
571     case SI:
572     if (! DirectPrn)
573     {
574     Glr[0] = 0; /* LS0 */
575     return;
576     }
577     break;
578     case DC1:
579     case DC3: return;
580     case ESC:
581     ICount = 0;
582     JustAfterESC = TRUE;
583     ParseMode = ModeESC;
584     WriteToPrnFile(0,TRUE); // flush prn buff
585     return;
586     case CSI:
587     if ((ts.TerminalID<IdVT220J) ||
588     ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0))
589     {
590     PutChar(b); /* Disp C1 char in VT100 mode */
591     return;
592     }
593     ICount = 0;
594     FirstPrm = TRUE;
595     NParam = 1;
596     Param[1] = -1;
597     Prv = 0;
598     ParseMode = ModeCSI;
599     WriteToPrnFile(0,TRUE); // flush prn buff
600     WriteToPrnFile(b,FALSE);
601     return;
602     }
603     /* send the uninterpreted character to printer */
604     WriteToPrnFile(b,TRUE);
605     }
606    
607     void ParseControl(BYTE b)
608     {
609     if (PrinterMode) { // printer mode
610     PrnParseControl(b);
611     return;
612     }
613    
614     if (b>=0x80) /* C1 char */
615     {
616     /* English mode */
617     if (ts.Language==IdEnglish)
618     {
619     if ((ts.TerminalID<IdVT220J) ||
620     ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0))
621     {
622     PutChar(b); /* Disp C1 char in VT100 mode */
623     return;
624     }
625     }
626     else { /* Japanese mode */
627     if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0)
628     return; /* ignore C1 char */
629     /* C1 chars are interpreted as C0 chars in VT100 mode */
630     if (ts.TerminalID<IdVT220J)
631     b = b & 0x7F;
632     }
633     }
634     switch (b) {
635     /* C0 group */
636     case ENQ:
637     CommBinaryOut(&cv,&(ts.Answerback[0]),ts.AnswerbackLen);
638     break;
639     case BEL:
640     if (ts.Beep!=0)
641     MessageBeep(0);
642     break;
643     case BS: BackSpace(); break;
644     case HT: Tab(); break;
645    
646     case LF:
647     // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
648     // CR+LF���������������������B
649     // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
650     // (2007.1.21 yutaka)
651     if (ts.CRReceive == IdLF) {
652     CarriageReturn(TRUE);
653     LineFeed(b, TRUE);
654     break;
655     }
656    
657     case VT: LineFeed(b,TRUE); break;
658    
659     case FF:
660     if ((ts.AutoWinSwitch>0) && JustAfterESC)
661     {
662     CommInsert1Byte(&cv,b);
663     CommInsert1Byte(&cv,ESC);
664     ChangeEmu = IdTEK; /* Enter TEK Mode */
665     }
666     else
667     LineFeed(b,TRUE);
668     break;
669     case CR:
670     CarriageReturn(TRUE);
671     if (ts.CRReceive==IdCRLF)
672     CommInsert1Byte(&cv,LF);
673     break;
674     case SO:
675     if ((ts.Language==IdJapanese) &&
676     (ts.KanjiCode==IdJIS) &&
677     (ts.JIS7Katakana==1) &&
678     ((ts.TermFlag & TF_FIXEDJIS)!=0))
679     Gn[1] = IdKatakana;
680    
681     Glr[0] = 1; /* LS1 */
682     break;
683     case SI: Glr[0] = 0; break; /* LS0 */
684     case DLE:
685     if ((ts.FTFlag & FT_BPAUTO)!=0)
686     ParseMode = ModeDLE; /* Auto B-Plus activation */
687     break;
688     case CAN:
689     if ((ts.FTFlag & FT_ZAUTO)!=0)
690     ParseMode = ModeCAN; /* Auto ZMODEM activation */
691     // else if (ts.AutoWinSwitch>0)
692     // ChangeEmu = IdTEK; /* Enter TEK Mode */
693     else
694     ParseMode = ModeFirst;
695     break;
696     case SUB: ParseMode = ModeFirst; break;
697     case ESC:
698     ICount = 0;
699     JustAfterESC = TRUE;
700     ParseMode = ModeESC;
701     break;
702     case FS:
703     case GS:
704     case RS:
705     case US:
706     if (ts.AutoWinSwitch>0)
707     {
708     CommInsert1Byte(&cv,b);
709     ChangeEmu = IdTEK; /* Enter TEK Mode */
710     }
711     break;
712    
713     /* C1 char */
714     case IND: LineFeed(0,TRUE); break;
715     case NEL:
716     LineFeed(0,TRUE);
717     CarriageReturn(TRUE);
718     break;
719     case HTS: SetTabStop(); break;
720     case RI: CursorUpWithScroll(); break;
721     case SS2:
722     GLtmp = 2;
723     SSflag = TRUE;
724     break;
725     case SS3:
726     GLtmp = 3;
727     SSflag = TRUE;
728     break;
729     case DCS:
730     SavedMode = ParseMode;
731     ESCFlag = FALSE;
732     NParam = 1;
733     Param[1] = -1;
734     ParseMode = ModeDCS;
735     break;
736     case SOS:
737     SavedMode = ParseMode;
738     ESCFlag = FALSE;
739     ParseMode = ModeSOS;
740     break;
741     case CSI:
742     ICount = 0;
743     FirstPrm = TRUE;
744     NParam = 1;
745     Param[1] = -1;
746     Prv = 0;
747     ParseMode = ModeCSI;
748     break;
749     case OSC:
750     Param[1] = 0;
751     ParseMode = ModeXS;
752     break;
753     case PM:
754     case APC:
755     SavedMode = ParseMode;
756     ESCFlag = FALSE;
757     ParseMode = ModeSOS;
758     break;
759     }
760     }
761    
762     void SaveCursor()
763     {
764     int i;
765     PStatusBuff Buff;
766    
767     if ((StatusLine>0) &&
768     (CursorY==NumOfLines-1))
769     Buff = &SBuff2; // for status line
770     else
771     Buff = &SBuff1; // for main screen
772    
773     Buff->CursorX = CursorX;
774     Buff->CursorY = CursorY;
775     Buff->Attr = CharAttr;
776     Buff->Glr[0] = Glr[0];
777     Buff->Glr[1] = Glr[1];
778     for (i=0 ; i<=3; i++)
779     Buff->Gn[i] = Gn[i];
780     Buff->AutoWrapMode = AutoWrapMode;
781     Buff->RelativeOrgMode = RelativeOrgMode;
782     }
783    
784     void RestoreCursor()
785     {
786     int i;
787     PStatusBuff Buff;
788     UpdateStr();
789    
790     if ((StatusLine>0) &&
791     (CursorY==NumOfLines-1))
792     Buff = &SBuff2; // for status line
793     else
794     Buff = &SBuff1; // for main screen
795    
796     if (Buff->CursorX > NumOfColumns-1)
797     Buff->CursorX = NumOfColumns-1;
798     if (Buff->CursorY > NumOfLines-1-StatusLine)
799     Buff->CursorY = NumOfLines-1-StatusLine;
800     MoveCursor(Buff->CursorX,Buff->CursorY);
801     CharAttr = Buff->Attr;
802     Glr[0] = Buff->Glr[0];
803     Glr[1] = Buff->Glr[1];
804     for (i=0 ; i<=3; i++)
805     Gn[i] = Buff->Gn[i];
806     AutoWrapMode = Buff->AutoWrapMode;
807     RelativeOrgMode = Buff->RelativeOrgMode;
808     }
809    
810     void AnswerTerminalType()
811     {
812     char Tmp[31];
813    
814     if (ts.TerminalID<IdVT320)
815     strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
816     else
817     strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
818    
819     switch (ts.TerminalID) {
820     case IdVT100:
821     strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
822     break;
823     case IdVT100J:
824     strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
825     break;
826     case IdVT101:
827     strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
828     break;
829     case IdVT102:
830     strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
831     break;
832     case IdVT102J:
833     strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
834     break;
835     case IdVT220J:
836     strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
837     break;
838     case IdVT282:
839     strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
840     break;
841     case IdVT320:
842     strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
843     break;
844     case IdVT382:
845     strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
846     break;
847     }
848     strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
849    
850     CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
851     }
852    
853     void ESCSpace(BYTE b)
854     {
855     switch (b) {
856     case 'F': Send8BitMode = FALSE; break; // S7C1T
857     case 'G': Send8BitMode = TRUE; break; // S8C1T
858     }
859     }
860    
861     void ESCSharp(BYTE b)
862     {
863     switch (b) {
864     case '8': /* Fill screen with "E" */
865     BuffUpdateScroll();
866     BuffFillWithE();
867     MoveCursor(0,0);
868     ParseMode = ModeFirst;
869     break;
870     }
871     }
872    
873     /* select double byte code set */
874     void ESCDBCSSelect(BYTE b)
875     {
876     int Dist;
877    
878     if (ts.Language!=IdJapanese) return;
879    
880     switch (ICount) {
881     case 1:
882     if ((b=='@') || (b=='B'))
883     {
884     Gn[0] = IdKanji; /* Kanji -> G0 */
885     if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
886     Glr[0] = 0; /* G0->GL */
887     }
888     break;
889     case 2:
890     /* Second intermediate char must be
891     '(' or ')' or '*' or '+'. */
892     Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
893     if ((b=='1') || (b=='3') ||
894     (b=='@') || (b=='B'))
895     {
896     Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
897     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
898     (Dist==0))
899     Glr[0] = 0; /* G0->GL */
900     }
901     break;
902     }
903     }
904    
905     void ESCSelectCode(BYTE b)
906     {
907     switch (b) {
908     case '0':
909     if (ts.AutoWinSwitch>0)
910     ChangeEmu = IdTEK; /* enter TEK mode */
911     break;
912     }
913     }
914    
915     /* select single byte code set */
916     void ESCSBCSSelect(BYTE b)
917     {
918     int Dist;
919    
920     /* Intermediate char must be
921     '(' or ')' or '*' or '+'. */
922     Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
923    
924     switch (b) {
925     case '0': Gn[Dist] = IdSpecial; break;
926     case '<': Gn[Dist] = IdASCII; break;
927     case '>': Gn[Dist] = IdASCII; break;
928     case 'B': Gn[Dist] = IdASCII; break;
929     case 'H': Gn[Dist] = IdASCII; break;
930     case 'I':
931     if (ts.Language==IdJapanese)
932     Gn[Dist] = IdKatakana;
933     break;
934     case 'J': Gn[Dist] = IdASCII; break;
935     }
936    
937     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
938     (Dist==0))
939     Glr[0] = 0; /* G0->GL */
940     }
941    
942     void PrnParseEscape(BYTE b) // printer mode
943     {
944     int i;
945    
946     ParseMode = ModeFirst;
947     switch (ICount) {
948     /* no intermediate char */
949     case 0:
950     switch (b) {
951     case '[': /* CSI */
952     ICount = 0;
953     FirstPrm = TRUE;
954     NParam = 1;
955     Param[1] = -1;
956     Prv = 0;
957     WriteToPrnFile(ESC,FALSE);
958     WriteToPrnFile('[',FALSE);
959     ParseMode = ModeCSI;
960     return;
961     } /* end of case Icount=0 */
962     break;
963     /* one intermediate char */
964     case 1:
965     switch (IntChar[1]) {
966     case '$':
967     if (! DirectPrn)
968     {
969     ESCDBCSSelect(b);
970     return;
971     }
972     break;
973     case '(':
974     case ')':
975     case '*':
976     case '+':
977     if (! DirectPrn)
978     {
979     ESCSBCSSelect(b);
980     return;
981     }
982     break;
983     }
984     break;
985     /* two intermediate char */
986     case 2:
987     if ((! DirectPrn) &&
988     (IntChar[1]=='$') &&
989     ('('<=IntChar[2]) &&
990     (IntChar[2]<='+'))
991     {
992     ESCDBCSSelect(b);
993     return;
994     }
995     break;
996     }
997     // send the uninterpreted sequence to printer
998     WriteToPrnFile(ESC,FALSE);
999     for (i=1; i<=ICount; i++)
1000     WriteToPrnFile(IntChar[i],FALSE);
1001     WriteToPrnFile(b,TRUE);
1002     }
1003    
1004     void ParseEscape(BYTE b) /* b is the final char */
1005     {
1006     if (PrinterMode) { // printer mode
1007     PrnParseEscape(b);
1008     return;
1009     }
1010    
1011     switch (ICount) {
1012     /* no intermediate char */
1013     case 0:
1014     switch (b) {
1015     case '7': SaveCursor(); break;
1016     case '8': RestoreCursor(); break;
1017     case '=': AppliKeyMode = TRUE; break;
1018     case '>': AppliKeyMode = FALSE; break;
1019     case 'D': /* IND */
1020     LineFeed(0,TRUE);
1021     break;
1022     case 'E': /* NEL */
1023     MoveCursor(0,CursorY);
1024     LineFeed(0,TRUE);
1025     break;
1026     case 'H': /* HTS */
1027     SetTabStop();
1028     break;
1029     case 'M': /* RI */
1030     CursorUpWithScroll();
1031     break;
1032     case 'N': /* SS2 */
1033     GLtmp = 2;
1034     SSflag = TRUE;
1035     break;
1036     case 'O': /* SS3 */
1037     GLtmp = 3;
1038     SSflag = TRUE;
1039     break;
1040     case 'P': /* DCS */
1041     SavedMode = ParseMode;
1042     ESCFlag = FALSE;
1043     NParam = 1;
1044     Param[1] = -1;
1045     ParseMode = ModeDCS;
1046     return;
1047     case 'X': /* SOS */
1048     SavedMode = ParseMode;
1049     ESCFlag = FALSE;
1050     ParseMode = ModeSOS;
1051     return;
1052     case 'Z': AnswerTerminalType(); break;
1053     case '[': /* CSI */
1054     ICount = 0;
1055     FirstPrm = TRUE;
1056     NParam = 1;
1057     Param[1] = -1;
1058     Prv = 0;
1059     ParseMode = ModeCSI;
1060     return;
1061     case '\\': break; /* ST */
1062     case ']': /* XTERM sequence (OSC) */
1063     NParam = 1;
1064     Param[1] = 0;
1065     ParseMode = ModeXS;
1066     return;
1067     case '^':
1068     case '_': /* PM, APC */
1069     SavedMode = ParseMode;
1070     ESCFlag = FALSE;
1071     ParseMode = ModeSOS;
1072     return;
1073     case 'c': /* Hardware reset */
1074     HideStatusLine();
1075     ResetTerminal();
1076     ClearUserKey();
1077     ClearBuffer();
1078     if (ts.PortType==IdSerial) // reset serial port
1079     CommResetSerial(&ts, &cv, TRUE);
1080     break;
1081     case 'n': Glr[0] = 2; break; /* LS2 */
1082     case 'o': Glr[0] = 3; break; /* LS3 */
1083     case '|': Glr[1] = 3; break; /* LS3R */
1084     case '}': Glr[1] = 2; break; /* LS2R */
1085     case '~': Glr[1] = 1; break; /* LS1R */
1086     } /* end of case Icount=0 */
1087     break;
1088     /* one intermediate char */
1089     case 1:
1090     switch (IntChar[1]) {
1091     case ' ': ESCSpace(b); break;
1092     case '#': ESCSharp(b); break;
1093     case '$': ESCDBCSSelect(b); break;
1094     case '%': break;
1095     case '(':
1096     case ')':
1097     case '*':
1098     case '+':
1099     ESCSBCSSelect(b);
1100     break;
1101     }
1102     break;
1103     /* two intermediate char */
1104     case 2:
1105     if ((IntChar[1]=='$') &&
1106     ('('<=IntChar[2]) &&
1107     (IntChar[2]<='+'))
1108     ESCDBCSSelect(b);
1109     else if ((IntChar[1]=='%') &&
1110     (IntChar[2]=='!'))
1111     ESCSelectCode(b);
1112     break;
1113     }
1114     ParseMode = ModeFirst;
1115     }
1116    
1117     void EscapeSequence(BYTE b)
1118     {
1119     if (b<=US)
1120     ParseControl(b);
1121     else if ((b>=0x20) && (b<=0x2F))
1122     {
1123     if (ICount<IntCharMax) ICount++;
1124     IntChar[ICount] = b;
1125     }
1126     else if ((b>=0x30) && (b<=0x7E))
1127     ParseEscape(b);
1128     else if ((b>=0x80) && (b<=0x9F))
1129     ParseControl(b);
1130    
1131     JustAfterESC = FALSE;
1132     }
1133    
1134     void CSInsertCharacter()
1135     {
1136     // Insert space characters at cursor
1137     int Count;
1138    
1139     BuffUpdateScroll();
1140     if (Param[1]<1) Param[1] = 1;
1141     Count = Param[1];
1142     BuffInsertSpace(Count);
1143     }
1144    
1145     void CSCursorUp()
1146     {
1147     if (Param[1]<1) Param[1] = 1;
1148    
1149     if (CursorY >= CursorTop)
1150     {
1151     if (CursorY-Param[1] > CursorTop)
1152     MoveCursor(CursorX,CursorY-Param[1]);
1153     else
1154     MoveCursor(CursorX,CursorTop);
1155     }
1156     else {
1157     if (CursorY > 0)
1158     MoveCursor(CursorX,CursorY-Param[1]);
1159     else
1160     MoveCursor(CursorX,0);
1161     }
1162     }
1163    
1164     void CSCursorUp1()
1165     {
1166     MoveCursor(0,CursorY);
1167     CSCursorUp();
1168     }
1169    
1170     void CSCursorDown()
1171     {
1172     if (Param[1]<1) Param[1] = 1;
1173    
1174     if (CursorY <= CursorBottom)
1175     {
1176     if (CursorY+Param[1] < CursorBottom)
1177     MoveCursor(CursorX,CursorY+Param[1]);
1178     else
1179     MoveCursor(CursorX,CursorBottom);
1180     }
1181     else {
1182     if (CursorY < NumOfLines-StatusLine-1)
1183     MoveCursor(CursorX,CursorY+Param[1]);
1184     else
1185     MoveCursor(CursorX,NumOfLines-StatusLine);
1186     }
1187     }
1188    
1189     void CSCursorDown1()
1190     {
1191     MoveCursor(0,CursorY);
1192     CSCursorDown();
1193     }
1194    
1195     void CSScreenErase()
1196     {
1197     if (Param[1] == -1) Param[1] = 0;
1198     BuffUpdateScroll();
1199     switch (Param[1]) {
1200     case 0:
1201     // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1202     // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1203     // �����������������B(2005.5.29 yutaka)
1204     if (CursorX == 0 && CursorY == 0) {
1205     // Erase screen (scroll out)
1206     BuffClearScreen();
1207     UpdateWindow(HVTWin);
1208    
1209     } else {
1210     // Erase characters from cursor to the end of screen
1211     BuffEraseCurToEnd();
1212     }
1213     break;
1214    
1215     case 1:
1216     // Erase characters from home to cursor
1217     BuffEraseHomeToCur();
1218     break;
1219    
1220     case 2:
1221     // Erase screen (scroll out)
1222     BuffClearScreen();
1223     UpdateWindow(HVTWin);
1224     break;
1225     }
1226     }
1227    
1228     void CSInsertLine()
1229     {
1230     // Insert lines at current position
1231     int Count, YEnd;
1232    
1233     if (CursorY < CursorTop) return;
1234     if (CursorY > CursorBottom) return;
1235     if (Param[1]<1) Param[1] = 1;
1236     Count = Param[1];
1237    
1238     YEnd = CursorBottom;
1239     if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1240     if (Count > YEnd+1 - CursorY) Count = YEnd+1 - CursorY;
1241    
1242     BuffInsertLines(Count,YEnd);
1243     }
1244    
1245     void CSLineErase()
1246     {
1247     if (Param[1] == -1) Param[1] = 0;
1248     BuffUpdateScroll();
1249     switch (Param[1]) {
1250     /* erase char from cursor to end of line */
1251     case 0:
1252     BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1253     break;
1254     /* erase char from start of line to cursor */
1255     case 1:
1256     BuffEraseCharsInLine(0,CursorX+1);
1257     break;
1258     /* erase entire line */
1259     case 2:
1260     BuffEraseCharsInLine(0,NumOfColumns);
1261     break;
1262     }
1263     }
1264    
1265     void CSDeleteNLines()
1266     // Delete lines from current line
1267     {
1268     int Count, YEnd;
1269    
1270     if (CursorY < CursorTop) return;
1271     if (CursorY > CursorBottom) return;
1272     Count = Param[1];
1273     if (Count<1) Count = 1;
1274    
1275     YEnd = CursorBottom;
1276     if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1277     if (Count > YEnd+1-CursorY) Count = YEnd+1-CursorY;
1278     BuffDeleteLines(Count,YEnd);
1279     }
1280    
1281     void CSDeleteCharacter()
1282     {
1283     // Delete characters in current line from cursor
1284    
1285     if (Param[1]<1) Param[1] = 1;
1286     BuffUpdateScroll();
1287     BuffDeleteChars(Param[1]);
1288     }
1289    
1290     void CSEraseCharacter()
1291     {
1292     if (Param[1]<1) Param[1] = 1;
1293     BuffUpdateScroll();
1294     BuffEraseChars(Param[1]);
1295     }
1296    
1297     void CSScrollUP()
1298     {
1299     if (Param[1]<1) Param[1] = 1;
1300     BuffUpdateScroll();
1301     BuffRegionScrollUpNLines(Param[1]);
1302     }
1303    
1304     void CSScrollDown()
1305     {
1306     if (Param[1]<1) Param[1] = 1;
1307     BuffUpdateScroll();
1308     BuffRegionScrollDownNLines(Param[1]);
1309     }
1310    
1311     void CSMoveToColumnN()
1312     {
1313     if (Param[1]<1) Param[1] = 1;
1314     Param[1]--;
1315     if (Param[1] < 0) Param[1] = 0;
1316     if (Param[1] > NumOfColumns-1) Param[1] = NumOfColumns-1;
1317     MoveCursor(Param[1],CursorY);
1318     }
1319    
1320     void CSCursorRight()
1321     {
1322     if (Param[1]<1) Param[1] = 1;
1323     if (CursorX + Param[1] > NumOfColumns-1)
1324     MoveCursor(NumOfColumns-1,CursorY);
1325     else
1326     MoveCursor(CursorX+Param[1],CursorY);
1327     }
1328    
1329     void CSCursorLeft()
1330     {
1331     if (Param[1]<1) Param[1] = 1;
1332     if (CursorX-Param[1] < 0)
1333     MoveCursor(0,CursorY);
1334     else
1335     MoveCursor(CursorX-Param[1],CursorY);
1336     }
1337    
1338     void CSMoveToLineN()
1339     {
1340     if (Param[1]<1) Param[1] = 1;
1341     if (RelativeOrgMode)
1342     {
1343     if (CursorTop+Param[1]-1 > CursorBottom)
1344     MoveCursor(CursorX,CursorBottom);
1345     else
1346     MoveCursor(CursorX,CursorTop+Param[1]-1);
1347     }
1348     else {
1349     if (Param[1] > NumOfLines-StatusLine)
1350     MoveCursor(CursorX,NumOfLines-1-StatusLine);
1351     else
1352     MoveCursor(CursorX,Param[1]-1);
1353     }
1354     }
1355    
1356     void CSMoveToXY()
1357     {
1358     int NewX, NewY;
1359    
1360     if (Param[1]<1) Param[1] = 1;
1361     if ((NParam < 2) || (Param[2]<1)) Param[2] = 1;
1362     NewX = Param[2] - 1;
1363     if (NewX > NumOfColumns-1) NewX = NumOfColumns-1;
1364    
1365     if ((StatusLine>0) && (CursorY==NumOfLines-1))
1366     NewY = CursorY;
1367     else if (RelativeOrgMode)
1368     {
1369     NewY = CursorTop + Param[1] - 1;
1370     if (NewY > CursorBottom) NewY = CursorBottom;
1371     }
1372     else {
1373     NewY = Param[1] - 1;
1374     if (NewY > NumOfLines-1-StatusLine)
1375     NewY = NumOfLines-1-StatusLine;
1376     }
1377     MoveCursor(NewX,NewY);
1378     }
1379    
1380     void CSDeleteTabStop()
1381     {
1382     if (Param[1]==-1) Param[1] = 0;
1383     ClearTabStop(Param[1]);
1384     }
1385    
1386     void CS_h_Mode()
1387     {
1388     switch (Param[1]) {
1389     case 2: KeybEnabled = FALSE; break;
1390     case 4: InsertMode = TRUE; break;
1391     case 12:
1392     ts.LocalEcho = 0;
1393     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1394     TelChangeEcho();
1395     break;
1396     case 20:
1397     LFMode = TRUE;
1398     ts.CRSend = IdCRLF;
1399     cv.CRSend = IdCRLF;
1400     break;
1401     }
1402     }
1403    
1404     void CS_i_Mode()
1405     {
1406     if (Param[1]==-1) Param[1] = 0;
1407     switch (Param[1]) {
1408     /* print screen */
1409     // PrintEX -- TRUE: print screen
1410     // FALSE: scroll region
1411     case 0: BuffPrint(! PrintEX); break;
1412     /* printer controller mode off */
1413     case 4: break; /* See PrnParseCS() */
1414     /* printer controller mode on */
1415     case 5:
1416     if (! AutoPrintMode)
1417     OpenPrnFile();
1418     DirectPrn = (ts.PrnDev[0]!=0);
1419     PrinterMode = TRUE;
1420     break;
1421     }
1422     }
1423    
1424     void CS_l_Mode()
1425     {
1426     switch (Param[1]) {
1427     case 2: KeybEnabled = TRUE; break;
1428     case 4: InsertMode = FALSE; break;
1429     case 12:
1430     ts.LocalEcho = 1;
1431     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1432     TelChangeEcho();
1433     break;
1434     case 20:
1435     LFMode = FALSE;
1436     ts.CRSend = IdCR;
1437     cv.CRSend = IdCR;
1438     break;
1439     }
1440     }
1441    
1442     void CS_n_Mode()
1443     {
1444     char Report[16];
1445     int Y;
1446    
1447     switch (Param[1]) {
1448     case 5:
1449     if (Send8BitMode)
1450     CommBinaryOut(&cv,"\2330n",3); /* Device Status Report -> Ready */
1451     else
1452     CommBinaryOut(&cv,"\033[0n",4); /* Device Status Report -> Ready */
1453     break;
1454     case 6:
1455     /* Cursor Position Report */
1456     Y = CursorY+1;
1457     if ((StatusLine>0) &&
1458     (Y==NumOfLines))
1459     Y = 1;
1460     if (Send8BitMode)
1461     _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "\233%u;%uR", CLocale, Y, CursorX+1);
1462     else
1463     _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "\033[%u;%uR", CLocale, Y, CursorX+1);
1464     CommBinaryOut(&cv,Report,strlen(Report));
1465     break;
1466     }
1467     }
1468    
1469     void CSSetAttr()
1470     {
1471     int i, P;
1472    
1473     UpdateStr();
1474     for (i=1 ; i<=NParam ; i++)
1475     {
1476     P = Param[i];
1477     if (P<0) P = 0;
1478     switch (P) {
1479     case 0: /* Clear all */
1480     CharAttr = DefCharAttr;
1481     BuffSetCurCharAttr(CharAttr);
1482     break;
1483    
1484     case 1: /* Bold */
1485     CharAttr.Attr |= AttrBold;
1486     BuffSetCurCharAttr(CharAttr);
1487     break;
1488    
1489     case 4: /* Under line */
1490     CharAttr.Attr |= AttrUnder;
1491     BuffSetCurCharAttr(CharAttr);
1492     break;
1493    
1494     case 5: /* Blink */
1495     CharAttr.Attr |= AttrBlink;
1496     BuffSetCurCharAttr(CharAttr);
1497     break;
1498    
1499     case 7: /* Reverse */
1500     CharAttr.Attr |= AttrReverse;
1501     BuffSetCurCharAttr(CharAttr);
1502     break;
1503    
1504     case 22: /* Bold off */
1505     CharAttr.Attr &= ~ AttrBold;
1506     BuffSetCurCharAttr(CharAttr);
1507     break;
1508    
1509     case 24: /* Under line off */
1510     CharAttr.Attr &= ~ AttrUnder;
1511     BuffSetCurCharAttr(CharAttr);
1512     break;
1513    
1514     case 25: /* Blink off */
1515     CharAttr.Attr &= ~ AttrBlink;
1516     BuffSetCurCharAttr(CharAttr);
1517     break;
1518    
1519     case 27: /* Reverse off */
1520     CharAttr.Attr &= ~ AttrReverse;
1521     BuffSetCurCharAttr(CharAttr);
1522     break;
1523    
1524     case 30:
1525     case 31:
1526     case 32:
1527     case 33:
1528     case 34:
1529     case 35:
1530     case 36:
1531     case 37: /* text color */
1532     CharAttr.Attr2 |= Attr2Fore;
1533     CharAttr.Fore = P - 30;
1534     BuffSetCurCharAttr(CharAttr);
1535     break;
1536    
1537     case 38: /* text color (256color mode) */
1538     if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1539     i++;
1540     if (i < NParam) {
1541     P = Param[++i];
1542     if (P<0) {
1543     P = 0;
1544     }
1545     CharAttr.Attr2 |= Attr2Fore;
1546     CharAttr.Fore = P;
1547     BuffSetCurCharAttr(CharAttr);
1548     }
1549     }
1550     break;
1551    
1552     case 39: /* Reset text color */
1553     CharAttr.Attr2 &= ~ Attr2Fore;
1554     CharAttr.Fore = AttrDefaultFG;
1555     BuffSetCurCharAttr(CharAttr);
1556     break;
1557    
1558     case 40:
1559     case 41:
1560     case 42:
1561     case 43:
1562     case 44:
1563     case 45:
1564     case 46:
1565     case 47: /* Back color */
1566     CharAttr.Attr2 |= Attr2Back;
1567     CharAttr.Back = P - 40;
1568     BuffSetCurCharAttr(CharAttr);
1569     break;
1570    
1571     case 48: /* Back color (256color mode) */
1572     if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1573     i++;
1574     if (i < NParam) {
1575     P = Param[++i];
1576     if (P<0) {
1577     P = 0;
1578     }
1579     CharAttr.Attr2 |= Attr2Back;
1580     CharAttr.Back = P;
1581     BuffSetCurCharAttr(CharAttr);
1582     }
1583     }
1584     break;
1585    
1586     case 49: /* Reset back color */
1587     CharAttr.Attr2 &= ~ Attr2Back;
1588     CharAttr.Back = AttrDefaultBG;
1589     BuffSetCurCharAttr(CharAttr);
1590     break;
1591    
1592     case 90:
1593     case 91:
1594     case 92:
1595     case 93:
1596     case 94:
1597     case 95:
1598     case 96:
1599     case 97: /* aixterm style text color */
1600     if (ts.ColorFlag & CF_AIXTERM16) {
1601     CharAttr.Attr2 |= Attr2Fore;
1602     CharAttr.Fore = P - 90 + 8;
1603     BuffSetCurCharAttr(CharAttr);
1604     }
1605     break;
1606    
1607     case 100:
1608     if (! (ts.ColorFlag & CF_AIXTERM16)) {
1609     /* Reset text and back color */
1610     CharAttr.Attr2 &= ~ (Attr2Fore | Attr2Back);
1611     CharAttr.Fore = AttrDefaultFG;
1612     CharAttr.Back = AttrDefaultBG;
1613     BuffSetCurCharAttr(CharAttr);
1614     break;
1615     }
1616     /* fall through to aixterm style back color */
1617    
1618     case 101:
1619     case 102:
1620     case 103:
1621     case 104:
1622     case 105:
1623     case 106:
1624     case 107: /* aixterm style back color */
1625     if (ts.ColorFlag & CF_AIXTERM16) {
1626     CharAttr.Attr2 |= Attr2Back;
1627     CharAttr.Back = P - 100 + 8;
1628     BuffSetCurCharAttr(CharAttr);
1629     }
1630     break;
1631     }
1632     }
1633     }
1634    
1635     void CSSetScrollRegion()
1636     {
1637     if ((StatusLine>0) &&
1638     (CursorY==NumOfLines-1))
1639     {
1640     MoveCursor(0,CursorY);
1641     return;
1642     }
1643     if (Param[1]<1) Param[1] =1;
1644     if ((NParam < 2) | (Param[2]<1))
1645     Param[2] = NumOfLines-StatusLine;
1646     Param[1]--;
1647     Param[2]--;
1648     if (Param[1] > NumOfLines-1-StatusLine)
1649     Param[1] = NumOfLines-1-StatusLine;
1650     if (Param[2] > NumOfLines-1-StatusLine)
1651     Param[2] = NumOfLines-1-StatusLine;
1652     if (Param[1] >= Param[2]) return;
1653     CursorTop = Param[1];
1654     CursorBottom = Param[2];
1655     if (RelativeOrgMode) MoveCursor(0,CursorTop);
1656     else MoveCursor(0,0);
1657     }
1658    
1659     void CSSunSequence() /* Sun terminal private sequences */
1660     {
1661     char Report[16];
1662    
1663     switch (Param[1]) {
1664     case 8: /* set terminal size */
1665     if ((Param[2]<=1) || (NParam<2)) Param[2] = 24;
1666     if ((Param[3]<=1) || (NParam<3)) Param[3] = 80;
1667     ChangeTerminalSize(Param[3],Param[2]);
1668     break;
1669     case 14: /* get window size??? */
1670     /* this is not actual window size */
1671     if (Send8BitMode)
1672     CommBinaryOut(&cv,"\2334;640;480t",11);
1673     else
1674     CommBinaryOut(&cv,"\033[4;640;480t",12);
1675     break;
1676     case 18: /* get terminal size */
1677     if (Send8BitMode)
1678     _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "\2338;%u;%u;t", CLocale, NumOfLines-StatusLine, NumOfColumns);
1679     else
1680     _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "\033[8;%u;%u;t", CLocale, NumOfLines-StatusLine, NumOfColumns);
1681     CommBinaryOut(&cv,Report,strlen(Report));
1682     break;
1683     }
1684     }
1685    
1686     void CSGT(BYTE b)
1687     {
1688     switch (b) {
1689     case 'c': /* second terminal report */
1690     if (Send8BitMode)
1691     CommBinaryOut(&cv,"\233>32;10;2c",11); /* VT382 */
1692     else
1693     CommBinaryOut(&cv,"\033[>32;10;2c",11); /* VT382 */
1694     break;
1695     case 'J':
1696     if (Param[1]==3) // IO-8256 terminal
1697     {
1698     if (Param[2]<1) Param[2]=1;
1699     if (Param[3]<1) Param[3]=1;
1700     if (Param[4]<1) Param[4]=1;
1701     if (Param[5]<1) Param[5]=1;
1702     BuffEraseBox(Param[3]-1,Param[2]-1,
1703     Param[5]-1,Param[4]-1);
1704     }
1705     break;
1706     case 'K':
1707     if ((NParam>=2) && (Param[1]==5))
1708     { // IO-8256 terminal
1709     switch (Param[2]) {
1710     case 3:
1711     case 4:
1712     case 5:
1713     case 6:
1714     BuffDrawLine(CharAttr, Param[2], Param[3]);
1715     break;
1716     case 12:
1717     /* Text color */
1718     if ((Param[3]>=0) && (Param[3]<=7))
1719     {
1720     switch (Param[3]) {
1721     case 3: CharAttr.Fore = IdBlue; break;
1722     case 4: CharAttr.Fore = IdCyan; break;
1723     case 5: CharAttr.Fore = IdYellow; break;
1724     case 6: CharAttr.Fore = IdMagenta; break;
1725     default: CharAttr.Fore = Param[3]; break;
1726     }
1727     CharAttr.Attr2 |= Attr2Fore;
1728     BuffSetCurCharAttr(CharAttr);
1729     }
1730     break;
1731     }
1732     }
1733     else if (Param[1]==3)
1734     {// IO-8256 terminal
1735     if (Param[2]<1) Param[2] = 1;
1736     if (Param[3]<1) Param[2] = 1;
1737     BuffEraseCharsInLine(Param[2]-1,Param[3]-Param[2]+1);
1738     }
1739     break;
1740     }
1741     }
1742    
1743     void CSQExchangeColor()
1744     {
1745     COLORREF ColorRef;
1746    
1747     BuffUpdateScroll();
1748    
1749     ColorRef = ts.VTColor[0];
1750     ts.VTColor[0] = ts.VTColor[1];
1751     ts.VTColor[1] = ColorRef;
1752     #ifdef ALPHABLEND_TYPE2
1753     BGInitialize();
1754     #endif
1755     DispChangeBackground();
1756     }
1757    
1758     void CSQ_h_Mode()
1759     {
1760     int i;
1761    
1762     for (i = 1 ; i<=NParam ; i++)
1763     switch (Param[i]) {
1764     case 1: AppliCursorMode = TRUE; break;
1765     case 3:
1766     ChangeTerminalSize(132,NumOfLines-StatusLine);
1767     break;
1768     case 5:
1769     if (ReverseColor) return;
1770     ReverseColor = TRUE;
1771     /* Exchange text/back color */
1772     CSQExchangeColor();
1773     break;
1774     case 6:
1775     if ((StatusLine>0) &&
1776     (CursorY==NumOfLines-1))
1777     MoveCursor(0,CursorY);
1778     else {
1779     RelativeOrgMode = TRUE;
1780     MoveCursor(0,CursorTop);
1781     }
1782     break;
1783     case 7: AutoWrapMode = TRUE; break;
1784     case 8: AutoRepeatMode = TRUE; break;
1785     case 9:
1786     if (ts.MouseEventTracking)
1787     MouseReportMode = IdMouseTrackX10;
1788     break;
1789     case 19: PrintEX = TRUE; break;
1790     case 25: DispEnableCaret(TRUE); break; // cursor on
1791     case 38:
1792     if (ts.AutoWinSwitch>0)
1793     ChangeEmu = IdTEK; /* Enter TEK Mode */
1794     break;
1795     case 59:
1796     if (ts.Language==IdJapanese)
1797     { /* kanji terminal */
1798     Gn[0] = IdASCII;
1799     Gn[1] = IdKatakana;
1800     Gn[2] = IdKatakana;
1801     Gn[3] = IdKanji;
1802     Glr[0] = 0;
1803     if ((ts.KanjiCode==IdJIS) &&
1804     (ts.JIS7Katakana==0))
1805     Glr[1] = 2; // 8-bit katakana
1806     else
1807     Glr[1] = 3;
1808     }
1809     break;
1810     case 66: AppliKeyMode = TRUE; break;
1811     case 67: ts.BSKey = IdBS; break;
1812     case 1000:
1813     if (ts.MouseEventTracking)
1814     MouseReportMode = IdMouseTrackVT200;
1815     break;
1816     case 1001:
1817     if (ts.MouseEventTracking)
1818     MouseReportMode = IdMouseTrackVT200Hl;
1819     break;
1820     case 1002:
1821     if (ts.MouseEventTracking)
1822     MouseReportMode = IdMouseTrackBtnEvent;
1823     break;
1824     case 1003:
1825     if (ts.MouseEventTracking)
1826     MouseReportMode = IdMouseTrackAllEvent;
1827     break;
1828     case 1004:
1829     if (ts.MouseEventTracking)
1830     FocusReportMode = TRUE;
1831     break;
1832     }
1833     }
1834    
1835     void CSQ_i_Mode()
1836     {
1837     if (Param[1]==-1) Param[1] = 0;
1838     switch (Param[1]) {
1839     case 1:
1840     OpenPrnFile();
1841     BuffDumpCurrentLine(LF);
1842     if (! AutoPrintMode)
1843     ClosePrnFile();
1844     break;
1845     /* auto print mode off */
1846     case 4:
1847     if (AutoPrintMode)
1848     {
1849     ClosePrnFile();
1850     AutoPrintMode = FALSE;
1851     }
1852     break;
1853     /* auto print mode on */
1854     case 5:
1855     if (! AutoPrintMode)
1856     {
1857     OpenPrnFile();
1858     AutoPrintMode = TRUE;
1859     }
1860     break;
1861     }
1862     }
1863    
1864     void CSQ_l_Mode()
1865     {
1866     int i;
1867    
1868     for (i = 1 ; i <= NParam ; i++)
1869     switch (Param[i]) {
1870     case 1: AppliCursorMode = FALSE; break;
1871     case 3:
1872     ChangeTerminalSize(80,NumOfLines-StatusLine);
1873     break;
1874     case 5:
1875     if (! ReverseColor) return;
1876     ReverseColor = FALSE;
1877     /* Exchange text/back color */
1878     CSQExchangeColor();
1879     break;
1880     case 6:
1881     if ((StatusLine>0) &&
1882     (CursorY==NumOfLines-1))
1883     MoveCursor(0,CursorY);
1884     else {
1885     RelativeOrgMode = FALSE;
1886     MoveCursor(0,0);
1887     }
1888     break;
1889     case 7: AutoWrapMode = FALSE; break;
1890     case 8: AutoRepeatMode = FALSE; break;
1891     case 9: MouseReportMode = IdMouseTrackNone; break;
1892     case 19: PrintEX = FALSE; break;
1893     case 25: DispEnableCaret(FALSE); break; // cursor off
1894     case 59:
1895     if (ts.Language==IdJapanese)
1896     { /* katakana terminal */
1897     Gn[0] = IdASCII;
1898     Gn[1] = IdKatakana;
1899     Gn[2] = IdKatakana;
1900     Gn[3] = IdKanji;
1901     Glr[0] = 0;
1902     if ((ts.KanjiCode==IdJIS) &&
1903     (ts.JIS7Katakana==0))
1904     Glr[1] = 2; // 8-bit katakana
1905     else
1906     Glr[1] = 3;
1907     }
1908     break;
1909     case 66: AppliKeyMode = FALSE; break;
1910     case 67: ts.BSKey = IdDEL; break;
1911     case 1000:
1912     case 1001:
1913     case 1002:
1914     case 1003: MouseReportMode = IdMouseTrackNone; break;
1915     case 1004: FocusReportMode = FALSE; break;
1916     }
1917     }
1918    
1919     void CSQ_n_Mode()
1920     {
1921     }
1922    
1923     void CSQuest(BYTE b)
1924     {
1925     switch (b) {
1926     case 'K': CSLineErase(); break;
1927     case 'h': CSQ_h_Mode(); break;
1928     case 'i': CSQ_i_Mode(); break;
1929     case 'l': CSQ_l_Mode(); break;
1930     case 'n': CSQ_n_Mode(); break;
1931     }
1932     }
1933    
1934     void SoftReset()
1935     // called by software-reset escape sequence handler
1936     {
1937     UpdateStr();
1938     AutoRepeatMode = TRUE;
1939     DispEnableCaret(TRUE); // cursor on
1940     InsertMode = FALSE;
1941     RelativeOrgMode = FALSE;
1942     AppliKeyMode = FALSE;
1943     AppliCursorMode = FALSE;
1944     if ((StatusLine>0) &&
1945     (CursorY == NumOfLines-1))
1946     MoveToMainScreen();
1947     CursorTop = 0;
1948     CursorBottom = NumOfLines-1-StatusLine;
1949     ResetCharSet();
1950    
1951     Send8BitMode = ts.Send8BitCtrl;
1952    
1953     /* Attribute */
1954     CharAttr = DefCharAttr;
1955     Special = FALSE;
1956     BuffSetCurCharAttr(CharAttr);
1957    
1958     // status buffers
1959     ResetSBuffers();
1960     }
1961    
1962     void CSExc(BYTE b)
1963     {
1964     switch (b) {
1965     case 'p':
1966     /* Software reset */
1967     SoftReset();
1968     break;
1969     }
1970     }
1971    
1972     void CSDouble(BYTE b)
1973     {
1974     switch (b) {
1975     case 'p':
1976     /* Select terminal mode (software reset) */
1977     SoftReset();
1978     if (NParam > 0) {
1979     switch (Param[1]) {
1980     case 61: // VT100 Mode
1981     Send8BitMode = FALSE; break;
1982     case 62: // VT200 Mode
1983     case 63: // VT300 Mode
1984     case 64: // VT400 Mode
1985     if (NParam > 1 && Param[2] == 1)
1986     Send8BitMode = FALSE;
1987     else
1988     Send8BitMode = TRUE;
1989     break;
1990     }
1991     }
1992     break;
1993     }
1994     }
1995    
1996     void CSDol(BYTE b)
1997     {
1998     switch (b) {
1999     case '}':
2000     if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2001     if (StatusLine==0) return;
2002     if ((Param[1]<1) && (CursorY==NumOfLines-1))
2003     MoveToMainScreen();
2004     else if ((Param[1]==1) && (CursorY<NumOfLines-1))
2005     MoveToStatusLine();
2006     break;
2007     case '~':
2008     if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2009     if (Param[1]<=1)
2010     HideStatusLine();
2011     else if ((StatusLine==0) && (Param[1]==2))
2012     ShowStatusLine(1); // show
2013     break;
2014     }
2015     }
2016    
2017     void PrnParseCS(BYTE b) // printer mode
2018     {
2019     ParseMode = ModeFirst;
2020     switch (ICount) {
2021     /* no intermediate char */
2022     case 0:
2023     switch (Prv) {
2024     /* no private parameter */
2025     case 0:
2026     switch (b) {
2027     case 'i':
2028     if (Param[1]==4)
2029     {
2030     PrinterMode = FALSE;
2031     // clear prn buff
2032     WriteToPrnFile(0,FALSE);
2033     if (! AutoPrintMode)
2034     ClosePrnFile();
2035     return;
2036     }
2037     break;
2038     } /* of case Prv=0 */
2039     break;
2040     }
2041     break;
2042     /* one intermediate char */
2043     case 1: break;
2044     } /* of case Icount */
2045    
2046     WriteToPrnFile(b,TRUE);
2047     }
2048    
2049     void ParseCS(BYTE b) /* b is the final char */
2050     {
2051     if (PrinterMode) { // printer mode
2052     PrnParseCS(b);
2053     return;
2054     }
2055    
2056     switch (ICount) {
2057     /* no intermediate char */
2058     case 0:
2059     switch (Prv) {
2060     /* no private parameter */
2061     case 0:
2062     switch (b) {
2063     case '@': CSInsertCharacter(); break;
2064     case 'A': CSCursorUp(); break;
2065     case 'B': CSCursorDown(); break;
2066     case 'C': CSCursorRight(); break;
2067     case 'D': CSCursorLeft(); break;
2068     case 'E': CSCursorDown1(); break;
2069     case 'F': CSCursorUp1(); break;
2070     case 'G': CSMoveToColumnN(); break;
2071     case 'H': CSMoveToXY(); break;
2072     case 'J': CSScreenErase(); break;
2073     case 'K': CSLineErase(); break;
2074     case 'L': CSInsertLine(); break;
2075     case 'M': CSDeleteNLines(); break;
2076     case 'P': CSDeleteCharacter(); break;
2077     case 'S': CSScrollUP(); break; // SU
2078     case 'T': CSScrollDown(); break; // SD
2079     case 'X': CSEraseCharacter(); break;
2080     case '`': CSMoveToColumnN(); break;
2081     case 'a': CSCursorRight(); break;
2082     case 'c': AnswerTerminalType(); break;
2083     case 'd': CSMoveToLineN(); break;
2084     case 'e': CSCursorUp(); break;
2085     case 'f': CSMoveToXY(); break;
2086     case 'g': CSDeleteTabStop(); break;
2087     case 'h': CS_h_Mode(); break;
2088     case 'i': CS_i_Mode(); break;
2089     case 'l': CS_l_Mode(); break;
2090     case 'm': CSSetAttr(); break;
2091     case 'n': CS_n_Mode(); break;
2092     case 'r': CSSetScrollRegion(); break;
2093     case 's': SaveCursor(); break;
2094     case 't': CSSunSequence(); break;
2095     case 'u': RestoreCursor(); break;
2096     } /* of case Prv=0 */
2097     break;
2098     /* private parameter = '>' */
2099     case '>': CSGT(b); break;
2100     /* private parameter = '?' */
2101     case '?': CSQuest(b); break;
2102     }
2103     break;
2104     /* one intermediate char */
2105     case 1:
2106     switch (IntChar[1]) {
2107     /* intermediate char = '!' */
2108     case '!': CSExc(b); break;
2109     /* intermediate char = '"' */
2110     case '"': CSDouble(b); break;
2111     /* intermediate char = '$' */
2112     case '$': CSDol(b); break;
2113     }
2114     break;
2115     } /* of case Icount */
2116    
2117     ParseMode = ModeFirst;
2118     }
2119    
2120     void ControlSequence(BYTE b)
2121     {
2122     if ((b<=US) || (b>=0x80) && (b<=0x9F))
2123     ParseControl(b); /* ctrl char */
2124     else if ((b>=0x40) && (b<=0x7E))
2125     ParseCS(b); /* terminate char */
2126     else {
2127     if (PrinterMode)
2128     WriteToPrnFile(b,FALSE);
2129    
2130     if ((b>=0x20) && (b<=0x2F))
2131     { /* intermediate char */
2132     if (ICount<IntCharMax) ICount++;
2133     IntChar[ICount] = b;
2134     }
2135     else if ((b>=0x30) && (b<=0x39))
2136     {
2137     if (Param[NParam] < 0)
2138     Param[NParam] = 0;
2139     if (Param[NParam]<1000)
2140     Param[NParam] = Param[NParam]*10 + b - 0x30;
2141     }
2142     else if (b==0x3B)
2143     {
2144     if (NParam < NParamMax)
2145     {
2146     NParam++;
2147     Param[NParam] = -1;
2148     }
2149     }
2150     else if ((b>=0x3C) && (b<=0x3F))
2151     { /* private char */
2152     if (FirstPrm) Prv = b;
2153     }
2154     }
2155     FirstPrm = FALSE;
2156     }
2157    
2158     void DeviceControl(BYTE b)
2159     {
2160     if (ESCFlag && (b=='\\') || (b==ST))
2161     {
2162     ESCFlag = FALSE;
2163     ParseMode = SavedMode;
2164     return;
2165     }
2166    
2167     if (b==ESC)
2168     {
2169     ESCFlag = TRUE;
2170     return;
2171     }
2172     else ESCFlag = FALSE;
2173    
2174     if (b<US)
2175     ParseControl(b);
2176     else if ((b>=0x30) && (b<=0x39))
2177     {
2178     if (Param[NParam] < 0) Param[NParam] = 0;
2179     if (Param[NParam]<1000)
2180     Param[NParam] = Param[NParam]*10 + b - 0x30;
2181     }
2182     else if (b==0x3B)
2183     {
2184     if (NParam < NParamMax)
2185     {
2186     NParam++;
2187     Param[NParam] = -1;
2188     }
2189     }
2190     else if ((b>=0x40) && (b<=0x7E))
2191     {
2192     if (b=='|')
2193     {
2194     ParseMode = ModeDCUserKey;
2195     if (Param[1] < 1) ClearUserKey();
2196     WaitKeyId = TRUE;
2197     NewKeyId = 0;
2198     }
2199     else ParseMode = ModeSOS;
2200     }
2201     }
2202    
2203     void DCUserKey(BYTE b)
2204     {
2205     if (ESCFlag && (b=='\\') || (b==ST))
2206     {
2207     if (! WaitKeyId) DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
2208     ESCFlag = FALSE;
2209     ParseMode = SavedMode;
2210     return;
2211     }
2212    
2213     if (b==ESC)
2214     {
2215     ESCFlag = TRUE;
2216     return;
2217     }
2218     else ESCFlag = FALSE;
2219    
2220     if (WaitKeyId)
2221     {
2222     if ((b>=0x30) && (b<=0x39))
2223     {
2224     if (NewKeyId<1000)
2225     NewKeyId = NewKeyId*10 + b - 0x30;
2226     }
2227     else if (b==0x2F)
2228     {
2229     WaitKeyId = FALSE;
2230     WaitHi = TRUE;
2231     NewKeyLen = 0;
2232     }
2233     }
2234     else {
2235     if (b==0x3B)
2236     {
2237     DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
2238     WaitKeyId = TRUE;
2239     NewKeyId = 0;
2240     }
2241     else {
2242     if (NewKeyLen < FuncKeyStrMax)
2243     {
2244     if (WaitHi)
2245     {
2246     NewKeyStr[NewKeyLen] = ConvHexChar(b) << 4;
2247     WaitHi = FALSE;
2248     }
2249     else {
2250     NewKeyStr[NewKeyLen] = NewKeyStr[NewKeyLen] +
2251     ConvHexChar(b);
2252     WaitHi = TRUE;
2253     NewKeyLen++;
2254     }
2255     }
2256     }
2257     }
2258     }
2259    
2260     void IgnoreString(BYTE b)
2261     {
2262     if (ESCFlag && (b=='\\') || (b==ST))
2263     ParseMode = SavedMode;
2264    
2265     if (b==ESC) ESCFlag = TRUE;
2266     else ESCFlag = FALSE;
2267     }
2268    
2269     BOOL XsParseColor(char *colspec, COLORREF *color)
2270     {
2271     int r, g, b;
2272     // double dr, dg, db;
2273    
2274     r = g = b = 255;
2275    
2276     if (colspec == NULL || color == NULL) {
2277     return FALSE;
2278     }
2279    
2280     if (_strnicmp(colspec, "rgb:", 4) == 0) {
2281     switch (strlen(colspec)) {
2282     case 9: // rgb:R/G/B
2283     if (sscanf(colspec, "rgb:%1x/%1x/%1x", &r, &g, &b) != 3) {
2284     return FALSE;
2285     }
2286     r *= 17; g *= 17; b *= 17;
2287     break;
2288     case 12: // rgb:RR/GG/BB
2289     if (sscanf(colspec, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) {
2290     return FALSE;
2291     }
2292     break;
2293     case 15: // rgb:RRR/GGG/BBB
2294     if (sscanf(colspec, "rgb:%3x/%3x/%3x", &r, &g, &b) != 3) {
2295     return FALSE;
2296     }
2297     r >>= 4; g >>= 4; b >>= 4;
2298     break;
2299     case 18: // rgb:RRRR/GGGG/BBBB
2300     if (sscanf(colspec, "rgb:%4x/%4x/%4x", &r, &g, &b) != 3) {
2301     return FALSE;
2302     }
2303     r >>= 8; g >>= 8; b >>= 8;
2304     break;
2305     default:
2306     return FALSE;
2307     }
2308     }
2309     //else if (_strnicmp(colspec, "rgbi:", 5) == 0) {
2310     //}
2311     else if (colspec[0] == '#') {
2312     switch (strlen(colspec)) {
2313     case 4: // #RGB
2314     if (sscanf(colspec, "#%1x%1x%1x", &r, &g, &b) != 3) {
2315     return FALSE;
2316     }
2317     r <<= 4; g <<= 4; b <<= 4;
2318     break;
2319     case 7: // #RGB
2320     if (sscanf(colspec, "#%2x%2x%2x", &r, &g, &b) != 3) {
2321     return FALSE;
2322     }
2323     break;
2324     case 10: // #RGB
2325     if (sscanf(colspec, "#%3x%3x%3x", &r, &g, &b) != 3) {
2326     return FALSE;
2327     }
2328     r >>= 4; g >>= 4; b >>= 4;
2329     break;
2330     case 13: // #RGB
2331     if (sscanf(colspec, "#%4x%4x%4x", &r, &g, &b) != 3) {
2332     return FALSE;
2333     }
2334     r >>= 8; g >>= 8; b >>= 8;
2335     break;
2336     default:
2337     return FALSE;
2338     }
2339     }
2340     else {
2341     return FALSE;
2342     }
2343    
2344     if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
2345     return FALSE;
2346     }
2347    
2348     *color = RGB(r, g, b);
2349     return TRUE;
2350     }
2351    
2352     #define ModeXsFirst 1
2353     #define ModeXsString 2
2354     #define ModeXsColorNum 3
2355     #define ModeXsColorSpec 4
2356     #define ModeXsEsc 5
2357     void XSequence(BYTE b)
2358     {
2359     static BYTE XsParseMode = ModeXsFirst, PrevMode;
2360     static char StrBuff[sizeof(ts.Title)];
2361     static int ColorNumber, StrLen;
2362     COLORREF color;
2363    
2364     switch (XsParseMode) {
2365     case ModeXsFirst:
2366     if (isdigit(b)) {
2367     if (Param[1] < 1000) {
2368     Param[1] = Param[1]*10 + b - '0';
2369     }
2370     }
2371     else if (b == ';') {
2372     StrBuff[0] = '\0';
2373     StrLen = 0;
2374     if (Param[1] == 4) {
2375     ColorNumber = 0;
2376     XsParseMode = ModeXsColorNum;
2377     }
2378     else {
2379     XsParseMode = ModeXsString;
2380     }
2381     }
2382     else {
2383     ParseMode = ModeFirst;
2384     }
2385     break;
2386     case ModeXsString:
2387     if (b == ST || b == '\a') { /* String Terminator */
2388     StrBuff[StrLen] = '\0';
2389     switch (Param[1]) {
2390     case 0: /* Change window title and icon name */
2391     case 1: /* Change icon name */
2392     case 2: /* Change window title */
2393     strncpy_s(ts.Title, sizeof(ts.Title), StrBuff, _TRUNCATE);
2394     // (2006.6.15 maya) �^�C�g�����n����������SJIS������
2395     ConvertToCP932(ts.Title, sizeof(ts.Title));
2396     ChangeTitle();
2397     break;
2398     default:
2399     /* nothing to do */;
2400     }
2401     ParseMode = ModeFirst;
2402     XsParseMode = ModeXsFirst;
2403     }
2404     else if (b == ESC) { /* Escape */
2405     PrevMode = ModeXsString;
2406     XsParseMode = ModeXsEsc;
2407     }
2408     else if (b <= US) { /* Other control character -- invalid sequence */
2409     ParseMode = ModeFirst;
2410     XsParseMode = ModeXsFirst;
2411     }
2412     else if (StrLen < sizeof(StrBuff) - 1) {
2413     StrBuff[StrLen++] = b;
2414     }
2415     break;
2416     case ModeXsColorNum:
2417     if (isdigit(b)) {
2418     ColorNumber = ColorNumber*10 + b - '0';
2419     }
2420     else if (b == ';') {
2421     XsParseMode = ModeXsColorSpec;
2422     StrBuff[0] = '\0';
2423     StrLen = 0;
2424     }
2425     else {
2426     ParseMode = ModeFirst;
2427     XsParseMode = ModeXsFirst;
2428     }
2429     break;
2430     case ModeXsColorSpec:
2431     if (b == ST || b == '\a') { /* String Terminator */
2432     StrBuff[StrLen] = '\0';
2433     if ((ts.ColorFlag & CF_XTERM256) && ColorNumber >= 0 && ColorNumber <= 255) {
2434     if (strcmp(StrBuff, "?") == 0) {
2435     color = DispGetANSIColor(ColorNumber);
2436     if (Send8BitMode) {
2437     _snprintf_s_l(StrBuff, sizeof(StrBuff), _TRUNCATE,
2438     "\2354;%d;rgb:%02x/%02x/%02x\234", CLocale,
2439     ColorNumber, GetRValue(color), GetGValue(color), GetBValue(color));
2440     }
2441     else {
2442     _snprintf_s_l(StrBuff, sizeof(StrBuff), _TRUNCATE,
2443     "\033]4;%d;rgb:%02x/%02x/%02x\033\\", CLocale,
2444     ColorNumber, GetRValue(color), GetGValue(color), GetBValue(color));
2445     }
2446     ParseMode = ModeFirst;
2447     XsParseMode = ModeXsFirst;
2448     CommBinaryOut(&cv, StrBuff, strlen(StrBuff));
2449     break;
2450     }
2451     else if (XsParseColor(StrBuff, &color)) {
2452     DispSetANSIColor(ColorNumber, color);
2453     }
2454     }
2455     ParseMode = ModeFirst;
2456     XsParseMode = ModeXsFirst;
2457     }
2458     else if (b == ESC) {
2459     PrevMode = ModeXsColorSpec;
2460     XsParseMode = ModeXsEsc;
2461     }
2462     else if (b <= US) { /* Other control character -- invalid sequence */
2463     ParseMode = ModeFirst;
2464     XsParseMode = ModeXsFirst;
2465     }
2466     else if (b == ';') {
2467     if ((ts.ColorFlag & CF_XTERM256) && ColorNumber >= 0 && ColorNumber <= 255) {
2468     if (strcmp(StrBuff, "?") == 0) {
2469     color = DispGetANSIColor(ColorNumber);
2470     if (Send8BitMode) {
2471     _snprintf_s_l(StrBuff, sizeof(StrBuff), _TRUNCATE,
2472     "\2354;%d;rgb:%02x/%02x/%02x\234", CLocale,
2473     ColorNumber, GetRValue(color), GetGValue(color), GetBValue(color));
2474     }
2475     else {
2476     _snprintf_s_l(StrBuff, sizeof(StrBuff), _TRUNCATE,
2477     "\033]4;%d;rgb:%02x/%02x/%02x\033\\", CLocale,
2478     ColorNumber, GetRValue(color), GetGValue(color), GetBValue(color));
2479     }
2480     XsParseMode = ModeXsColorNum;
2481     CommBinaryOut(&cv, StrBuff, strlen(StrBuff));
2482     }
2483     else if (XsParseColor(StrBuff, &color)) {
2484     DispSetANSIColor(ColorNumber, color);
2485     }
2486     }
2487     ColorNumber = 0;
2488     StrBuff[0] = '\0';
2489     StrLen = 0;
2490     XsParseMode = ModeXsColorNum;
2491     }
2492     else if (StrLen < sizeof(StrBuff) - 1) {
2493     StrBuff[StrLen++] = b;
2494     }
2495     break;
2496     case ModeXsEsc:
2497     if (b == '\\') { /* String Terminator */
2498     XsParseMode = PrevMode;
2499     XSequence(ST);
2500     }
2501     else { /* Other character -- invalid sequence */
2502     ParseMode = ModeFirst;
2503     XsParseMode = ModeXsFirst;
2504     }
2505     break;
2506     // default:
2507     // ParseMode = ModeFirst;
2508     // XsParseMode = ModeXsFirst;
2509     }
2510     }
2511    
2512     void DLESeen(BYTE b)
2513     {
2514     ParseMode = ModeFirst;
2515     if (((ts.FTFlag & FT_BPAUTO)!=0) && (b=='B'))
2516     BPStart(IdBPAuto); /* Auto B-Plus activation */
2517     ChangeEmu = -1;
2518     }
2519    
2520     void CANSeen(BYTE b)
2521     {
2522     ParseMode = ModeFirst;
2523     if (((ts.FTFlag & FT_ZAUTO)!=0) && (b=='B'))
2524     ZMODEMStart(IdZAuto); /* Auto ZMODEM activation */
2525     ChangeEmu = -1;
2526     }
2527    
2528     BOOL CheckKanji(BYTE b)
2529     {
2530     BOOL Check;
2531    
2532     if (ts.Language!=IdJapanese) return FALSE;
2533    
2534     ConvJIS = FALSE;
2535    
2536     if (ts.KanjiCode==IdSJIS)
2537     {
2538     if ((0x80<b) && (b<0xa0) || (0xdf<b) && (b<0xfd))
2539     return TRUE; // SJIS kanji
2540     if ((0xa1<=b) && (b<=0xdf))
2541     return FALSE; // SJIS katakana
2542     }
2543    
2544     if ((b>=0x21) && (b<=0x7e))
2545     {
2546     Check = (Gn[Glr[0]]==IdKanji);
2547     ConvJIS = Check;
2548     }
2549     else if ((b>=0xA1) && (b<=0xFE))
2550     {
2551     Check = (Gn[Glr[1]]==IdKanji);
2552     if (ts.KanjiCode==IdEUC)
2553     Check = TRUE;
2554     else if (ts.KanjiCode==IdJIS)
2555     {
2556     if (((ts.TermFlag & TF_FIXEDJIS)!=0) &&
2557     (ts.JIS7Katakana==0))
2558     Check = FALSE; // 8-bit katakana
2559     }
2560     ConvJIS = Check;
2561     }
2562     else
2563     Check = FALSE;
2564    
2565     return Check;
2566     }
2567    
2568     BOOL ParseFirstJP(BYTE b)
2569     // returns TRUE if b is processed
2570     // (actually allways returns TRUE)
2571     {
2572     if (KanjiIn)
2573     {
2574     if ((! ConvJIS) && (0x3F<b) && (b<0xFD) ||
2575     ConvJIS && ( (0x20<b) && (b<0x7f) ||
2576     (0xa0<b) && (b<0xff) ))
2577     {
2578     PutKanji(b);
2579     KanjiIn = FALSE;
2580     return TRUE;
2581     }
2582     else if ((ts.TermFlag & TF_CTRLINKANJI)==0)
2583     KanjiIn = FALSE;
2584     else if ((b==CR) && Wrap) {
2585     CarriageReturn(FALSE);
2586     LineFeed(LF,FALSE);
2587     Wrap = FALSE;
2588     }
2589     }
2590    
2591     if (SSflag)
2592     {
2593     if (Gn[GLtmp] == IdKanji)
2594     {
2595     Kanji = b << 8;
2596     KanjiIn = TRUE;
2597     SSflag = FALSE;
2598     return TRUE;
2599     }
2600     else if (Gn[GLtmp] == IdKatakana) b = b | 0x80;
2601    
2602     PutChar(b);
2603     SSflag = FALSE;
2604     return TRUE;
2605     }
2606    
2607     if ((! EUCsupIn) && (! EUCkanaIn) &&
2608     (! KanjiIn) && CheckKanji(b))
2609     {
2610     Kanji = b << 8;
2611     KanjiIn = TRUE;
2612     return TRUE;
2613     }
2614    
2615     if (b<=US)
2616     ParseControl(b);
2617     else if (b==0x20)
2618     PutChar(b);
2619     else if ((b>=0x21