Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4275 - (show annotations) (download) (as text)
Tue Jan 11 17:34:29 2011 UTC (13 years, 3 months ago) by doda
File MIME type: text/x-csrc
File size: 99998 byte(s)
対応していない OSC シーケンスを正しく無視できていない場合があったのを修正。

1 /* 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 #include <ctype.h>
14
15 #include "buffer.h"
16 #include "ttwinman.h"
17 #include "ttcommon.h"
18 #include "commlib.h"
19 #include "vtdisp.h"
20 #include "keyboard.h"
21 #include "ttlib.h"
22 #include "ttftypes.h"
23 #include "filesys.h"
24 #include "teraprn.h"
25 #include "telnet.h"
26
27 #include "vtterm.h"
28
29 void ParseFirst(BYTE b);
30
31 #define MAPSIZE(x) (sizeof(x)/sizeof((x)[0]))
32 #define Accept8BitCtrl ((VTlevel >= 2) && (ts.TermFlag & TF_ACCEPT8BITCTRL))
33
34 /* Parsing modes */
35 #define ModeFirst 0
36 #define ModeESC 1
37 #define ModeDCS 2
38 #define ModeDCUserKey 3
39 #define ModeSOS 4
40 #define ModeCSI 5
41 #define ModeXS 6
42 #define ModeDLE 7
43 #define ModeCAN 8
44
45 #define NParamMax 16
46 #define IntCharMax 5
47
48 /* DEC Locator Flag */
49 #define DecLocatorOneShot 1
50 #define DecLocatorPixel 2
51 #define DecLocatorButtonDown 4
52 #define DecLocatorButtonUp 8
53 #define DecLocatorFiltered 16
54
55 void VisualBell();
56 BOOL DecLocatorReport(int Event, int Button);
57
58 /* character attribute */
59 static TCharAttr CharAttr;
60
61 /* various modes of VT emulation */
62 static BOOL RelativeOrgMode;
63 static BOOL InsertMode;
64 static BOOL LFMode;
65 static BOOL AutoWrapMode;
66 static BOOL FocusReportMode;
67 static BOOL AltScr;
68 BOOL BracketedPaste;
69
70 static int VTlevel;
71
72 // save/restore cursor
73 typedef struct {
74 int CursorX, CursorY;
75 TCharAttr Attr;
76 int Glr[2], Gn[4]; // G0-G3, GL & GR
77 BOOL AutoWrapMode;
78 BOOL RelativeOrgMode;
79 } TStatusBuff;
80 typedef TStatusBuff *PStatusBuff;
81
82 // status buffer for main screen & status line
83 static TStatusBuff SBuff1, SBuff2, SBuff3;
84
85 static BOOL ESCFlag, JustAfterESC;
86 static BOOL KanjiIn;
87 static BOOL EUCkanaIn, EUCsupIn;
88 static int EUCcount;
89 static BOOL Special;
90
91 static int Param[NParamMax+1];
92 static int NParam;
93 static BOOL FirstPrm;
94 static BYTE IntChar[IntCharMax+1];
95 static int ICount;
96 static BYTE Prv;
97 static int ParseMode, SavedMode;
98 static int ChangeEmu;
99
100 /* user defined keys */
101 static BOOL WaitKeyId, WaitHi;
102
103 /* GL, GR code group */
104 static int Glr[2];
105 /* G0, G1, G2, G3 code group */
106 static int Gn[4];
107 /* GL for single shift 2/3 */
108 static int GLtmp;
109 /* single shift 2/3 flag */
110 static BOOL SSflag;
111 /* JIS -> SJIS conversion flag */
112 static BOOL ConvJIS;
113 static WORD Kanji;
114
115 // variables for status line mode
116 static int StatusX=0;
117 static BOOL StatusWrap=FALSE;
118 static BOOL StatusCursor=TRUE;
119 static int MainX, MainY; //cursor registers
120 static int MainTop, MainBottom; // scroll region registers
121 static BOOL MainWrap;
122 static BOOL MainCursor=TRUE;
123
124 /* status for printer escape sequences */
125 static BOOL PrintEX = TRUE; // printing extent
126 // (TRUE: screen, FALSE: scroll region)
127 static BOOL AutoPrintMode = FALSE;
128 static BOOL PrinterMode = FALSE;
129 static BOOL DirectPrn = FALSE;
130
131 /* User key */
132 static BYTE NewKeyStr[FuncKeyStrMax];
133 static int NewKeyId, NewKeyLen;
134
135 /* Mouse Report */
136 int MouseReportMode;
137 unsigned int DecLocatorFlag;
138 int LastX, LastY;
139 int ButtonStat;
140 int FilterTop, FilterBottom, FilterLeft, FilterRight;
141
142 static _locale_t CLocale = NULL;
143
144 void ResetSBuffer(PStatusBuff sbuff)
145 {
146 sbuff->CursorX = 0;
147 sbuff->CursorY = 0;
148 sbuff->Attr = DefCharAttr;
149 if (ts.Language==IdJapanese)
150 {
151 sbuff->Gn[0] = IdASCII;
152 sbuff->Gn[1] = IdKatakana;
153 sbuff->Gn[2] = IdKatakana;
154 sbuff->Gn[3] = IdKanji;
155 sbuff->Glr[0] = 0;
156 if ((ts.KanjiCode==IdJIS) &&
157 (ts.JIS7Katakana==0))
158 sbuff->Glr[1] = 2; // 8-bit katakana
159 else
160 sbuff->Glr[1] = 3;
161 }
162 else {
163 sbuff->Gn[0] = IdASCII;
164 sbuff->Gn[1] = IdSpecial;
165 sbuff->Gn[2] = IdASCII;
166 sbuff->Gn[3] = IdASCII;
167 sbuff->Glr[0] = 0;
168 sbuff->Glr[1] = 0;
169 }
170 sbuff->AutoWrapMode = TRUE;
171 sbuff->RelativeOrgMode = FALSE;
172 }
173
174 void ResetAllSBuffers()
175 {
176 ResetSBuffer(&SBuff1);
177 // copy SBuff1 to SBuff2
178 SBuff2 = SBuff1;
179 SBuff3 = SBuff1;
180 }
181
182 void ResetCurSBuffer()
183 {
184 PStatusBuff Buff;
185
186 if (AltScr) {
187 Buff = &SBuff3; // Alternate screen buffer
188 }
189 else {
190 Buff = &SBuff1; // Normal screen buffer
191 }
192 ResetSBuffer(Buff);
193 SBuff2 = *Buff;
194 }
195
196 void ResetTerminal() /*reset variables but don't update screen */
197 {
198 DispReset();
199 BuffReset();
200
201 /* Attribute */
202 CharAttr = DefCharAttr;
203 Special = FALSE;
204 BuffSetCurCharAttr(CharAttr);
205
206 /* Various modes */
207 InsertMode = FALSE;
208 LFMode = (ts.CRSend == IdCRLF);
209 AutoWrapMode = TRUE;
210 AppliKeyMode = FALSE;
211 AppliCursorMode = FALSE;
212 AppliEscapeMode = FALSE;
213 RelativeOrgMode = FALSE;
214 ts.ColorFlag &= ~CF_REVERSEVIDEO;
215 AutoRepeatMode = TRUE;
216 FocusReportMode = FALSE;
217 MouseReportMode = IdMouseTrackNone;
218 DecLocatorFlag = 0;
219
220 ChangeTerminalID();
221
222 LastX = 0;
223 LastY = 0;
224 ButtonStat = 0;
225
226 if (CLocale == NULL) {
227 CLocale = _create_locale(LC_ALL, "C");
228 }
229
230 /* Character sets */
231 ResetCharSet();
232
233 /* ESC flag for device control sequence */
234 ESCFlag = FALSE;
235 /* for TEK sequence */
236 JustAfterESC = FALSE;
237
238 /* Parse mode */
239 ParseMode = ModeFirst;
240
241 /* Clear printer mode */
242 PrinterMode = FALSE;
243
244 // status buffers
245 ResetAllSBuffers();
246
247 // Alternate Screen Buffer
248 AltScr = FALSE;
249
250 // Bracketed Paste Mode
251 BracketedPaste = FALSE;
252 }
253
254 void ResetCharSet()
255 {
256 if (ts.Language==IdJapanese)
257 {
258 Gn[0] = IdASCII;
259 Gn[1] = IdKatakana;
260 Gn[2] = IdKatakana;
261 Gn[3] = IdKanji;
262 Glr[0] = 0;
263 if ((ts.KanjiCode==IdJIS) &&
264 (ts.JIS7Katakana==0))
265 Glr[1] = 2; // 8-bit katakana
266 else
267 Glr[1] = 3;
268 }
269 else {
270 Gn[0] = IdASCII;
271 Gn[1] = IdSpecial;
272 Gn[2] = IdASCII;
273 Gn[3] = IdASCII;
274 Glr[0] = 0;
275 Glr[1] = 0;
276 cv.SendCode = IdASCII;
277 cv.SendKanjiFlag = FALSE;
278 cv.EchoCode = IdASCII;
279 cv.EchoKanjiFlag = FALSE;
280 }
281 /* Kanji flag */
282 KanjiIn = FALSE;
283 EUCkanaIn = FALSE;
284 EUCsupIn = FALSE;
285 SSflag = FALSE;
286
287 cv.Language = ts.Language;
288 cv.CRSend = ts.CRSend;
289 cv.KanjiCodeEcho = ts.KanjiCode;
290 cv.JIS7KatakanaEcho = ts.JIS7Katakana;
291 cv.KanjiCodeSend = ts.KanjiCodeSend;
292 cv.JIS7KatakanaSend = ts.JIS7KatakanaSend;
293 cv.KanjiIn = ts.KanjiIn;
294 cv.KanjiOut = ts.KanjiOut;
295 }
296
297 void ResetKeypadMode(BOOL DisabledModeOnly)
298 {
299 if (!DisabledModeOnly || ts.DisableAppKeypad) AppliKeyMode = FALSE;
300 if (!DisabledModeOnly || ts.DisableAppCursor) AppliCursorMode = FALSE;
301 }
302
303 void MoveToMainScreen()
304 {
305 StatusX = CursorX;
306 StatusWrap = Wrap;
307 StatusCursor = IsCaretEnabled();
308
309 CursorTop = MainTop;
310 CursorBottom = MainBottom;
311 Wrap = MainWrap;
312 DispEnableCaret(MainCursor);
313 MoveCursor(MainX,MainY); // move to main screen
314 }
315
316 void MoveToStatusLine()
317 {
318 MainX = CursorX;
319 MainY = CursorY;
320 MainTop = CursorTop;
321 MainBottom = CursorBottom;
322 MainWrap = Wrap;
323 MainCursor = IsCaretEnabled();
324
325 DispEnableCaret(StatusCursor);
326 MoveCursor(StatusX,NumOfLines-1); // move to status line
327 CursorTop = NumOfLines-1;
328 CursorBottom = CursorTop;
329 Wrap = StatusWrap;
330 }
331
332 void HideStatusLine()
333 {
334 if ((StatusLine>0) &&
335 (CursorY==NumOfLines-1))
336 MoveToMainScreen();
337 StatusX = 0;
338 StatusWrap = FALSE;
339 StatusCursor = TRUE;
340 ShowStatusLine(0); //hide
341 }
342
343 void ChangeTerminalSize(int Nx, int Ny)
344 {
345 BuffChangeTerminalSize(Nx,Ny);
346 StatusX = 0;
347 MainX = 0;
348 MainY = 0;
349 MainTop = 0;
350 MainBottom = NumOfColumns-1;
351 }
352
353 void SendCSIstr(char *str, int len) {
354 int l;
355
356 if (str == NULL || len < 0)
357 return;
358
359 if (len == 0) {
360 l = strlen(str);
361 }
362 else {
363 l = len;
364 }
365
366 if (Send8BitMode)
367 CommBinaryOut(&cv,"\233", 1);
368 else
369 CommBinaryOut(&cv,"\033[", 2);
370
371 CommBinaryOut(&cv, str, l);
372 }
373
374 void SendOSCstr(char *str, int len) {
375 int l;
376
377 if (str == NULL || len < 0)
378 return;
379
380 if (len == 0) {
381 l = strlen(str);
382 }
383 else {
384 l = len;
385 }
386
387 if (Send8BitMode) {
388 CommBinaryOut(&cv,"\235", 1);
389 CommBinaryOut(&cv, str, l);
390 CommBinaryOut(&cv,"\234", 1);
391 }
392 else {
393 CommBinaryOut(&cv,"\033]", 2);
394 CommBinaryOut(&cv, str, l);
395 CommBinaryOut(&cv,"\033\\", 2);
396 }
397
398 }
399
400 void SendDCSstr(char *str, int len) {
401 int l;
402
403 if (str == NULL || len < 0)
404 return;
405
406 if (len == 0) {
407 l = strlen(str);
408 }
409 else {
410 l = len;
411 }
412
413 if (Send8BitMode) {
414 CommBinaryOut(&cv,"\220", 1);
415 CommBinaryOut(&cv, str, l);
416 CommBinaryOut(&cv,"\234", 1);
417 }
418 else {
419 CommBinaryOut(&cv,"\033P", 2);
420 CommBinaryOut(&cv, str, l);
421 CommBinaryOut(&cv,"\033\\", 2);
422 }
423
424 }
425
426 void BackSpace()
427 {
428 if (CursorX == 0)
429 {
430 if ((CursorY>0) &&
431 ((ts.TermFlag & TF_BACKWRAP)!=0))
432 {
433 MoveCursor(NumOfColumns-1,CursorY-1);
434 // if (cv.HLogBuf!=0) Log1Byte(BS);
435 // (2005.2.20 yutaka)
436 if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
437 }
438 }
439 else if (CursorX > 0)
440 {
441 MoveCursor(CursorX-1,CursorY);
442 // if (cv.HLogBuf!=0) Log1Byte(BS);
443 // (2005.2.20 yutaka)
444 if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
445 }
446 }
447
448 void CarriageReturn(BOOL logFlag)
449 {
450 #ifndef NO_COPYLINE_FIX
451 if (!ts.EnableContinuedLineCopy || logFlag)
452 #endif /* NO_COPYLINE_FIX */
453 if (cv.HLogBuf!=0) Log1Byte(CR);
454
455 if (CursorX>0)
456 MoveCursor(0,CursorY);
457 }
458
459 void LineFeed(BYTE b, BOOL logFlag)
460 {
461 /* for auto print mode */
462 if ((AutoPrintMode) &&
463 (b>=LF) && (b<=FF))
464 BuffDumpCurrentLine(b);
465
466 #ifndef NO_COPYLINE_FIX
467 if (!ts.EnableContinuedLineCopy || logFlag)
468 #endif /* NO_COPYLINE_FIX */
469 if (cv.HLogBuf!=0) Log1Byte(LF);
470
471 if (CursorY < CursorBottom)
472 MoveCursor(CursorX,CursorY+1);
473 else if (CursorY == CursorBottom) BuffScrollNLines(1);
474 else if (CursorY < NumOfLines-StatusLine-1)
475 MoveCursor(CursorX,CursorY+1);
476
477 #ifndef NO_COPYLINE_FIX
478 ClearLineContinued();
479 #endif /* NO_COPYLINE_FIX */
480
481 if (LFMode) CarriageReturn(logFlag);
482 }
483
484 void Tab()
485 {
486 if (Wrap && !ts.VTCompatTab) {
487 CarriageReturn(FALSE);
488 LineFeed(LF,FALSE);
489 #ifndef NO_COPYLINE_FIX
490 if (ts.EnableContinuedLineCopy) {
491 SetLineContinued();
492 }
493 #endif /* NO_COPYLINE_FIX */
494 Wrap = FALSE;
495 }
496 CursorForwardTab(1, AutoWrapMode);
497 if (cv.HLogBuf!=0) Log1Byte(HT);
498 }
499
500 void PutChar(BYTE b)
501 {
502 BOOL SpecialNew;
503 TCharAttr CharAttrTmp;
504
505 CharAttrTmp = CharAttr;
506
507 if (PrinterMode) { // printer mode
508 WriteToPrnFile(b,TRUE);
509 return;
510 }
511
512 if (Wrap)
513 {
514 CarriageReturn(FALSE);
515 LineFeed(LF,FALSE);
516 #ifndef NO_COPYLINE_FIX
517 CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
518 #endif /* NO_COPYLINE_FIX */
519 }
520
521 // if (cv.HLogBuf!=0) Log1Byte(b);
522 // (2005.2.20 yutaka)
523 if (ts.LogTypePlainText) {
524 if (__isascii(b) && !isprint(b)) {
525 // ASCII�������A���\�������������O�����������B
526 } else {
527 if (cv.HLogBuf!=0) Log1Byte(b);
528 }
529 } else {
530 if (cv.HLogBuf!=0) Log1Byte(b);
531 }
532
533 Wrap = FALSE;
534
535 SpecialNew = FALSE;
536 if ((b>0x5F) && (b<0x80))
537 {
538 if (SSflag)
539 SpecialNew = (Gn[GLtmp]==IdSpecial);
540 else
541 SpecialNew = (Gn[Glr[0]]==IdSpecial);
542 }
543 else if (b>0xDF)
544 {
545 if (SSflag)
546 SpecialNew = (Gn[GLtmp]==IdSpecial);
547 else
548 SpecialNew = (Gn[Glr[1]]==IdSpecial);
549 }
550
551 if (SpecialNew != Special)
552 {
553 UpdateStr();
554 Special = SpecialNew;
555 }
556
557 if (Special)
558 {
559 b = b & 0x7F;
560 CharAttrTmp.Attr |= AttrSpecial;
561 }
562 else
563 CharAttrTmp.Attr |= CharAttr.Attr;
564
565 BuffPutChar(b, CharAttrTmp, InsertMode);
566
567 if (CursorX < NumOfColumns-1)
568 MoveRight();
569 else {
570 UpdateStr();
571 Wrap = AutoWrapMode;
572 }
573 }
574
575 void PutDecSp(BYTE b)
576 {
577 TCharAttr CharAttrTmp;
578
579 CharAttrTmp = CharAttr;
580
581 if (PrinterMode) { // printer mode
582 WriteToPrnFile(b, TRUE);
583 return;
584 }
585
586 if (Wrap) {
587 CarriageReturn(FALSE);
588 LineFeed(LF, FALSE);
589 #ifndef NO_COPYLINE_FIX
590 CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
591 #endif /* NO_COPYLINE_FIX */
592 }
593
594 if (cv.HLogBuf!=0) Log1Byte(b);
595 /*
596 if (ts.LogTypePlainText && __isascii(b) && !isprint(b)) {
597 // ASCII�������A���\�������������O�����������B
598 } else {
599 if (cv.HLogBuf!=0) Log1Byte(b);
600 }
601 */
602
603 Wrap = FALSE;
604
605 if (!Special) {
606 UpdateStr();
607 Special = TRUE;
608 }
609
610 CharAttrTmp.Attr |= AttrSpecial;
611 BuffPutChar(b, CharAttrTmp, InsertMode);
612
613 if (CursorX < NumOfColumns-1)
614 MoveRight();
615 else {
616 UpdateStr();
617 Wrap = AutoWrapMode;
618 }
619 }
620
621 void PutKanji(BYTE b)
622 {
623 #ifndef NO_COPYLINE_FIX
624 TCharAttr CharAttrTmp;
625
626 CharAttrTmp = CharAttr;
627 #endif /* NO_COPYLINE_FIX */
628 Kanji = Kanji + b;
629
630 if (PrinterMode && DirectPrn)
631 {
632 WriteToPrnFile(HIBYTE(Kanji),FALSE);
633 WriteToPrnFile(LOBYTE(Kanji),TRUE);
634 return;
635 }
636
637 if (ConvJIS)
638 Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f));
639
640 if (PrinterMode) { // printer mode
641 WriteToPrnFile(HIBYTE(Kanji),FALSE);
642 WriteToPrnFile(LOBYTE(Kanji),TRUE);
643 return;
644 }
645
646 if (Wrap)
647 {
648 CarriageReturn(FALSE);
649 LineFeed(LF,FALSE);
650 #ifndef NO_COPYLINE_FIX
651 if (ts.EnableContinuedLineCopy)
652 CharAttrTmp.Attr |= AttrLineContinued;
653 #endif /* NO_COPYLINE_FIX */
654 }
655 else if (CursorX > NumOfColumns-2)
656 if (AutoWrapMode)
657 {
658 #ifndef NO_COPYLINE_FIX
659 if (ts.EnableContinuedLineCopy)
660 {
661 CharAttrTmp.Attr |= AttrLineContinued;
662 if (CursorX == NumOfColumns-1)
663 BuffPutChar(0x20, CharAttr, FALSE);
664 }
665 #endif /* NO_COPYLINE_FIX */
666 CarriageReturn(FALSE);
667 LineFeed(LF,FALSE);
668 }
669 else return;
670
671 Wrap = FALSE;
672
673 if (cv.HLogBuf!=0)
674 {
675 Log1Byte(HIBYTE(Kanji));
676 Log1Byte(LOBYTE(Kanji));
677 }
678
679 if (Special)
680 {
681 UpdateStr();
682 Special = FALSE;
683 }
684
685 #ifndef NO_COPYLINE_FIX
686 BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
687 #else
688 BuffPutKanji(Kanji, CharAttr, InsertMode);
689 #endif /* NO_COPYLINE_FIX */
690
691 if (CursorX < NumOfColumns-2)
692 {
693 MoveRight();
694 MoveRight();
695 }
696 else {
697 UpdateStr();
698 Wrap = AutoWrapMode;
699 }
700 }
701
702 void PutDebugChar(BYTE b)
703 {
704 static BYTE buff[3];
705 int i = 0;
706
707 if (DebugFlag!=DEBUG_FLAG_NONE) {
708 InsertMode = FALSE;
709 AutoWrapMode = TRUE;
710
711 if (DebugFlag==DEBUG_FLAG_HEXD) {
712 _snprintf(buff,3,"%02X",(unsigned int) b);
713
714 for (;i<2;i++)
715 PutChar(buff[i]);
716 PutChar(' ');
717 }
718 else if (DebugFlag==DEBUG_FLAG_NORM) {
719
720 if ((b & 0x80) == 0x80)
721 {
722 UpdateStr();
723 CharAttr.Attr = AttrReverse;
724 b = b & 0x7f;
725 }
726
727 if (b<=US)
728 {
729 PutChar('^');
730 PutChar((char)(b+0x40));
731 }
732 else if (b==DEL)
733 {
734 PutChar('<');
735 PutChar('D');
736 PutChar('E');
737 PutChar('L');
738 PutChar('>');
739 }
740 else
741 PutChar(b);
742 }
743
744 if (CharAttr.Attr != AttrDefault)
745 {
746 UpdateStr();
747 CharAttr.Attr = AttrDefault;
748 }
749 }
750 }
751
752 void PrnParseControl(BYTE b) // printer mode
753 {
754 switch (b) {
755 case NUL: return;
756 case SO:
757 if (! DirectPrn)
758 {
759 if ((ts.Language==IdJapanese) &&
760 (ts.KanjiCode==IdJIS) &&
761 (ts.JIS7Katakana==1) &&
762 ((ts.TermFlag & TF_FIXEDJIS)!=0))
763 Gn[1] = IdKatakana;
764 Glr[0] = 1; /* LS1 */
765 return;
766 }
767 break;
768 case SI:
769 if (! DirectPrn)
770 {
771 Glr[0] = 0; /* LS0 */
772 return;
773 }
774 break;
775 case DC1:
776 case DC3: return;
777 case ESC:
778 ICount = 0;
779 JustAfterESC = TRUE;
780 ParseMode = ModeESC;
781 WriteToPrnFile(0,TRUE); // flush prn buff
782 return;
783 case CSI:
784 if (! Accept8BitCtrl) {
785 PutChar(b); /* Disp C1 char in VT100 mode */
786 return;
787 }
788 ICount = 0;
789 FirstPrm = TRUE;
790 NParam = 1;
791 Param[1] = -1;
792 Prv = 0;
793 ParseMode = ModeCSI;
794 WriteToPrnFile(0,TRUE); // flush prn buff
795 WriteToPrnFile(b,FALSE);
796 return;
797 }
798 /* send the uninterpreted character to printer */
799 WriteToPrnFile(b,TRUE);
800 }
801
802 void ParseControl(BYTE b)
803 {
804 if (PrinterMode) { // printer mode
805 PrnParseControl(b);
806 return;
807 }
808
809 if (b>=0x80) /* C1 char */
810 {
811 /* English mode */
812 if (ts.Language==IdEnglish)
813 {
814 if (!Accept8BitCtrl) {
815 PutChar(b); /* Disp C1 char in VT100 mode */
816 return;
817 }
818 }
819 else { /* Japanese mode */
820 if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0)
821 return; /* ignore C1 char */
822 /* C1 chars are interpreted as C0 chars in VT100 mode */
823 if (VTlevel < 2)
824 b = b & 0x7F;
825 }
826 }
827 switch (b) {
828 /* C0 group */
829 case ENQ:
830 CommBinaryOut(&cv,&(ts.Answerback[0]),ts.AnswerbackLen);
831 break;
832 case BEL:
833 switch (ts.Beep) {
834 case IdBeepOff:
835 /* nothing to do */
836 break;
837 case IdBeepOn:
838 MessageBeep(0);
839 break;
840 case IdBeepVisual:
841 VisualBell();
842 break;
843 }
844 break;
845 case BS: BackSpace(); break;
846 case HT: Tab(); break;
847
848 case LF:
849 // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
850 // CR+LF���������������������B
851 // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
852 // (2007.1.21 yutaka)
853 if (ts.CRReceive == IdLF) {
854 CarriageReturn(TRUE);
855 LineFeed(b, TRUE);
856 break;
857 }
858
859 case VT: LineFeed(b,TRUE); break;
860
861 case FF:
862 if ((ts.AutoWinSwitch>0) && JustAfterESC)
863 {
864 CommInsert1Byte(&cv,b);
865 CommInsert1Byte(&cv,ESC);
866 ChangeEmu = IdTEK; /* Enter TEK Mode */
867 }
868 else
869 LineFeed(b,TRUE);
870 break;
871 case CR:
872 CarriageReturn(TRUE);
873 if (ts.CRReceive==IdCRLF)
874 CommInsert1Byte(&cv,LF);
875 break;
876 case SO:
877 if ((ts.Language==IdJapanese) &&
878 (ts.KanjiCode==IdJIS) &&
879 (ts.JIS7Katakana==1) &&
880 ((ts.TermFlag & TF_FIXEDJIS)!=0))
881 Gn[1] = IdKatakana;
882
883 Glr[0] = 1; /* LS1 */
884 break;
885 case SI: Glr[0] = 0; break; /* LS0 */
886 case DLE:
887 if ((ts.FTFlag & FT_BPAUTO)!=0)
888 ParseMode = ModeDLE; /* Auto B-Plus activation */
889 break;
890 case CAN:
891 if ((ts.FTFlag & FT_ZAUTO)!=0)
892 ParseMode = ModeCAN; /* Auto ZMODEM activation */
893 // else if (ts.AutoWinSwitch>0)
894 // ChangeEmu = IdTEK; /* Enter TEK Mode */
895 else
896 ParseMode = ModeFirst;
897 break;
898 case SUB: ParseMode = ModeFirst; break;
899 case ESC:
900 ICount = 0;
901 JustAfterESC = TRUE;
902 ParseMode = ModeESC;
903 break;
904 case FS:
905 case GS:
906 case RS:
907 case US:
908 if (ts.AutoWinSwitch>0)
909 {
910 CommInsert1Byte(&cv,b);
911 ChangeEmu = IdTEK; /* Enter TEK Mode */
912 }
913 break;
914
915 /* C1 char */
916 case IND: LineFeed(0,TRUE); break;
917 case NEL:
918 LineFeed(0,TRUE);
919 CarriageReturn(TRUE);
920 break;
921 case HTS: SetTabStop(); break;
922 case RI: CursorUpWithScroll(); break;
923 case SS2:
924 GLtmp = 2;
925 SSflag = TRUE;
926 break;
927 case SS3:
928 GLtmp = 3;
929 SSflag = TRUE;
930 break;
931 case DCS:
932 SavedMode = ParseMode;
933 ESCFlag = FALSE;
934 ICount = 0;
935 NParam = 1;
936 Param[1] = -1;
937 Prv = 0;
938 ParseMode = ModeDCS;
939 break;
940 case SOS:
941 SavedMode = ParseMode;
942 ESCFlag = FALSE;
943 ParseMode = ModeSOS;
944 break;
945 case CSI:
946 ICount = 0;
947 FirstPrm = TRUE;
948 NParam = 1;
949 Param[1] = -1;
950 Prv = 0;
951 ParseMode = ModeCSI;
952 break;
953 case OSC:
954 Param[1] = 0;
955 ParseMode = ModeXS;
956 break;
957 case PM:
958 case APC:
959 SavedMode = ParseMode;
960 ESCFlag = FALSE;
961 ParseMode = ModeSOS;
962 break;
963 }
964 }
965
966 void SaveCursor()
967 {
968 int i;
969 PStatusBuff Buff;
970
971 if ((StatusLine>0) &&
972 (CursorY==NumOfLines-1))
973 Buff = &SBuff2; // for status line
974 else if (AltScr)
975 Buff = &SBuff3; // for alternate screen
976 else
977 Buff = &SBuff1; // for main screen
978
979 Buff->CursorX = CursorX;
980 Buff->CursorY = CursorY;
981 Buff->Attr = CharAttr;
982 Buff->Glr[0] = Glr[0];
983 Buff->Glr[1] = Glr[1];
984 for (i=0 ; i<=3; i++)
985 Buff->Gn[i] = Gn[i];
986 Buff->AutoWrapMode = AutoWrapMode;
987 Buff->RelativeOrgMode = RelativeOrgMode;
988 }
989
990 void RestoreCursor()
991 {
992 int i;
993 PStatusBuff Buff;
994 UpdateStr();
995
996 if ((StatusLine>0) &&
997 (CursorY==NumOfLines-1))
998 Buff = &SBuff2; // for status line
999 else if (AltScr)
1000 Buff = &SBuff3; // for alternate screen
1001 else
1002 Buff = &SBuff1; // for main screen
1003
1004 if (Buff->CursorX > NumOfColumns-1)
1005 Buff->CursorX = NumOfColumns-1;
1006 if (Buff->CursorY > NumOfLines-1-StatusLine)
1007 Buff->CursorY = NumOfLines-1-StatusLine;
1008 MoveCursor(Buff->CursorX,Buff->CursorY);
1009 CharAttr = Buff->Attr;
1010 Glr[0] = Buff->Glr[0];
1011 Glr[1] = Buff->Glr[1];
1012 for (i=0 ; i<=3; i++)
1013 Gn[i] = Buff->Gn[i];
1014 AutoWrapMode = Buff->AutoWrapMode;
1015 RelativeOrgMode = Buff->RelativeOrgMode;
1016 }
1017
1018 void AnswerTerminalType()
1019 {
1020 char Tmp[50];
1021
1022 if (ts.TerminalID<IdVT320)
1023 strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1024 else
1025 strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1026
1027 switch (ts.TerminalID) {
1028 case IdVT100:
1029 strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1030 break;
1031 case IdVT100J:
1032 strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1033 break;
1034 case IdVT101:
1035 strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1036 break;
1037 case IdVT102:
1038 strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1039 break;
1040 case IdVT102J:
1041 strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1042 break;
1043 case IdVT220J:
1044 strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1045 break;
1046 case IdVT282:
1047 strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1048 break;
1049 case IdVT320:
1050 strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1051 break;
1052 case IdVT382:
1053 strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1054 break;
1055 case IdVT420:
1056 strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1057 break;
1058 case IdVT520:
1059 strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1060 break;
1061 case IdVT525:
1062 strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1063 break;
1064 }
1065 strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1066
1067 CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1068 }
1069
1070 void ESCSpace(BYTE b)
1071 {
1072 switch (b) {
1073 case 'F': // S7C1T
1074 Send8BitMode = FALSE;
1075 break;
1076 case 'G': // S8C1T
1077 if (VTlevel >= 2) {
1078 Send8BitMode = TRUE;
1079 }
1080 break;
1081 }
1082 }
1083
1084 void ESCSharp(BYTE b)
1085 {
1086 switch (b) {
1087 case '8': /* Fill screen with "E" (DECALN) */
1088 BuffUpdateScroll();
1089 BuffFillWithE();
1090 CursorTop = 0;
1091 CursorBottom = NumOfLines-1-StatusLine;
1092 MoveCursor(0,0);
1093 ParseMode = ModeFirst;
1094 break;
1095 }
1096 }
1097
1098 /* select double byte code set */
1099 void ESCDBCSSelect(BYTE b)
1100 {
1101 int Dist;
1102
1103 if (ts.Language!=IdJapanese) return;
1104
1105 switch (ICount) {
1106 case 1:
1107 if ((b=='@') || (b=='B'))
1108 {
1109 Gn[0] = IdKanji; /* Kanji -> G0 */
1110 if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1111 Glr[0] = 0; /* G0->GL */
1112 }
1113 break;
1114 case 2:
1115 /* Second intermediate char must be
1116 '(' or ')' or '*' or '+'. */
1117 Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1118 if ((b=='1') || (b=='3') ||
1119 (b=='@') || (b=='B'))
1120 {
1121 Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1122 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1123 (Dist==0))
1124 Glr[0] = 0; /* G0->GL */
1125 }
1126 break;
1127 }
1128 }
1129
1130 void ESCSelectCode(BYTE b)
1131 {
1132 switch (b) {
1133 case '0':
1134 if (ts.AutoWinSwitch>0)
1135 ChangeEmu = IdTEK; /* enter TEK mode */
1136 break;
1137 }
1138 }
1139
1140 /* select single byte code set */
1141 void ESCSBCSSelect(BYTE b)
1142 {
1143 int Dist;
1144
1145 /* Intermediate char must be
1146 '(' or ')' or '*' or '+'. */
1147 Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1148
1149 switch (b) {
1150 case '0': Gn[Dist] = IdSpecial; break;
1151 case '<': Gn[Dist] = IdASCII; break;
1152 case '>': Gn[Dist] = IdASCII; break;
1153 case 'A': Gn[Dist] = IdASCII; break;
1154 case 'B': Gn[Dist] = IdASCII; break;
1155 case 'H': Gn[Dist] = IdASCII; break;
1156 case 'I':
1157 if (ts.Language==IdJapanese)
1158 Gn[Dist] = IdKatakana;
1159 break;
1160 case 'J': Gn[Dist] = IdASCII; break;
1161 }
1162
1163 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1164 (Dist==0))
1165 Glr[0] = 0; /* G0->GL */
1166 }
1167
1168 void PrnParseEscape(BYTE b) // printer mode
1169 {
1170 int i;
1171
1172 ParseMode = ModeFirst;
1173 switch (ICount) {
1174 /* no intermediate char */
1175 case 0:
1176 switch (b) {
1177 case '[': /* CSI */
1178 ICount = 0;
1179 FirstPrm = TRUE;
1180 NParam = 1;
1181 Param[1] = -1;
1182 Prv = 0;
1183 WriteToPrnFile(ESC,FALSE);
1184 WriteToPrnFile('[',FALSE);
1185 ParseMode = ModeCSI;
1186 return;
1187 } /* end of case Icount=0 */
1188 break;
1189 /* one intermediate char */
1190 case 1:
1191 switch (IntChar[1]) {
1192 case '$':
1193 if (! DirectPrn)
1194 {
1195 ESCDBCSSelect(b);
1196 return;
1197 }
1198 break;
1199 case '(':
1200 case ')':
1201 case '*':
1202 case '+':
1203 if (! DirectPrn)
1204 {
1205 ESCSBCSSelect(b);
1206 return;
1207 }
1208 break;
1209 }
1210 break;
1211 /* two intermediate char */
1212 case 2:
1213 if ((! DirectPrn) &&
1214 (IntChar[1]=='$') &&
1215 ('('<=IntChar[2]) &&
1216 (IntChar[2]<='+'))
1217 {
1218 ESCDBCSSelect(b);
1219 return;
1220 }
1221 break;
1222 }
1223 // send the uninterpreted sequence to printer
1224 WriteToPrnFile(ESC,FALSE);
1225 for (i=1; i<=ICount; i++)
1226 WriteToPrnFile(IntChar[i],FALSE);
1227 WriteToPrnFile(b,TRUE);
1228 }
1229
1230 void ParseEscape(BYTE b) /* b is the final char */
1231 {
1232 if (PrinterMode) { // printer mode
1233 PrnParseEscape(b);
1234 return;
1235 }
1236
1237 switch (ICount) {
1238 /* no intermediate char */
1239 case 0:
1240 switch (b) {
1241 case '6': // DECBI
1242 if (CursorX == 0) {
1243 BuffScrollRight(1);
1244 }
1245 else {
1246 CursorX--;
1247 }
1248 case '7': SaveCursor(); break;
1249 case '8': RestoreCursor(); break;
1250 case '9': // DECFI
1251 if (CursorX == NumOfColumns-1) {
1252 BuffScrollLeft(1);
1253 }
1254 else {
1255 CursorX++;
1256 }
1257 case '=': AppliKeyMode = TRUE; break;
1258 case '>': AppliKeyMode = FALSE; break;
1259 case 'D': /* IND */
1260 LineFeed(0,TRUE);
1261 break;
1262 case 'E': /* NEL */
1263 MoveCursor(0,CursorY);
1264 LineFeed(0,TRUE);
1265 break;
1266 case 'H': /* HTS */
1267 SetTabStop();
1268 break;
1269 case 'M': /* RI */
1270 CursorUpWithScroll();
1271 break;
1272 case 'N': /* SS2 */
1273 GLtmp = 2;
1274 SSflag = TRUE;
1275 break;
1276 case 'O': /* SS3 */
1277 GLtmp = 3;
1278 SSflag = TRUE;
1279 break;
1280 case 'P': /* DCS */
1281 SavedMode = ParseMode;
1282 ESCFlag = FALSE;
1283 NParam = 1;
1284 Param[1] = -1;
1285 ParseMode = ModeDCS;
1286 return;
1287 case 'X': /* SOS */
1288 SavedMode = ParseMode;
1289 ESCFlag = FALSE;
1290 ParseMode = ModeSOS;
1291 return;
1292 case 'Z': AnswerTerminalType(); break;
1293 case '[': /* CSI */
1294 ICount = 0;
1295 FirstPrm = TRUE;
1296 NParam = 1;
1297 Param[1] = -1;
1298 Prv = 0;
1299 ParseMode = ModeCSI;
1300 return;
1301 case '\\': break; /* ST */
1302 case ']': /* XTERM sequence (OSC) */
1303 NParam = 1;
1304 Param[1] = 0;
1305 ParseMode = ModeXS;
1306 return;
1307 case '^':
1308 case '_': /* PM, APC */
1309 SavedMode = ParseMode;
1310 ESCFlag = FALSE;
1311 ParseMode = ModeSOS;
1312 return;
1313 case 'c': /* Hardware reset */
1314 HideStatusLine();
1315 ResetTerminal();
1316 ClearUserKey();
1317 ClearBuffer();
1318 if (ts.PortType==IdSerial) // reset serial port
1319 CommResetSerial(&ts, &cv, TRUE);
1320 break;
1321 case 'g': /* Visual Bell (screen original?) */
1322 VisualBell();
1323 break;
1324 case 'n': Glr[0] = 2; break; /* LS2 */
1325 case 'o': Glr[0] = 3; break; /* LS3 */
1326 case '|': Glr[1] = 3; break; /* LS3R */
1327 case '}': Glr[1] = 2; break; /* LS2R */
1328 case '~': Glr[1] = 1; break; /* LS1R */
1329 } /* end of case Icount=0 */
1330 break;
1331 /* one intermediate char */
1332 case 1:
1333 switch (IntChar[1]) {
1334 case ' ': ESCSpace(b); break;
1335 case '#': ESCSharp(b); break;
1336 case '$': ESCDBCSSelect(b); break;
1337 case '%': break;
1338 case '(':
1339 case ')':
1340 case '*':
1341 case '+':
1342 ESCSBCSSelect(b);
1343 break;
1344 }
1345 break;
1346 /* two intermediate char */
1347 case 2:
1348 if ((IntChar[1]=='$') &&
1349 ('('<=IntChar[2]) &&
1350 (IntChar[2]<='+'))
1351 ESCDBCSSelect(b);
1352 else if ((IntChar[1]=='%') &&
1353 (IntChar[2]=='!'))
1354 ESCSelectCode(b);
1355 break;
1356 }
1357 ParseMode = ModeFirst;
1358 }
1359
1360 void EscapeSequence(BYTE b)
1361 {
1362 if (b<=US)
1363 ParseControl(b);
1364 else if ((b>=0x20) && (b<=0x2F))
1365 {
1366 if (ICount<IntCharMax) ICount++;
1367 IntChar[ICount] = b;
1368 }
1369 else if ((b>=0x30) && (b<=0x7E))
1370 ParseEscape(b);
1371 else if ((b>=0x80) && (b<=0x9F))
1372 ParseControl(b);
1373 else if (b>=0xA0) {
1374 ParseMode=ModeFirst;
1375 ParseFirst(b);
1376 }
1377
1378 JustAfterESC = FALSE;
1379 }
1380
1381 void CSInsertCharacter()
1382 {
1383 // Insert space characters at cursor
1384 int Count;
1385
1386 BuffUpdateScroll();
1387 if (Param[1]<1) Param[1] = 1;
1388 Count = Param[1];
1389 BuffInsertSpace(Count);
1390 }
1391
1392 void CSCursorUp()
1393 {
1394 if (Param[1]<1) Param[1] = 1;
1395
1396 if (CursorY >= CursorTop)
1397 {
1398 if (CursorY-Param[1] > CursorTop)
1399 MoveCursor(CursorX,CursorY-Param[1]);
1400 else
1401 MoveCursor(CursorX,CursorTop);
1402 }
1403 else {
1404 if (CursorY > 0)
1405 MoveCursor(CursorX,CursorY-Param[1]);
1406 else
1407 MoveCursor(CursorX,0);
1408 }
1409 }
1410
1411 void CSCursorUp1()
1412 {
1413 MoveCursor(0,CursorY);
1414 CSCursorUp();
1415 }
1416
1417 void CSCursorDown()
1418 {
1419 if (Param[1]<1) Param[1] = 1;
1420
1421 if (CursorY <= CursorBottom)
1422 {
1423 if (CursorY+Param[1] < CursorBottom)
1424 MoveCursor(CursorX,CursorY+Param[1]);
1425 else
1426 MoveCursor(CursorX,CursorBottom);
1427 }
1428 else {
1429 if (CursorY < NumOfLines-StatusLine-1)
1430 MoveCursor(CursorX,CursorY+Param[1]);
1431 else
1432 MoveCursor(CursorX,NumOfLines-StatusLine);
1433 }
1434 }
1435
1436 void CSCursorDown1()
1437 {
1438 MoveCursor(0,CursorY);
1439 CSCursorDown();
1440 }
1441
1442 void CSScreenErase()
1443 {
1444 if (Param[1] == -1) Param[1] = 0;
1445 BuffUpdateScroll();
1446 switch (Param[1]) {
1447 case 0:
1448 // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1449 // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1450 // �����������������B(2005.5.29 yutaka)
1451 // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1452 if (ts.ScrollWindowClearScreen &&
1453 (CursorX == 0 && CursorY == 0)) {
1454 // Erase screen (scroll out)
1455 BuffClearScreen();
1456 UpdateWindow(HVTWin);
1457
1458 } else {
1459 // Erase characters from cursor to the end of screen
1460 BuffEraseCurToEnd();
1461 }
1462 break;
1463
1464 case 1:
1465 // Erase characters from home to cursor
1466 BuffEraseHomeToCur();
1467 break;
1468
1469 case 2:
1470 // Erase screen (scroll out)
1471 BuffClearScreen();
1472 UpdateWindow(HVTWin);
1473 break;
1474 }
1475 }
1476
1477 void CSQSelScreenErase()
1478 {
1479 if (Param[1] == -1) Param[1] = 0;
1480 BuffUpdateScroll();
1481 switch (Param[1]) {
1482 case 0:
1483 // Erase characters from cursor to end
1484 BuffSelectedEraseCurToEnd();
1485 break;
1486
1487 case 1:
1488 // Erase characters from home to cursor
1489 BuffSelectedEraseHomeToCur();
1490 break;
1491
1492 case 2:
1493 // Erase entire screen
1494 BuffSelectedEraseScreen();
1495 break;
1496 }
1497 }
1498
1499 void CSInsertLine()
1500 {
1501 // Insert lines at current position
1502 int Count, YEnd;
1503
1504 if (CursorY < CursorTop) return;
1505 if (CursorY > CursorBottom) return;
1506 if (Param[1]<1) Param[1] = 1;
1507 Count = Param[1];
1508
1509 YEnd = CursorBottom;
1510 if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1511 if (Count > YEnd+1 - CursorY) Count = YEnd+1 - CursorY;
1512
1513 BuffInsertLines(Count,YEnd);
1514 }
1515
1516 void CSLineErase()
1517 {
1518 if (Param[1] == -1) Param[1] = 0;
1519 BuffUpdateScroll();
1520 switch (Param[1]) {
1521 /* erase char from cursor to end of line */
1522 case 0:
1523 BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1524 break;
1525 /* erase char from start of line to cursor */
1526 case 1:
1527 BuffEraseCharsInLine(0,CursorX+1);
1528 break;
1529 /* erase entire line */
1530 case 2:
1531 BuffEraseCharsInLine(0,NumOfColumns);
1532 break;
1533 }
1534 }
1535
1536 void CSQSelLineErase()
1537 {
1538 if (Param[1] == -1) Param[1] = 0;
1539 BuffUpdateScroll();
1540 switch (Param[1]) {
1541 /* erase char from cursor to end of line */
1542 case 0:
1543 BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1544 break;
1545 /* erase char from start of line to cursor */
1546 case 1:
1547 BuffSelectedEraseCharsInLine(0,CursorX+1);
1548 break;
1549 /* erase entire line */
1550 case 2:
1551 BuffSelectedEraseCharsInLine(0,NumOfColumns);
1552 break;
1553 }
1554 }
1555
1556 void CSDeleteNLines()
1557 // Delete lines from current line
1558 {
1559 int Count, YEnd;
1560
1561 if (CursorY < CursorTop) return;
1562 if (CursorY > CursorBottom) return;
1563 Count = Param[1];
1564 if (Count<1) Count = 1;
1565
1566 YEnd = CursorBottom;
1567 if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1568 if (Count > YEnd+1-CursorY) Count = YEnd+1-CursorY;
1569 BuffDeleteLines(Count,YEnd);
1570 }
1571
1572 void CSDeleteCharacter()
1573 {
1574 // Delete characters in current line from cursor
1575
1576 if (Param[1]<1) Param[1] = 1;
1577 BuffUpdateScroll();
1578 BuffDeleteChars(Param[1]);
1579 }
1580
1581 void CSEraseCharacter()
1582 {
1583 if (Param[1]<1) Param[1] = 1;
1584 BuffUpdateScroll();
1585 BuffEraseChars(Param[1]);
1586 }
1587
1588 void CSScrollUP()
1589 {
1590 if (Param[1]<1) Param[1] = 1;
1591 BuffUpdateScroll();
1592 BuffRegionScrollUpNLines(Param[1]);
1593 }
1594
1595 void CSScrollDown()
1596 {
1597 if (Param[1]<1) Param[1] = 1;
1598 BuffUpdateScroll();
1599 BuffRegionScrollDownNLines(Param[1]);
1600 }
1601
1602 void CSForwardTab()
1603 {
1604 if (Param[1]<1) Param[1] = 1;
1605 CursorForwardTab(Param[1], AutoWrapMode);
1606 }
1607
1608 void CSBackwardTab()
1609 {
1610 if (Param[1]<1) Param[1] = 1;
1611 CursorBackwardTab(Param[1]);
1612 }
1613
1614 void CSMoveToColumnN()
1615 {
1616 if (Param[1]<1) Param[1] = 1;
1617 Param[1]--;
1618 if (Param[1] < 0) Param[1] = 0;
1619 if (Param[1] > NumOfColumns-1) Param[1] = NumOfColumns-1;
1620 MoveCursor(Param[1],CursorY);
1621 }
1622
1623 void CSCursorRight()
1624 {
1625 if (Param[1]<1) Param[1] = 1;
1626 if (CursorX + Param[1] > NumOfColumns-1)
1627 MoveCursor(NumOfColumns-1,CursorY);
1628 else
1629 MoveCursor(CursorX+Param[1],CursorY);
1630 }
1631
1632 void CSCursorLeft()
1633 {
1634 if (Param[1]<1) Param[1] = 1;
1635 if (CursorX-Param[1] < 0)
1636 MoveCursor(0,CursorY);
1637 else
1638 MoveCursor(CursorX-Param[1],CursorY);
1639 }
1640
1641 void CSMoveToLineN()
1642 {
1643 if (Param[1]<1) Param[1] = 1;
1644 if (RelativeOrgMode)
1645 {
1646 if (CursorTop+Param[1]-1 > CursorBottom)
1647 MoveCursor(CursorX,CursorBottom);
1648 else
1649 MoveCursor(CursorX,CursorTop+Param[1]-1);
1650 }
1651 else {
1652 if (Param[1] > NumOfLines-StatusLine)
1653 MoveCursor(CursorX,NumOfLines-1-StatusLine);
1654 else
1655 MoveCursor(CursorX,Param[1]-1);
1656 }
1657 }
1658
1659 void CSMoveToXY()
1660 {
1661 int NewX, NewY;
1662
1663 if (Param[1]<1) Param[1] = 1;
1664 if ((NParam < 2) || (Param[2]<1)) Param[2] = 1;
1665 NewX = Param[2] - 1;
1666 if (NewX > NumOfColumns-1) NewX = NumOfColumns-1;
1667
1668 if ((StatusLine>0) && (CursorY==NumOfLines-1))
1669 NewY = CursorY;
1670 else if (RelativeOrgMode)
1671 {
1672 NewY = CursorTop + Param[1] - 1;
1673 if (NewY > CursorBottom) NewY = CursorBottom;
1674 }
1675 else {
1676 NewY = Param[1] - 1;
1677 if (NewY > NumOfLines-1-StatusLine)
1678 NewY = NumOfLines-1-StatusLine;
1679 }
1680 MoveCursor(NewX,NewY);
1681 }
1682
1683 void CSDeleteTabStop()
1684 {
1685 if (Param[1]==-1) Param[1] = 0;
1686 ClearTabStop(Param[1]);
1687 }
1688
1689 void CS_h_Mode() // SM
1690 {
1691 switch (Param[1]) {
1692 case 2: // KAM
1693 KeybEnabled = FALSE; break;
1694 case 4: // IRM
1695 InsertMode = TRUE; break;
1696 case 12: // SRM
1697 ts.LocalEcho = 0;
1698 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1699 TelChangeEcho();
1700 break;
1701 case 20: // LF/NL
1702 LFMode = TRUE;
1703 ts.CRSend = IdCRLF;
1704 cv.CRSend = IdCRLF;
1705 break;
1706 case 33: // WYSTCURM
1707 if (ts.WindowFlag & WF_CURSORCHANGE) {
1708 ts.NonblinkingCursor = TRUE;
1709 ChangeCaret();
1710 }
1711 break;
1712 case 34: // WYULCURM
1713 if (ts.WindowFlag & WF_CURSORCHANGE) {
1714 ts.CursorShape = IdHCur;
1715 ChangeCaret();
1716 }
1717 break;
1718 }
1719 }
1720
1721 void CS_i_Mode() // MC
1722 {
1723 if (Param[1]==-1) Param[1] = 0;
1724 switch (Param[1]) {
1725 /* print screen */
1726 // PrintEX -- TRUE: print screen
1727 // FALSE: scroll region
1728 case 0: BuffPrint(! PrintEX); break;
1729 /* printer controller mode off */
1730 case 4: break; /* See PrnParseCS() */
1731 /* printer controller mode on */
1732 case 5:
1733 if (! AutoPrintMode)
1734 OpenPrnFile();
1735 DirectPrn = (ts.PrnDev[0]!=0);
1736 PrinterMode = TRUE;
1737 break;
1738 }
1739 }
1740
1741 void CS_l_Mode() // RM
1742 {
1743 switch (Param[1]) {
1744 case 2: // KAM
1745 KeybEnabled = TRUE; break;
1746 case 4: // IRM
1747 InsertMode = FALSE; break;
1748 case 12: // SRM
1749 ts.LocalEcho = 1;
1750 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1751 TelChangeEcho();
1752 break;
1753 case 20: // LF/NL
1754 LFMode = FALSE;
1755 ts.CRSend = IdCR;
1756 cv.CRSend = IdCR;
1757 break;
1758 case 33: // WYSTCURM
1759 if (ts.WindowFlag & WF_CURSORCHANGE) {
1760 ts.NonblinkingCursor = FALSE;
1761 ChangeCaret();
1762 }
1763 break;
1764 case 34: // WYULCURM
1765 if (ts.WindowFlag & WF_CURSORCHANGE) {
1766 ts.CursorShape = IdBlkCur;
1767 ChangeCaret();
1768 }
1769 break;
1770 }
1771 }
1772
1773 void CS_n_Mode() // DSR
1774 {
1775 char Report[16];
1776 int Y, len;
1777
1778 switch (Param[1]) {
1779 case 5:
1780 /* Device Status Report -> Ready */
1781 SendCSIstr("0n", 0);
1782 break;
1783 case 6:
1784 /* Cursor Position Report */
1785 Y = CursorY+1;
1786 if ((StatusLine>0) &&
1787 (Y==NumOfLines))
1788 Y = 1;
1789 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, CursorX+1);
1790 SendCSIstr(Report, len);
1791 break;
1792 }
1793 }
1794
1795 void CSSetAttr() // SGR
1796 {
1797 int i, P;
1798
1799 UpdateStr();
1800 for (i=1 ; i<=NParam ; i++)
1801 {
1802 P = Param[i];
1803 if (P<0) P = 0;
1804 switch (P) {
1805 case 0: /* Clear all */
1806 if (CharAttr.Attr2 & Attr2Protect) {
1807 CharAttr = DefCharAttr;
1808 CharAttr.Attr2 |= Attr2Protect;
1809 }
1810 else {
1811 CharAttr = DefCharAttr;
1812 }
1813 BuffSetCurCharAttr(CharAttr);
1814 break;
1815
1816 case 1: /* Bold */
1817 CharAttr.Attr |= AttrBold;
1818 BuffSetCurCharAttr(CharAttr);
1819 break;
1820
1821 case 4: /* Under line */
1822 CharAttr.Attr |= AttrUnder;
1823 BuffSetCurCharAttr(CharAttr);
1824 break;
1825
1826 case 5: /* Blink */
1827 CharAttr.Attr |= AttrBlink;
1828 BuffSetCurCharAttr(CharAttr);
1829 break;
1830
1831 case 7: /* Reverse */
1832 CharAttr.Attr |= AttrReverse;
1833 BuffSetCurCharAttr(CharAttr);
1834 break;
1835
1836 case 22: /* Bold off */
1837 CharAttr.Attr &= ~ AttrBold;
1838 BuffSetCurCharAttr(CharAttr);
1839 break;
1840
1841 case 24: /* Under line off */
1842 CharAttr.Attr &= ~ AttrUnder;
1843 BuffSetCurCharAttr(CharAttr);
1844 break;
1845
1846 case 25: /* Blink off */
1847 CharAttr.Attr &= ~ AttrBlink;
1848 BuffSetCurCharAttr(CharAttr);
1849 break;
1850
1851 case 27: /* Reverse off */
1852 CharAttr.Attr &= ~ AttrReverse;
1853 BuffSetCurCharAttr(CharAttr);
1854 break;
1855
1856 case 30:
1857 case 31:
1858 case 32:
1859 case 33:
1860 case 34:
1861 case 35:
1862 case 36:
1863 case 37: /* text color */
1864 CharAttr.Attr2 |= Attr2Fore;
1865 CharAttr.Fore = P - 30;
1866 BuffSetCurCharAttr(CharAttr);
1867 break;
1868
1869 case 38: /* text color (256color mode) */
1870 if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1871 i++;
1872 if (i < NParam) {
1873 P = Param[++i];
1874 if (P<0) {
1875 P = 0;
1876 }
1877 CharAttr.Attr2 |= Attr2Fore;
1878 CharAttr.Fore = P;
1879 BuffSetCurCharAttr(CharAttr);
1880 }
1881 }
1882 break;
1883
1884 case 39: /* Reset text color */
1885 CharAttr.Attr2 &= ~ Attr2Fore;
1886 CharAttr.Fore = AttrDefaultFG;
1887 BuffSetCurCharAttr(CharAttr);
1888 break;
1889
1890 case 40:
1891 case 41:
1892 case 42:
1893 case 43:
1894 case 44:
1895 case 45:
1896 case 46:
1897 case 47: /* Back color */
1898 CharAttr.Attr2 |= Attr2Back;
1899 CharAttr.Back = P - 40;
1900 BuffSetCurCharAttr(CharAttr);
1901 break;
1902
1903 case 48: /* Back color (256color mode) */
1904 if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1905 i++;
1906 if (i < NParam) {
1907 P = Param[++i];
1908 if (P<0) {
1909 P = 0;
1910 }
1911 CharAttr.Attr2 |= Attr2Back;
1912 CharAttr.Back = P;
1913 BuffSetCurCharAttr(CharAttr);
1914 }
1915 }
1916 break;
1917
1918 case 49: /* Reset back color */
1919 CharAttr.Attr2 &= ~ Attr2Back;
1920 CharAttr.Back = AttrDefaultBG;
1921 BuffSetCurCharAttr(CharAttr);
1922 break;
1923
1924 case 90:
1925 case 91:
1926 case 92:
1927 case 93:
1928 case 94:
1929 case 95:
1930 case 96:
1931 case 97: /* aixterm style text color */
1932 if (ts.ColorFlag & CF_AIXTERM16) {
1933 CharAttr.Attr2 |= Attr2Fore;
1934 CharAttr.Fore = P - 90 + 8;
1935 BuffSetCurCharAttr(CharAttr);
1936 }
1937 break;
1938
1939 case 100:
1940 if (! (ts.ColorFlag & CF_AIXTERM16)) {
1941 /* Reset text and back color */
1942 CharAttr.Attr2 &= ~ (Attr2Fore | Attr2Back);
1943 CharAttr.Fore = AttrDefaultFG;
1944 CharAttr.Back = AttrDefaultBG;
1945 BuffSetCurCharAttr(CharAttr);
1946 break;
1947 }
1948 /* fall through to aixterm style back color */
1949
1950 case 101:
1951 case 102:
1952 case 103:
1953 case 104:
1954 case 105:
1955 case 106:
1956 case 107: /* aixterm style back color */
1957 if (ts.ColorFlag & CF_AIXTERM16) {
1958 CharAttr.Attr2 |= Attr2Back;
1959 CharAttr.Back = P - 100 + 8;
1960 BuffSetCurCharAttr(CharAttr);
1961 }
1962 break;
1963 }
1964 }
1965 }
1966
1967 void CSSetScrollRegion()
1968 {
1969 if ((StatusLine>0) &&
1970 (CursorY==NumOfLines-1))
1971 {
1972 MoveCursor(0,CursorY);
1973 return;
1974 }
1975 if (Param[1]<1) Param[1] =1;
1976 if ((NParam < 2) | (Param[2]<1))
1977 Param[2] = NumOfLines-StatusLine;
1978 Param[1]--;
1979 Param[2]--;
1980 if (Param[1] > NumOfLines-1-StatusLine)
1981 Param[1] = NumOfLines-1-StatusLine;
1982 if (Param[2] > NumOfLines-1-StatusLine)
1983 Param[2] = NumOfLines-1-StatusLine;
1984 if (Param[1] >= Param[2]) return;
1985 CursorTop = Param[1];
1986 CursorBottom = Param[2];
1987 if (RelativeOrgMode) MoveCursor(0,CursorTop);
1988 else MoveCursor(0,0);
1989 }
1990
1991 void CSSunSequence() /* Sun terminal private sequences */
1992 {
1993 int x, y, len;
1994 char Report[TitleBuffSize*2+10];
1995
1996 switch (Param[1]) {
1997 case 1: // De-iconify window
1998 if (ts.WindowFlag & WF_WINDOWCHANGE)
1999 DispShowWindow(WINDOW_RESTORE);
2000 break;
2001 case 2: // Iconify window
2002 if (ts.WindowFlag & WF_WINDOWCHANGE)
2003 DispShowWindow(WINDOW_MINIMIZE);
2004 break;
2005 case 3: // set window position
2006 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2007 if (NParam < 2) Param[2] = 0;
2008 if (NParam < 3) Param[3] = 0;
2009 DispMoveWindow(Param[2], Param[3]);
2010 }
2011 break;
2012 case 4: // set window size
2013 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2014 if (NParam < 2) Param[2] = 0;
2015 if (NParam < 3) Param[3] = 0;
2016 DispResizeWin(Param[3], Param[2]);
2017 }
2018 break;
2019 case 5: // Raise window
2020 if (ts.WindowFlag & WF_WINDOWCHANGE)
2021 DispShowWindow(WINDOW_RAISE);
2022 break;
2023 case 6: // Lower window
2024 if (ts.WindowFlag & WF_WINDOWCHANGE)
2025 DispShowWindow(WINDOW_LOWER);
2026 break;
2027 case 7: // Refresh window
2028 if (ts.WindowFlag & WF_WINDOWCHANGE)
2029 DispShowWindow(WINDOW_REFRESH);
2030 break;
2031 case 8: /* set terminal size */
2032 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2033 if ((Param[2]<=1) || (NParam<2)) Param[2] = 24;
2034 if ((Param[3]<=1) || (NParam<3)) Param[3] = 80;
2035 ChangeTerminalSize(Param[3],Param[2]);
2036 }
2037 break;
2038 case 9: // Maximize/Restore window
2039 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2040 if (NParam < 2 || Param[2] == 0) {
2041 DispShowWindow(WINDOW_RESTORE);
2042 }
2043 else if (Param[2] == 1) {
2044 DispShowWindow(WINDOW_MAXIMIZE);
2045 }
2046 }
2047 break;
2048 case 11: // Report window state
2049 if (ts.WindowFlag & WF_WINDOWREPORT) {
2050 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
2051 SendCSIstr(Report, len);
2052 }
2053 break;
2054 case 13: // Report window position
2055 if (ts.WindowFlag & WF_WINDOWREPORT) {
2056 DispGetWindowPos(&x, &y);
2057 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%d;%dt", CLocale, x, y);
2058 SendCSIstr(Report, len);
2059 }
2060 break;
2061 case 14: /* get window size */
2062 if (ts.WindowFlag & WF_WINDOWREPORT) {
2063 DispGetWindowSize(&x, &y);
2064 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "4;%d;%dt", CLocale, y, x);
2065 SendCSIstr(Report, len);
2066 }
2067 break;
2068 case 18: /* get terminal size */
2069 if (ts.WindowFlag & WF_WINDOWREPORT) {
2070 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%u;t", CLocale,
2071 NumOfLines-StatusLine, NumOfColumns);
2072 SendCSIstr(Report, len);
2073 }
2074 break;
2075 case 19: // Report display size (character)
2076 if (ts.WindowFlag & WF_WINDOWREPORT) {
2077 DispGetRootWinSize(&x, &y);
2078 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
2079 SendCSIstr(Report, len);
2080 }
2081 break;
2082 case 20: // Report icon label
2083 switch (ts.WindowFlag & WF_TITLEREPORT) {
2084 case IdTitleReportIgnore:
2085 // nothing to do
2086 break;
2087 case IdTitleReportAccept:
2088 switch (ts.AcceptTitleChangeRequest) {
2089 case IdTitleChangeRequestOff:
2090 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2091 break;
2092 case IdTitleChangeRequestAhead:
2093 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, cv.TitleRemote, ts.Title);
2094 break;
2095 case IdTitleChangeRequestLast:
2096 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, ts.Title, cv.TitleRemote);
2097 break;
2098 default:
2099 if (cv.TitleRemote[0] == 0) {
2100 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2101 }
2102 else {
2103 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, cv.TitleRemote);
2104 }
2105 }
2106 SendOSCstr(Report, len);
2107 break;
2108 default: // IdTitleReportEmpty:
2109 SendOSCstr("L", 0);
2110 break;
2111 }
2112 break;
2113 case 21: // Report window title
2114 switch (ts.WindowFlag & WF_TITLEREPORT) {
2115 case IdTitleReportIgnore:
2116 // nothing to do
2117 break;
2118 case IdTitleReportAccept:
2119 switch (ts.AcceptTitleChangeRequest) {
2120 case IdTitleChangeRequestOff:
2121 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2122 break;
2123 case IdTitleChangeRequestAhead:
2124 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, cv.TitleRemote, ts.Title);
2125 break;
2126 case IdTitleChangeRequestLast:
2127 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, ts.Title, cv.TitleRemote);
2128 break;
2129 default:
2130 if (cv.TitleRemote[0] == 0) {
2131 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2132 }
2133 else {
2134 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, cv.TitleRemote);
2135 }
2136 }
2137 SendOSCstr(Report, len);
2138 break;
2139 default: // IdTitleReportEmpty:
2140 SendOSCstr("l", 0);
2141 break;
2142 }
2143 break;
2144 }
2145 }
2146
2147 void CSEQ(BYTE b)
2148 {
2149 char Report[16];
2150 int len;
2151
2152 switch (b) {
2153 case 'c': /* Tertiary terminal report (Tertiary DA) */
2154 if (Param[1] < 1) {
2155 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "!|%8s", CLocale, ts.TerminalUID);
2156 SendDCSstr(Report, len);
2157 }
2158 break;
2159 }
2160 }
2161
2162 void CSGT(BYTE b)
2163 {
2164 switch (b) {
2165 case 'c': /* second terminal report (Secondary DA) */
2166 if (Param[1] < 1) {
2167 SendCSIstr(">32;100;2c", 0); /* VT382 */
2168 }
2169 break;
2170 case 'J': // IO-8256 terminal
2171 if (Param[1]==3) {
2172 if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2173 if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2174 if (Param[4] < 1 || NParam < 4) Param[4] = NumOfLines-StatusLine;
2175 if (Param[5] < 1 || NParam < 5) Param[5] = NumOfColumns;
2176 BuffEraseBox(Param[3]-1, Param[2]-1, Param[5]-1, Param[4]-1);
2177 }
2178 break;
2179 case 'K': // IO-8256 terminal
2180 switch (Param[1]) {
2181 case 3:
2182 if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2183 if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2184 BuffEraseCharsInLine(Param[2]-1, Param[3]-Param[2]+1);
2185 break;
2186 case 5:
2187 if (NParam < 2) Param[2] = 0;
2188 if (NParam < 3) Param[3] = 0;
2189 switch (Param[2]) {
2190 case 3:
2191 case 4:
2192 case 5:
2193 case 6: // Draw Line
2194 BuffDrawLine(CharAttr, Param[2], Param[3]);
2195 break;
2196
2197 case 12: // Text color
2198 if ((Param[3]>=0) && (Param[3]<=7)) {
2199 switch (Param[3]) {
2200 case 3: CharAttr.Fore = IdBlue; break;
2201 case 4: CharAttr.Fore = IdCyan; break;
2202 case 5: CharAttr.Fore = IdYellow; break;
2203 case 6: CharAttr.Fore = IdMagenta; break;
2204 default: CharAttr.Fore = Param[3]; break;
2205 }
2206 CharAttr.Attr2 |= Attr2Fore;
2207 BuffSetCurCharAttr(CharAttr);
2208 }
2209 break;
2210 }
2211 break;
2212 }
2213 break;
2214 }
2215 }
2216
2217 void CSQExchangeColor() // DECSCNM / Visual Bell
2218 {
2219 COLORREF ColorRef;
2220
2221 BuffUpdateScroll();
2222
2223 if (ts.ColorFlag & CF_REVERSECOLOR) {
2224 ColorRef = ts.VTColor[0];
2225 ts.VTColor[0] = ts.VTReverseColor[0];
2226 ts.VTReverseColor[0] = ColorRef;
2227 ColorRef = ts.VTColor[1];
2228 ts.VTColor[1] = ts.VTReverseColor[1];
2229 ts.VTReverseColor[1] = ColorRef;
2230 }
2231 else {
2232 ColorRef = ts.VTColor[0];
2233 ts.VTColor[0] = ts.VTColor[1];
2234 ts.VTColor[1] = ColorRef;
2235 }
2236
2237 ColorRef = ts.VTBoldColor[0];
2238 ts.VTBoldColor[0] = ts.VTBoldColor[1];
2239 ts.VTBoldColor[1] = ColorRef;
2240
2241 ColorRef = ts.VTBlinkColor[0];
2242 ts.VTBlinkColor[0] = ts.VTBlinkColor[1];
2243 ts.VTBlinkColor[1] = ColorRef;
2244
2245 ColorRef = ts.URLColor[0];
2246 ts.URLColor[0] = ts.URLColor[1];
2247 ts.URLColor[1] = ColorRef;
2248
2249 ts.ColorFlag ^= CF_REVERSEVIDEO;
2250
2251 #ifdef ALPHABLEND_TYPE2
2252 BGExchangeColor();
2253 #endif
2254 DispChangeBackground();
2255 UpdateWindow(HVTWin);
2256 }
2257
2258 void CSQChangeColumnMode(int width) // DECCOLM
2259 {
2260 ChangeTerminalSize(width, NumOfLines-StatusLine);
2261 if ((ts.TermFlag & TF_CLEARONRESIZE) == 0) {
2262 MoveCursor(0, 0);
2263 BuffClearScreen();
2264 UpdateWindow(HVTWin);
2265 }
2266 }
2267
2268 void CSQ_h_Mode() // DECSET
2269 {
2270 int i;
2271
2272 for (i = 1 ; i<=NParam ; i++)
2273 switch (Param[i]) {
2274 case 1: AppliCursorMode = TRUE; break; // DECCKM
2275 case 3: CSQChangeColumnMode(132); break; // DECCOLM
2276 case 5: /* Reverse Video (DECSCNM) */
2277 if (!(ts.ColorFlag & CF_REVERSEVIDEO))
2278 CSQExchangeColor(); /* Exchange text/back color */
2279 break;
2280 case 6: // DECOM
2281 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2282 MoveCursor(0,CursorY);
2283 else {
2284 RelativeOrgMode = TRUE;
2285 MoveCursor(0,CursorTop);
2286 }
2287 break;
2288 case 7: AutoWrapMode = TRUE; break; // DECAWM
2289 case 8: AutoRepeatMode = TRUE; break; // DECARM
2290 case 9: /* X10 Mouse Tracking */
2291 if (ts.MouseEventTracking)
2292 MouseReportMode = IdMouseTrackX10;
2293 break;
2294 case 12: /* att610 cursor blinking */
2295 if (ts.WindowFlag & WF_CURSORCHANGE) {
2296 ts.NonblinkingCursor = FALSE;
2297 ChangeCaret();
2298 }
2299 break;
2300 case 19: PrintEX = TRUE; break; // DECPEX
2301 case 25: DispEnableCaret(TRUE); break; // cursor on (DECTCEM)
2302 case 38: // DECTEK
2303 if (ts.AutoWinSwitch>0)
2304 ChangeEmu = IdTEK; /* Enter TEK Mode */
2305 break;
2306 case 47: // Alternate Screen Buffer
2307 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2308 BuffSaveScreen();
2309 AltScr = TRUE;
2310 }
2311 break;
2312 case 59:
2313 if (ts.Language==IdJapanese)
2314 { /* kanji terminal */
2315 Gn[0] = IdASCII;
2316 Gn[1] = IdKatakana;
2317 Gn[2] = IdKatakana;
2318 Gn[3] = IdKanji;
2319 Glr[0] = 0;
2320 if ((ts.KanjiCode==IdJIS) &&
2321 (ts.JIS7Katakana==0))
2322 Glr[1] = 2; // 8-bit katakana
2323 else
2324 Glr[1] = 3;
2325 }
2326 break;
2327 case 66: AppliKeyMode = TRUE; break; // DECNKM
2328 case 67: ts.BSKey = IdBS; break; // DECBKM
2329 case 1000: // Mouse Tracking
2330 if (ts.MouseEventTracking)
2331 MouseReportMode = IdMouseTrackVT200;
2332 break;
2333 case 1001: // Hilite Mouse Tracking
2334 if (ts.MouseEventTracking)
2335 MouseReportMode = IdMouseTrackVT200Hl;
2336 break;
2337 case 1002: // Button-Event Mouse Tracking
2338 if (ts.MouseEventTracking)
2339 MouseReportMode = IdMouseTrackBtnEvent;
2340 break;
2341 case 1003: // Any-Event Mouse Tracking
2342 if (ts.MouseEventTracking)
2343 MouseReportMode = IdMouseTrackAllEvent;
2344 break;
2345 case 1004: // Focus Report
2346 if (ts.MouseEventTracking)
2347 FocusReportMode = TRUE;
2348 break;
2349 case 1047: // Alternate Screen Buffer
2350 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2351 BuffSaveScreen();
2352 AltScr = TRUE;
2353 }
2354 break;
2355 case 1048: // Save Cursor Position (Alternate Screen Buffer)
2356 if (ts.TermFlag & TF_ALTSCR) {
2357 SaveCursor();
2358 }
2359 break;
2360 case 1049: // Alternate Screen Buffer
2361 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2362 SaveCursor();
2363 BuffSaveScreen();
2364 BuffClearScreen();
2365 AltScr = TRUE;
2366 }
2367 break;
2368 case 2004: // Bracketed Paste Mode
2369 BracketedPaste = TRUE;
2370 break;
2371 case 7727: // mintty Application Escape Mode
2372 AppliEscapeMode = TRUE;
2373 break;
2374 }
2375 }
2376
2377 void CSQ_i_Mode() // DECMC
2378 {
2379 if (Param[1]==-1) Param[1] = 0;
2380 switch (Param[1]) {
2381 case 1:
2382 OpenPrnFile();
2383 BuffDumpCurrentLine(LF);
2384 if (! AutoPrintMode)
2385 ClosePrnFile();
2386 break;
2387 /* auto print mode off */
2388 case 4:
2389 if (AutoPrintMode)
2390 {
2391 ClosePrnFile();
2392 AutoPrintMode = FALSE;
2393 }
2394 break;
2395 /* auto print mode on */
2396 case 5:
2397 if (! AutoPrintMode)
2398 {
2399 OpenPrnFile();
2400 AutoPrintMode = TRUE;
2401 }
2402 break;
2403 }
2404 }
2405
2406 void CSQ_l_Mode() // DECRST
2407 {
2408 int i;
2409
2410 for (i = 1 ; i <= NParam ; i++)
2411 switch (Param[i]) {
2412 case 1: AppliCursorMode = FALSE; break; // DECCKM
2413 case 3: CSQChangeColumnMode(80); break; // DECCOLM
2414 case 5: /* Normal Video (DECSCNM) */
2415 if (ts.ColorFlag & CF_REVERSEVIDEO)
2416 CSQExchangeColor(); /* Exchange text/back color */
2417 break;
2418 case 6: // DECOM
2419 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2420 MoveCursor(0,CursorY);
2421 else {
2422 RelativeOrgMode = FALSE;
2423 MoveCursor(0,0);
2424 }
2425 break;
2426 case 7: AutoWrapMode = FALSE; break; // DECAWM
2427 case 8: AutoRepeatMode = FALSE; break; // DECARM
2428 case 9: MouseReportMode = IdMouseTrackNone; break; /* X10 Mouse Tracking */
2429 case 12: /* att610 cursor blinking */
2430 if (ts.WindowFlag & WF_CURSORCHANGE) {
2431 ts.NonblinkingCursor = TRUE;
2432 ChangeCaret();
2433 }
2434 break;
2435 case 19: PrintEX = FALSE; break; // DECPEX
2436 case 25: DispEnableCaret(FALSE); break; // cursor off (DECTCEM)
2437 case 47: // Alternate Screen Buffer
2438 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2439 BuffRestoreScreen();
2440 AltScr = FALSE;
2441 }
2442 break;
2443 case 59:
2444 if (ts.Language==IdJapanese)
2445 { /* katakana terminal */
2446 Gn[0] = IdASCII;
2447 Gn[1] = IdKatakana;
2448 Gn[2] = IdKatakana;
2449 Gn[3] = IdKanji;
2450 Glr[0] = 0;
2451 if ((ts.KanjiCode==IdJIS) &&
2452 (ts.JIS7Katakana==0))
2453 Glr[1] = 2; // 8-bit katakana
2454 else
2455 Glr[1] = 3;
2456 }
2457 break;
2458 case 66: AppliKeyMode = FALSE; break; // DECNKM
2459 case 67: ts.BSKey = IdDEL; break; // DECBKM
2460 case 1000: // Mouse Tracking
2461 case 1001: // Hilite Mouse Tracking
2462 case 1002: // Button-Event Mouse Tracking
2463 case 1003: // Any-Event Mouse Tracking
2464 MouseReportMode = IdMouseTrackNone;
2465 break;
2466 case 1004: FocusReportMode = FALSE; break; // Focus Report
2467 case 1047: // Alternate Screen Buffer
2468 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2469 BuffClearScreen();
2470 BuffRestoreScreen();
2471 AltScr = FALSE;
2472 }
2473 break;
2474 case 1048: // Save Cursor Position (Alternate Screen Buffer)
2475 if (ts.TermFlag & TF_ALTSCR) {
2476 RestoreCursor();
2477 }
2478 break;
2479 case 1049: // Alternate Screen Buffer
2480 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2481 BuffClearScreen();
2482 BuffRestoreScreen();
2483 AltScr = FALSE;
2484 RestoreCursor();
2485 }
2486 break;
2487 case 2004: // Bracketed Paste Mode
2488 BracketedPaste = FALSE;
2489 break;
2490 case 7727: // mintty Application Escape Mode
2491 AppliEscapeMode = FALSE;
2492 break;
2493 }
2494 }
2495
2496 void CSQ_n_Mode() // DECDSR
2497 {
2498 switch (Param[1]) {
2499 case 53:
2500 case 55:
2501 /* Locator Device Status Report -> Ready */
2502 SendCSIstr("?50n", 0);
2503 break;
2504 }
2505 }
2506
2507 void CSQuest(BYTE b)
2508 {
2509 switch (b) {
2510 case 'J': CSQSelScreenErase(); break; // DECSED
2511 case 'K': CSQSelLineErase(); break; // DECSEL
2512 case 'h': CSQ_h_Mode(); break; // DECSET
2513 case 'i': CSQ_i_Mode(); break; // DECMC
2514 case 'l': CSQ_l_Mode(); break; // DECRST
2515 case 'n': CSQ_n_Mode(); break; // DECDSR
2516 }
2517 }
2518
2519 void SoftReset()
2520 // called by software-reset escape sequence handler
2521 {
2522 UpdateStr();
2523 AutoRepeatMode = TRUE;
2524 DispEnableCaret(TRUE); // cursor on
2525 InsertMode = FALSE;
2526 RelativeOrgMode = FALSE;
2527 AppliKeyMode = FALSE;
2528 AppliCursorMode = FALSE;
2529 AppliEscapeMode = FALSE;
2530 if ((StatusLine>0) &&
2531 (CursorY == NumOfLines-1))
2532 MoveToMainScreen();
2533 CursorTop = 0;
2534 CursorBottom = NumOfLines-1-StatusLine;
2535 ResetCharSet();
2536
2537 /* Attribute */
2538 CharAttr = DefCharAttr;
2539 Special = FALSE;
2540 BuffSetCurCharAttr(CharAttr);
2541
2542 // status buffers
2543 ResetCurSBuffer();
2544 }
2545
2546 void CSExc(BYTE b)
2547 {
2548 switch (b) {
2549 case 'p':
2550 /* Software reset */
2551 SoftReset();
2552 break;
2553 }
2554 }
2555
2556 void CSDouble(BYTE b)
2557 {
2558 switch (b) {
2559 case 'p': // DECSCL
2560 /* Select terminal mode (software reset) */
2561 SoftReset();
2562 if (NParam > 0) {
2563 ChangeTerminalID();
2564 if (Param[1] >= 61 && Param[1] <= 65) {
2565 if (VTlevel > Param[1] - 60) {
2566 VTlevel = Param[1] - 60;
2567 }
2568 }
2569 else {
2570 VTlevel = 1;
2571 }
2572
2573 if (VTlevel < 2 || (NParam > 1 && Param[2] == 1))
2574 Send8BitMode = FALSE;
2575 else
2576 Send8BitMode = TRUE;
2577 }
2578 break;
2579
2580 case 'q': // DECSCA
2581 if (Param[1] < 0)
2582 Param[1] = 0;
2583 switch (Param[1]) {
2584 case 0:
2585 case 2:
2586 CharAttr.Attr2 &= ~Attr2Protect;
2587 BuffSetCurCharAttr(CharAttr);
2588 break;
2589 case 1:
2590 CharAttr.Attr2 |= Attr2Protect;
2591 BuffSetCurCharAttr(CharAttr);
2592 break;
2593 default:
2594 /* nothing to do */
2595 break;
2596 }
2597 break;
2598 }
2599 }
2600
2601 void CSDol(BYTE b)
2602 {
2603 switch (b) {
2604 case 'z': // DECERA
2605 case '{': // DECSERA
2606 if (Param[1] < 1 || NParam < 1) Param[1]=1;
2607 if (Param[2] < 1 || NParam < 2) Param[2]=1;
2608 if (Param[3] < 1 || NParam < 3) Param[3]=NumOfLines-StatusLine;
2609 if (Param[4] < 1 || NParam < 4) Param[4]=NumOfColumns;
2610 if (RelativeOrgMode) {
2611 Param[1] += CursorTop;
2612 if (Param[1] > CursorBottom) {
2613 Param[1] = CursorBottom + 1;
2614 }
2615 Param[3] += CursorTop;
2616 if (Param[3] > CursorBottom) {
2617 Param[3] = CursorBottom + 1;
2618 }
2619 }
2620 if (b == 'z') {
2621 BuffEraseBox(Param[2]-1, Param[1]-1, Param[4]-1, Param[3]-1);
2622 }
2623 else {
2624 BuffSelectEraseBox(Param[2]-1, Param[1]-1, Param[4]-1, Param[3]-1);
2625 }
2626 break;
2627
2628 case '}': // DECSASD
2629 if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2630 if (StatusLine==0) return;
2631 if ((Param[1]<1) && (CursorY==NumOfLines-1))
2632 MoveToMainScreen();
2633 else if ((Param[1]==1) && (CursorY<NumOfLines-1))
2634 MoveToStatusLine();
2635 break;
2636 case '~': // DECSSDT
2637 if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2638 if (Param[1]<=1)
2639 HideStatusLine();
2640 else if ((StatusLine==0) && (Param[1]==2))
2641 ShowStatusLine(1); // show
2642 break;
2643 }
2644 }
2645
2646 void CSQuote(BYTE b)
2647 {
2648 int i, x, y;
2649 switch (b) {
2650 case 'w': // Enable Filter Rectangle (DECEFR)
2651 if (MouseReportMode == IdMouseTrackDECELR) {
2652 if (DecLocatorFlag & DecLocatorPixel) {
2653 x = LastX + 1;
2654 y = LastY + 1;
2655 }
2656 else {
2657 DispConvWinToScreen(LastX, LastY, &x, &y, NULL);
2658 x++;
2659 y++;
2660 }
2661 FilterTop = (NParam<1 || Param[1]<1)? y : Param[1];
2662 FilterLeft = (NParam<2 || Param[2]<1)? x : Param[2];
2663 FilterBottom = (NParam<3 || Param[3]<1)? y : Param[3];
2664 FilterRight = (NParam<4 || Param[4]<1)? x : Param[4];
2665 if (FilterTop > FilterBottom) {
2666 i = FilterTop; FilterTop = FilterBottom; FilterBottom = i;
2667 }
2668 if (FilterLeft > FilterRight) {
2669 i = FilterLeft; FilterLeft = FilterRight; FilterRight = i;
2670 }
2671 DecLocatorFlag |= DecLocatorFiltered;
2672 DecLocatorReport(IdMouseEventMove, 0);
2673 }
2674 break;
2675
2676 case 'z': // Enable DEC Locator reporting (DECELR)
2677 if (Param[1] < 0) {
2678 Param[1] = 0;
2679 }
2680 switch (Param[1]) {
2681 case 0:
2682 if (MouseReportMode == IdMouseTrackDECELR) {
2683 MouseReportMode = IdMouseTrackNone;
2684 }
2685 break;
2686 case 1:
2687 if (ts.MouseEventTracking) {
2688 MouseReportMode = IdMouseTrackDECELR;
2689 DecLocatorFlag &= ~DecLocatorOneShot;
2690 }
2691 break;
2692 case 2:
2693 if (ts.MouseEventTracking) {
2694 MouseReportMode = IdMouseTrackDECELR;
2695 DecLocatorFlag |= DecLocatorOneShot;
2696 }
2697 break;
2698 }
2699 if (NParam > 1 && Param[2] == 1) {
2700 DecLocatorFlag |= DecLocatorPixel;
2701 }
2702 else {
2703 DecLocatorFlag &= ~DecLocatorPixel;
2704 }
2705 break;
2706
2707 case '{': // Select Locator Events (DECSLE)
2708 for (i=1; i<=NParam; i++) {
2709 if (Param[i] < 0) {
2710 Param[i] = 0;
2711 }
2712 switch (Param[i]) {
2713 case 0:
2714 DecLocatorFlag &= ~(DecLocatorButtonUp | DecLocatorButtonDown | DecLocatorFiltered);
2715 break;
2716 case 1:
2717 DecLocatorFlag |= DecLocatorButtonDown;
2718 break;
2719 case 2:
2720 DecLocatorFlag &= ~DecLocatorButtonDown;
2721 break;
2722 case 3:
2723 DecLocatorFlag |= DecLocatorButtonUp;
2724 break;
2725 case 4:
2726 DecLocatorFlag &= ~DecLocatorButtonUp;
2727 break;
2728 }
2729 }
2730 break;
2731
2732 case '|': // Request Locator Position (DECRQLP)
2733 DecLocatorReport(IdMouseEventCurStat, 0);
2734 break;
2735 }
2736 }
2737
2738 void CSSpace(BYTE b) {
2739 switch (b) {
2740 case 'q':
2741 if (ts.WindowFlag & WF_CURSORCHANGE) {
2742 if (NParam > 0) {
2743 if (Param[1] < 0) Param[1] = 0;
2744 switch (Param[1]) {
2745 case 0:
2746 case 1:
2747 ts.CursorShape = IdBlkCur;
2748 ts.NonblinkingCursor = FALSE;
2749 break;
2750 case 2:
2751 ts.CursorShape = IdBlkCur;
2752 ts.NonblinkingCursor = TRUE;
2753 break;
2754 case 3:
2755 ts.CursorShape = IdHCur;
2756 ts.NonblinkingCursor = FALSE;
2757 break;
2758 case 4:
2759 ts.CursorShape = IdHCur;
2760 ts.NonblinkingCursor = TRUE;
2761 break;
2762 case 5:
2763 ts.CursorShape = IdVCur;
2764 ts.NonblinkingCursor = FALSE;
2765 break;
2766 case 6:
2767 ts.CursorShape = IdVCur;
2768 ts.NonblinkingCursor = TRUE;
2769 break;
2770 default:
2771 return;
2772 }
2773 ChangeCaret();
2774 }
2775 }
2776 break;
2777 }
2778 }
2779
2780 void PrnParseCS(BYTE b) // printer mode
2781 {
2782 ParseMode = ModeFirst;
2783 switch (ICount) {
2784 /* no intermediate char */
2785 case 0:
2786 switch (Prv) {
2787 /* no private parameter */
2788 case 0:
2789 switch (b) {
2790 case 'i':
2791 if (Param[1]==4)
2792 {
2793 PrinterMode = FALSE;
2794 // clear prn buff
2795 WriteToPrnFile(0,FALSE);
2796 if (! AutoPrintMode)
2797 ClosePrnFile();
2798 return;
2799 }
2800 break;
2801 } /* of case Prv=0 */
2802 break;
2803 }
2804 break;
2805 /* one intermediate char */
2806 case 1: break;
2807 } /* of case Icount */
2808
2809 WriteToPrnFile(b,TRUE);
2810 }
2811
2812 void ParseCS(BYTE b) /* b is the final char */
2813 {
2814 if (PrinterMode) { // printer mode
2815 PrnParseCS(b);
2816 return;
2817 }
2818
2819 switch (ICount) {
2820 /* no intermediate char */
2821 case 0:
2822 switch (Prv) {
2823 /* no private parameter */
2824 case 0:
2825 switch (b) {
2826 // ISO/IEC 6429 / ECMA-48 Sequence
2827 case '@': CSInsertCharacter(); break; // ICH
2828 case 'A': CSCursorUp(); break; // CUU
2829 case 'B': CSCursorDown(); break; // CUD
2830 case 'C': CSCursorRight(); break; // CUF
2831 case 'D': CSCursorLeft(); break; // CUB
2832 case 'E': CSCursorDown1(); break; // CNL
2833 case 'F': CSCursorUp1(); break; // CPL
2834 case 'G': CSMoveToColumnN(); break; // CHA
2835 case 'H': CSMoveToXY(); break; // CUP
2836 case 'I': CSForwardTab(); break; // CHT
2837 case 'J': CSScreenErase(); break; // ED
2838 case 'K': CSLineErase(); break; // EL
2839 case 'L': CSInsertLine(); break; // IL
2840 case 'M': CSDeleteNLines(); break; // DL
2841 // case 'N': break; // EF -- Not support
2842 // case 'O': break; // EA -- Not support
2843 case 'P': CSDeleteCharacter(); break; // DCH
2844 // case 'Q': break; // SEE -- Not support
2845 // case 'R': break; // CPR -- Report only, ignore.
2846 case 'S': CSScrollUP(); break; // SU
2847 case 'T': CSScrollDown(); break; // SD
2848 // case 'U': break; // NP -- Not support
2849 // case 'V': break; // PP -- Not support
2850 // case 'W': break; // CTC -- Not support
2851 case 'X': CSEraseCharacter(); break; // ECH
2852 // case 'Y': break; // CVT -- Not support
2853 case 'Z': CSBackwardTab(); break; // CBT
2854 // case '[': break; // SRS -- Not support
2855 // case '\\': break; // PTX -- Not support
2856 // case ']': break; // SDS -- Not support
2857 // case '^': break; // SIMD -- Not support
2858 case '`': CSMoveToColumnN(); break; // HPA
2859 case 'a': CSCursorRight(); break; // HPR
2860 // case 'b': break; // REP -- Not support
2861 case 'c': AnswerTerminalType(); break; // DA
2862 case 'd': CSMoveToLineN(); break; // VPA
2863 case 'e': CSCursorDown(); break; // VPR
2864 case 'f': CSMoveToXY(); break; // HVP
2865 case 'g': CSDeleteTabStop(); break; // TBC
2866 case 'h': CS_h_Mode(); break; // SM
2867 case 'i': CS_i_Mode(); break; // MC
2868 case 'j': CSCursorLeft(); break; // HPB
2869 case 'k': CSCursorUp(); // VPB
2870 case 'l': CS_l_Mode(); break; // RM
2871 case 'm': CSSetAttr(); break; // SGR
2872 case 'n': CS_n_Mode(); break; // DSR
2873 // case 'o': break; // DAQ -- Not support
2874
2875 // Private Sequence
2876 case 'r': CSSetScrollRegion(); break; // DECSTBM
2877 case 's': SaveCursor(); break; // SCP (Save cursor (ANSI.SYS/SCO?))
2878 case 't': CSSunSequence(); break; // DECSLPP / Window manipulation(dtterm?)
2879 case 'u': RestoreCursor(); break; // RCP (Restore cursor (ANSI.SYS/SCO))
2880 } /* of case Prv=0 */
2881 break;
2882 /* private parameter = '=' */
2883 case '=': CSEQ(b); break;
2884 /* private parameter = '>' */
2885 case '>': CSGT(b); break;
2886 /* private parameter = '?' */
2887 case '?': CSQuest(b); break;
2888 } /* end of siwtch (Prv) */
2889 break;
2890 /* one intermediate char */
2891 case 1:
2892 switch (IntChar[1]) {
2893 /* intermediate char = ' ' */
2894 case ' ': CSSpace(b); break;
2895 /* intermediate char = '!' */
2896 case '!': CSExc(b); break;
2897 /* intermediate char = '"' */
2898 case '"': CSDouble(b); break;
2899 /* intermediate char = '$' */
2900 case '$': CSDol(b); break;
2901 /* intermediate char = '\'' */
2902 case '\'': CSQuote(b); break;
2903 }
2904 break;
2905 } /* of case Icount */
2906
2907 ParseMode = ModeFirst;
2908 }
2909
2910 void ControlSequence(BYTE b)
2911 {
2912 if ((b<=US) || (b>=0x80) && (b<=0x9F))
2913 ParseControl(b); /* ctrl char */
2914 else if ((b>=0x40) && (b<=0x7E))
2915 ParseCS(b); /* terminate char */
2916 else {
2917 if (PrinterMode)
2918 WriteToPrnFile(b,FALSE);
2919
2920 if ((b>=0x20) && (b<=0x2F))
2921 { /* intermediate char */
2922 if (ICount<IntCharMax) ICount++;
2923 IntChar[ICount] = b;
2924 }
2925 else if ((b>=0x30) && (b<=0x39))
2926 {
2927 if (Param[NParam] < 0)
2928 Param[NParam] = 0;
2929 if (Param[NParam]<1000)
2930 Param[NParam] = Param[NParam]*10 + b - 0x30;
2931 }
2932 else if (b==0x3B)
2933 {
2934 if (NParam < NParamMax)
2935 {
2936 NParam++;
2937 Param[NParam] = -1;
2938 }
2939 }
2940 else if ((b>=0x3C) && (b<=0x3F))
2941 { /* private char */
2942 if (FirstPrm) Prv = b;
2943 }
2944 else if (b>0xA0) {
2945 ParseMode=ModeFirst;
2946 ParseFirst(b);
2947 }
2948 }
2949 FirstPrm = FALSE;
2950 }
2951
2952 void RequestStatusString(unsigned char *StrBuff, int StrLen) {
2953 unsigned char RepStr[256];
2954 int len = 0;
2955
2956 switch (StrBuff[0]) {
2957 case '"':
2958 switch (StrBuff[1]) {
2959 case 'p': // DECSCL
2960 if (VTlevel > 1 && Send8BitMode) {
2961 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r6%d;0\"p", CLocale, VTlevel);
2962 }
2963 else {
2964 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r6%d;1\"p", CLocale, VTlevel);
2965 }
2966 break;
2967
2968 case 'q': // DECSCA
2969 if (CharAttr.Attr2 & Attr2Protect) {
2970 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r1\"q", CLocale);
2971 }
2972 else {
2973 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r0\"q", CLocale);
2974 }
2975 break;
2976 }
2977 break;
2978 case 'm': // SGR
2979 if (StrBuff[1] == 0) {
2980 RepStr[0] = '0';
2981 RepStr[1] = '$';
2982 RepStr[2] = 'r';
2983 len = 3;
2984 if (CharAttr.Attr & AttrBold) {
2985 RepStr[len++] = '1';
2986 RepStr[len++] = ';';
2987 }
2988 if (CharAttr.Attr & AttrUnder) {
2989 RepStr[len++] = '4';
2990 RepStr[len++] = ';';
2991 }
2992 if (CharAttr.Attr & AttrBlink) {
2993 RepStr[len++] = '5';
2994 RepStr[len++] = ';';
2995 }
2996 if (CharAttr.Attr & AttrReverse) {
2997 RepStr[len++] = '7';
2998 RepStr[len++] = ';';
2999 }
3000 if (len == 3) {
3001 RepStr[len++] = '0';
3002 }
3003 else {
3004 len--;
3005 }
3006 RepStr[len++] = 'm';
3007 RepStr[len] = 0;
3008 }
3009 break;
3010 case 'r': // DECSTBM
3011 if (StrBuff[1] == 0) {
3012 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r%d;%dr", CLocale, CursorTop+1, CursorBottom+1);
3013 }
3014 break;
3015 }
3016 if (len > 0) {
3017 SendDCSstr(RepStr, len);
3018 }
3019 else {
3020 SendDCSstr("1$r", 0);
3021 }
3022 }
3023
3024 void ParseDCS(BYTE Cmd, unsigned char *StrBuff, int len) {
3025 switch (ICount) {
3026 case 0:
3027 break;
3028 case 1:
3029 switch (IntChar[1]) {
3030 case '!':
3031 if (Cmd == '{') { // DECSTUI
3032 if (! (ts.TermFlag & TF_LOCKTUID)) {
3033 int i;
3034 for (i=0; i<8 && isxdigit(StrBuff[i]); i++) {
3035 if (islower(StrBuff[i])) {
3036 StrBuff[i] = toupper(StrBuff[i]);
3037 }
3038 }
3039 if (len == 8 && i == 8) {
3040 strncpy_s(ts.TerminalUID, sizeof(ts.TerminalUID), StrBuff, _TRUNCATE);
3041 }
3042 }
3043 }
3044 break;
3045 case '$':
3046 if (Cmd == 'q') { // DECRQSS
3047 RequestStatusString(StrBuff, len);
3048 }
3049 break;
3050 default:
3051 break;
3052 }
3053 break;
3054 default:
3055 break;
3056 }
3057 }
3058
3059 #define ModeDcsFirst 1
3060 #define ModeDcsString 2
3061 void DeviceControl(BYTE b)
3062 {
3063 static unsigned char StrBuff[256];
3064 static int DcsParseMode = ModeDcsFirst;
3065 static int StrLen;
3066 static BYTE Cmd;
3067
3068 if ((ESCFlag && (b=='\\')) || (b==ST && ts.KanjiCode!=IdSJIS)) {
3069 if (DcsParseMode == ModeDcsString) {
3070 StrBuff[StrLen] = 0;
3071 ParseDCS(Cmd, StrBuff, StrLen);
3072 }
3073 ESCFlag = FALSE;
3074 ParseMode = SavedMode;
3075 DcsParseMode = ModeDcsFirst;
3076 StrLen = 0;
3077 return;
3078 }
3079
3080 if (b==ESC) {
3081 ESCFlag = TRUE;
3082 return;
3083 }
3084 else {
3085 ESCFlag = FALSE;
3086 }
3087
3088 switch (DcsParseMode) {
3089 case ModeDcsFirst:
3090 if (b<=US) {
3091 ParseControl(b);
3092 }
3093 else if ((b>=0x20) && (b<=0x2F)) {
3094 if (ICount<IntCharMax) ICount++;
3095 IntChar[ICount] = b;
3096 }
3097 else if ((b>=0x30) && (b<=0x39)) {
3098 if (Param[NParam] < 0) Param[NParam] = 0;
3099 if (Param[NParam]<1000)
3100 Param[NParam] = Param[NParam]*10 + b - 0x30;
3101 }
3102 else if (b==0x3B) {
3103 if (NParam < NParamMax) {
3104 NParam++;
3105 Param[NParam] = -1;
3106 }
3107 }
3108 else if ((b>=0x40) && (b<=0x7E)) {
3109 if (ICount == 0 && b=='|') {
3110 ParseMode = ModeDCUserKey;
3111 if (Param[1] < 1) ClearUserKey();
3112 WaitKeyId = TRUE;
3113 NewKeyId = 0;
3114 }
3115 else {
3116 Cmd = b;
3117 DcsParseMode = ModeDcsString;
3118 }
3119 }
3120 else {
3121 ParseMode = ModeSOS;
3122 }
3123 break;
3124
3125 case ModeDcsString:
3126 if (b <= US && b != HT && b != CR) {
3127 ESCFlag = FALSE;
3128 ParseMode = SavedMode;
3129 DcsParseMode = ModeDcsFirst;
3130 StrLen = 0;
3131 }
3132 else if (StrLen < sizeof(StrBuff)-1) {
3133 StrBuff[StrLen++] = b;
3134 }
3135 break;
3136 }
3137 }
3138
3139 void DCUserKey(BYTE b)
3140 {
3141 if (ESCFlag && (b=='\\') || (b==ST && ts.KanjiCode!=IdSJIS))
3142 {
3143 if (! WaitKeyId) DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
3144 ESCFlag = FALSE;
3145 ParseMode = SavedMode;
3146 return;
3147 }
3148
3149 if (b==ESC)
3150 {
3151 ESCFlag = TRUE;
3152 return;
3153 }
3154 else ESCFlag = FALSE;
3155
3156 if (WaitKeyId)
3157 {
3158 if ((b>=0x30) && (b<=0x39))
3159 {
3160 if (NewKeyId<1000)
3161 NewKeyId = NewKeyId*10 + b - 0x30;
3162 }
3163 else if (b==0x2F)
3164 {
3165 WaitKeyId = FALSE;
3166 WaitHi = TRUE;
3167 NewKeyLen = 0;
3168 }
3169 }
3170 else {
3171 if (b==0x3B)
3172 {
3173 DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
3174 WaitKeyId = TRUE;
3175 NewKeyId = 0;
3176 }
3177 else {
3178 if (NewKeyLen < FuncKeyStrMax)
3179 {
3180 if (WaitHi)
3181 {
3182 NewKeyStr[NewKeyLen] = ConvHexChar(b) << 4;
3183 WaitHi = FALSE;
3184 }
3185 else {
3186 NewKeyStr[NewKeyLen] = NewKeyStr[NewKeyLen] +
3187 ConvHexChar(b);
3188 WaitHi = TRUE;
3189 NewKeyLen++;
3190 }
3191 }
3192 }
3193 }
3194 }
3195
3196 void IgnoreString(BYTE b)
3197 {
3198 if ((ESCFlag && (b=='\\')) ||
3199 (b<=US && b!=ESC && b!=HT) ||
3200 (b==ST && ts.KanjiCode!=IdSJIS))
3201 ParseMode = SavedMode;
3202
3203 if (b==ESC) ESCFlag = TRUE;
3204 else ESCFlag = FALSE;
3205 }
3206
3207 BOOL XsParseColor(char *colspec, COLORREF *color)
3208 {
3209 unsigned int r, g, b;
3210 // double dr, dg, db;
3211
3212 r = g = b = 255;
3213
3214 if (colspec == NULL || color == NULL) {
3215 return FALSE;
3216 }
3217
3218 if (_strnicmp(colspec, "rgb:", 4) == 0) {
3219 switch (strlen(colspec)) {
3220 case 9: // rgb:R/G/B
3221 if (sscanf(colspec, "rgb:%1x/%1x/%1x", &r, &g, &b) != 3) {
3222 return FALSE;
3223 }
3224 r *= 17; g *= 17; b *= 17;
3225 break;
3226 case 12: // rgb:RR/GG/BB
3227 if (sscanf(colspec, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) {
3228 return FALSE;
3229 }
3230 break;
3231 case 15: // rgb:RRR/GGG/BBB
3232 if (sscanf(colspec, "rgb:%3x/%3x/%3x", &r, &g, &b) != 3) {
3233 return FALSE;
3234 }
3235 r >>= 4; g >>= 4; b >>= 4;
3236 break;
3237 case 18: // rgb:RRRR/GGGG/BBBB
3238 if (sscanf(colspec, "rgb:%4x/%4x/%4x", &r, &g, &b) != 3) {
3239 return FALSE;
3240 }
3241 r >>= 8; g >>= 8; b >>= 8;
3242 break;
3243 default:
3244 return FALSE;
3245 }
3246 }
3247 // else if (_strnicmp(colspec, "rgbi:", 5) == 0) {
3248 // ; /* nothing to do */
3249 // }
3250 else if (colspec[0] == '#') {
3251 switch (strlen(colspec)) {
3252 case 4: // #RGB
3253 if (sscanf(colspec, "#%1x%1x%1x", &r, &g, &b) != 3) {
3254 return FALSE;
3255 }
3256 r <<= 4; g <<= 4; b <<= 4;
3257 break;
3258 case 7: // #RRGGBB
3259 if (sscanf(colspec, "#%2x%2x%2x", &r, &g, &b) != 3) {
3260 return FALSE;
3261 }
3262 break;
3263 case 10: // #RRRGGGBBB
3264 if (sscanf(colspec, "#%3x%3x%3x", &r, &g, &b) != 3) {
3265 return FALSE;
3266 }
3267 r >>= 4; g >>= 4; b >>= 4;
3268 break;
3269 case 13: // #RRRRGGGGBBBB
3270 if (sscanf(colspec, "#%4x%4x%4x", &r, &g, &b) != 3) {
3271 return FALSE;
3272 }
3273 r >>= 8; g >>= 8; b >>= 8;
3274 break;
3275 default:
3276 return FALSE;
3277 }
3278 }
3279 else {
3280 return FALSE;
3281 }
3282
3283 if (r > 255 || g > 255 || b > 255) {
3284 return FALSE;
3285 }
3286
3287 *color = RGB(r, g, b);
3288 return TRUE;
3289 }
3290
3291 #define ModeXsFirst 1
3292 #define ModeXsString 2
3293 #define ModeXsColorNum 3
3294 #define ModeXsColorSpec 4
3295 #define ModeXsEsc 5
3296 void XSequence(BYTE b)
3297 {
3298 static BYTE XsParseMode = ModeXsFirst, PrevMode;
3299 static char StrBuff[sizeof(ts.Title)];
3300 static unsigned int ColorNumber, StrLen;
3301 int len;
3302 COLORREF color;
3303
3304 switch (XsParseMode) {
3305 case ModeXsFirst:
3306 if (isdigit(b)) {
3307 if (Param[1] < 1000) {
3308 Param[1] = Param[1]*10 + b - '0';
3309 }
3310 }
3311 else if (b == ';') {
3312 StrBuff[0] = '\0';
3313 StrLen = 0;
3314 if (Param[1] == 4) {
3315 ColorNumber = 0;
3316 XsParseMode = ModeXsColorNum;
3317 }
3318 else {
3319 XsParseMode = ModeXsString;
3320 }
3321 }
3322 else {
3323 // Invalid Sequence. Ignore.
3324 Param[1] = -1;
3325 StrBuff[0] = '\0';
3326 StrLen = 0;
3327 XsParseMode = ModeXsString;
3328 }
3329 break;
3330 case ModeXsString:
3331 if ((b==ST && Accept8BitCtrl && !(ts.Language==IdJapanese && ts.KanjiCode==IdSJ