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 4291 - (show annotations) (download) (as text)
Tue Feb 1 05:27:32 2011 UTC (13 years, 2 months ago) by doda
File MIME type: text/x-csrc
File size: 102434 byte(s)
DCS/SOS/APC/PM の直後の文字が正しく表示できないのを修正。

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