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 4281 - (show annotations) (download) (as text)
Wed Jan 19 00:24:01 2011 UTC (13 years, 2 months ago) by doda
File MIME type: text/x-csrc
File size: 101628 byte(s)
DECRPSS を xterm に合わせられるようにした。
テスト用なので非公開。

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, SavedMode;
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 SavedMode = ParseMode;
940 ESCFlag = FALSE;
941 ICount = 0;
942 NParam = 1;
943 Param[1] = -1;
944 Prv = 0;
945 ParseMode = ModeDCS;
946 break;
947 case SOS:
948 SavedMode = ParseMode;
949 ESCFlag = FALSE;
950 ParseMode = ModeSOS;
951 break;
952 case CSI:
953 ICount = 0;
954 FirstPrm = TRUE;
955 NParam = 1;
956 Param[1] = -1;
957 Prv = 0;
958 ParseMode = ModeCSI;
959 break;
960 case OSC:
961 Param[1] = 0;
962 ParseMode = ModeXS;
963 break;
964 case PM:
965 case APC:
966 SavedMode = ParseMode;
967 ESCFlag = FALSE;
968 ParseMode = ModeSOS;
969 break;
970 }
971 }
972
973 void SaveCursor()
974 {
975 int i;
976 PStatusBuff Buff;
977
978 if ((StatusLine>0) &&
979 (CursorY==NumOfLines-1))
980 Buff = &SBuff2; // for status line
981 else if (AltScr)
982 Buff = &SBuff3; // for alternate screen
983 else
984 Buff = &SBuff1; // for main screen
985
986 Buff->CursorX = CursorX;
987 Buff->CursorY = CursorY;
988 Buff->Attr = CharAttr;
989 Buff->Glr[0] = Glr[0];
990 Buff->Glr[1] = Glr[1];
991 for (i=0 ; i<=3; i++)
992 Buff->Gn[i] = Gn[i];
993 Buff->AutoWrapMode = AutoWrapMode;
994 Buff->RelativeOrgMode = RelativeOrgMode;
995 }
996
997 void RestoreCursor()
998 {
999 int i;
1000 PStatusBuff Buff;
1001 UpdateStr();
1002
1003 if ((StatusLine>0) &&
1004 (CursorY==NumOfLines-1))
1005 Buff = &SBuff2; // for status line
1006 else if (AltScr)
1007 Buff = &SBuff3; // for alternate screen
1008 else
1009 Buff = &SBuff1; // for main screen
1010
1011 if (Buff->CursorX > NumOfColumns-1)
1012 Buff->CursorX = NumOfColumns-1;
1013 if (Buff->CursorY > NumOfLines-1-StatusLine)
1014 Buff->CursorY = NumOfLines-1-StatusLine;
1015 MoveCursor(Buff->CursorX,Buff->CursorY);
1016 CharAttr = Buff->Attr;
1017 Glr[0] = Buff->Glr[0];
1018 Glr[1] = Buff->Glr[1];
1019 for (i=0 ; i<=3; i++)
1020 Gn[i] = Buff->Gn[i];
1021 AutoWrapMode = Buff->AutoWrapMode;
1022 RelativeOrgMode = Buff->RelativeOrgMode;
1023 }
1024
1025 void AnswerTerminalType()
1026 {
1027 char Tmp[50];
1028
1029 if (ts.TerminalID<IdVT320)
1030 strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1031 else
1032 strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1033
1034 switch (ts.TerminalID) {
1035 case IdVT100:
1036 strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1037 break;
1038 case IdVT100J:
1039 strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1040 break;
1041 case IdVT101:
1042 strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1043 break;
1044 case IdVT102:
1045 strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1046 break;
1047 case IdVT102J:
1048 strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1049 break;
1050 case IdVT220J:
1051 strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1052 break;
1053 case IdVT282:
1054 strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1055 break;
1056 case IdVT320:
1057 strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1058 break;
1059 case IdVT382:
1060 strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1061 break;
1062 case IdVT420:
1063 strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1064 break;
1065 case IdVT520:
1066 strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1067 break;
1068 case IdVT525:
1069 strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1070 break;
1071 }
1072 strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1073
1074 CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1075 }
1076
1077 void ESCSpace(BYTE b)
1078 {
1079 switch (b) {
1080 case 'F': // S7C1T
1081 Send8BitMode = FALSE;
1082 break;
1083 case 'G': // S8C1T
1084 if (VTlevel >= 2) {
1085 Send8BitMode = TRUE;
1086 }
1087 break;
1088 }
1089 }
1090
1091 void ESCSharp(BYTE b)
1092 {
1093 switch (b) {
1094 case '8': /* Fill screen with "E" (DECALN) */
1095 BuffUpdateScroll();
1096 BuffFillWithE();
1097 CursorTop = 0;
1098 CursorBottom = NumOfLines-1-StatusLine;
1099 MoveCursor(0,0);
1100 ParseMode = ModeFirst;
1101 break;
1102 }
1103 }
1104
1105 /* select double byte code set */
1106 void ESCDBCSSelect(BYTE b)
1107 {
1108 int Dist;
1109
1110 if (ts.Language!=IdJapanese) return;
1111
1112 switch (ICount) {
1113 case 1:
1114 if ((b=='@') || (b=='B'))
1115 {
1116 Gn[0] = IdKanji; /* Kanji -> G0 */
1117 if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1118 Glr[0] = 0; /* G0->GL */
1119 }
1120 break;
1121 case 2:
1122 /* Second intermediate char must be
1123 '(' or ')' or '*' or '+'. */
1124 Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1125 if ((b=='1') || (b=='3') ||
1126 (b=='@') || (b=='B'))
1127 {
1128 Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1129 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1130 (Dist==0))
1131 Glr[0] = 0; /* G0->GL */
1132 }
1133 break;
1134 }
1135 }
1136
1137 void ESCSelectCode(BYTE b)
1138 {
1139 switch (b) {
1140 case '0':
1141 if (ts.AutoWinSwitch>0)
1142 ChangeEmu = IdTEK; /* enter TEK mode */
1143 break;
1144 }
1145 }
1146
1147 /* select single byte code set */
1148 void ESCSBCSSelect(BYTE b)
1149 {
1150 int Dist;
1151
1152 /* Intermediate char must be
1153 '(' or ')' or '*' or '+'. */
1154 Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1155
1156 switch (b) {
1157 case '0': Gn[Dist] = IdSpecial; break;
1158 case '<': Gn[Dist] = IdASCII; break;
1159 case '>': Gn[Dist] = IdASCII; break;
1160 case 'A': Gn[Dist] = IdASCII; break;
1161 case 'B': Gn[Dist] = IdASCII; break;
1162 case 'H': Gn[Dist] = IdASCII; break;
1163 case 'I':
1164 if (ts.Language==IdJapanese)
1165 Gn[Dist] = IdKatakana;
1166 break;
1167 case 'J': Gn[Dist] = IdASCII; break;
1168 }
1169
1170 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1171 (Dist==0))
1172 Glr[0] = 0; /* G0->GL */
1173 }
1174
1175 void PrnParseEscape(BYTE b) // printer mode
1176 {
1177 int i;
1178
1179 ParseMode = ModeFirst;
1180 switch (ICount) {
1181 /* no intermediate char */
1182 case 0:
1183 switch (b) {
1184 case '[': /* CSI */
1185 ICount = 0;
1186 FirstPrm = TRUE;
1187 NParam = 1;
1188 Param[1] = -1;
1189 Prv = 0;
1190 WriteToPrnFile(ESC,FALSE);
1191 WriteToPrnFile('[',FALSE);
1192 ParseMode = ModeCSI;
1193 return;
1194 } /* end of case Icount=0 */
1195 break;
1196 /* one intermediate char */
1197 case 1:
1198 switch (IntChar[1]) {
1199 case '$':
1200 if (! DirectPrn)
1201 {
1202 ESCDBCSSelect(b);
1203 return;
1204 }
1205 break;
1206 case '(':
1207 case ')':
1208 case '*':
1209 case '+':
1210 if (! DirectPrn)
1211 {
1212 ESCSBCSSelect(b);
1213 return;
1214 }
1215 break;
1216 }
1217 break;
1218 /* two intermediate char */
1219 case 2:
1220 if ((! DirectPrn) &&
1221 (IntChar[1]=='$') &&
1222 ('('<=IntChar[2]) &&
1223 (IntChar[2]<='+'))
1224 {
1225 ESCDBCSSelect(b);
1226 return;
1227 }
1228 break;
1229 }
1230 // send the uninterpreted sequence to printer
1231 WriteToPrnFile(ESC,FALSE);
1232 for (i=1; i<=ICount; i++)
1233 WriteToPrnFile(IntChar[i],FALSE);
1234 WriteToPrnFile(b,TRUE);
1235 }
1236
1237 void ParseEscape(BYTE b) /* b is the final char */
1238 {
1239 if (PrinterMode) { // printer mode
1240 PrnParseEscape(b);
1241 return;
1242 }
1243
1244 switch (ICount) {
1245 /* no intermediate char */
1246 case 0:
1247 switch (b) {
1248 case '6': // DECBI
1249 if (CursorX == 0) {
1250 BuffScrollRight(1);
1251 }
1252 else {
1253 CursorX--;
1254 }
1255 case '7': SaveCursor(); break;
1256 case '8': RestoreCursor(); break;
1257 case '9': // DECFI
1258 if (CursorX == NumOfColumns-1) {
1259 BuffScrollLeft(1);
1260 }
1261 else {
1262 CursorX++;
1263 }
1264 case '=': AppliKeyMode = TRUE; break;
1265 case '>': AppliKeyMode = FALSE; break;
1266 case 'D': /* IND */
1267 LineFeed(0,TRUE);
1268 break;
1269 case 'E': /* NEL */
1270 MoveCursor(0,CursorY);
1271 LineFeed(0,TRUE);
1272 break;
1273 case 'H': /* HTS */
1274 SetTabStop();
1275 break;
1276 case 'M': /* RI */
1277 CursorUpWithScroll();
1278 break;
1279 case 'N': /* SS2 */
1280 GLtmp = 2;
1281 SSflag = TRUE;
1282 break;
1283 case 'O': /* SS3 */
1284 GLtmp = 3;
1285 SSflag = TRUE;
1286 break;
1287 case 'P': /* DCS */
1288 SavedMode = ParseMode;
1289 ESCFlag = FALSE;
1290 NParam = 1;
1291 Param[1] = -1;
1292 ParseMode = ModeDCS;
1293 return;
1294 case 'X': /* SOS */
1295 SavedMode = ParseMode;
1296 ESCFlag = FALSE;
1297 ParseMode = ModeSOS;
1298 return;
1299 case 'Z': AnswerTerminalType(); break;
1300 case '[': /* CSI */
1301 ICount = 0;
1302 FirstPrm = TRUE;
1303 NParam = 1;
1304 Param[1] = -1;
1305 Prv = 0;
1306 ParseMode = ModeCSI;
1307 return;
1308 case '\\': break; /* ST */
1309 case ']': /* XTERM sequence (OSC) */
1310 NParam = 1;
1311 Param[1] = 0;
1312 ParseMode = ModeXS;
1313 return;
1314 case '^':
1315 case '_': /* PM, APC */
1316 SavedMode = ParseMode;
1317 ESCFlag = FALSE;
1318 ParseMode = ModeSOS;
1319 return;
1320 case 'c': /* Hardware reset */
1321 HideStatusLine();
1322 ResetTerminal();
1323 ClearUserKey();
1324 ClearBuffer();
1325 if (ts.PortType==IdSerial) // reset serial port
1326 CommResetSerial(&ts, &cv, TRUE);
1327 break;
1328 case 'g': /* Visual Bell (screen original?) */
1329 VisualBell();
1330 break;
1331 case 'n': Glr[0] = 2; break; /* LS2 */
1332 case 'o': Glr[0] = 3; break; /* LS3 */
1333 case '|': Glr[1] = 3; break; /* LS3R */
1334 case '}': Glr[1] = 2; break; /* LS2R */
1335 case '~': Glr[1] = 1; break; /* LS1R */
1336 } /* end of case Icount=0 */
1337 break;
1338 /* one intermediate char */
1339 case 1:
1340 switch (IntChar[1]) {
1341 case ' ': ESCSpace(b); break;
1342 case '#': ESCSharp(b); break;
1343 case '$': ESCDBCSSelect(b); break;
1344 case '%': break;
1345 case '(':
1346 case ')':
1347 case '*':
1348 case '+':
1349 ESCSBCSSelect(b);
1350 break;
1351 }
1352 break;
1353 /* two intermediate char */
1354 case 2:
1355 if ((IntChar[1]=='$') &&
1356 ('('<=IntChar[2]) &&
1357 (IntChar[2]<='+'))
1358 ESCDBCSSelect(b);
1359 else if ((IntChar[1]=='%') &&
1360 (IntChar[2]=='!'))
1361 ESCSelectCode(b);
1362 break;
1363 }
1364 ParseMode = ModeFirst;
1365 }
1366
1367 void EscapeSequence(BYTE b)
1368 {
1369 if (b<=US)
1370 ParseControl(b);
1371 else if ((b>=0x20) && (b<=0x2F))
1372 {
1373 if (ICount<IntCharMax) ICount++;
1374 IntChar[ICount] = b;
1375 }
1376 else if ((b>=0x30) && (b<=0x7E))
1377 ParseEscape(b);
1378 else if ((b>=0x80) && (b<=0x9F))
1379 ParseControl(b);
1380 else if (b>=0xA0) {
1381 ParseMode=ModeFirst;
1382 ParseFirst(b);
1383 }
1384
1385 JustAfterESC = FALSE;
1386 }
1387
1388 void CSInsertCharacter()
1389 {
1390 // Insert space characters at cursor
1391 int Count;
1392
1393 BuffUpdateScroll();
1394 if (Param[1]<1) Param[1] = 1;
1395 Count = Param[1];
1396 BuffInsertSpace(Count);
1397 }
1398
1399 void CSCursorUp()
1400 {
1401 if (Param[1]<1) Param[1] = 1;
1402
1403 if (CursorY >= CursorTop)
1404 {
1405 if (CursorY-Param[1] > CursorTop)
1406 MoveCursor(CursorX,CursorY-Param[1]);
1407 else
1408 MoveCursor(CursorX,CursorTop);
1409 }
1410 else {
1411 if (CursorY > 0)
1412 MoveCursor(CursorX,CursorY-Param[1]);
1413 else
1414 MoveCursor(CursorX,0);
1415 }
1416 }
1417
1418 void CSCursorUp1()
1419 {
1420 MoveCursor(0,CursorY);
1421 CSCursorUp();
1422 }
1423
1424 void CSCursorDown()
1425 {
1426 if (Param[1]<1) Param[1] = 1;
1427
1428 if (CursorY <= CursorBottom)
1429 {
1430 if (CursorY+Param[1] < CursorBottom)
1431 MoveCursor(CursorX,CursorY+Param[1]);
1432 else
1433 MoveCursor(CursorX,CursorBottom);
1434 }
1435 else {
1436 if (CursorY < NumOfLines-StatusLine-1)
1437 MoveCursor(CursorX,CursorY+Param[1]);
1438 else
1439 MoveCursor(CursorX,NumOfLines-StatusLine);
1440 }
1441 }
1442
1443 void CSCursorDown1()
1444 {
1445 MoveCursor(0,CursorY);
1446 CSCursorDown();
1447 }
1448
1449 void CSScreenErase()
1450 {
1451 if (Param[1] == -1) Param[1] = 0;
1452 BuffUpdateScroll();
1453 switch (Param[1]) {
1454 case 0:
1455 // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1456 // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1457 // �����������������B(2005.5.29 yutaka)
1458 // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1459 if (ts.ScrollWindowClearScreen &&
1460 (CursorX == 0 && CursorY == 0)) {
1461 // Erase screen (scroll out)
1462 BuffClearScreen();
1463 UpdateWindow(HVTWin);
1464
1465 } else {
1466 // Erase characters from cursor to the end of screen
1467 BuffEraseCurToEnd();
1468 }
1469 break;
1470
1471 case 1:
1472 // Erase characters from home to cursor
1473 BuffEraseHomeToCur();
1474 break;
1475
1476 case 2:
1477 // Erase screen (scroll out)
1478 BuffClearScreen();
1479 UpdateWindow(HVTWin);
1480 break;
1481 }
1482 }
1483
1484 void CSQSelScreenErase()
1485 {
1486 if (Param[1] == -1) Param[1] = 0;
1487 BuffUpdateScroll();
1488 switch (Param[1]) {
1489 case 0:
1490 // Erase characters from cursor to end
1491 BuffSelectedEraseCurToEnd();
1492 break;
1493
1494 case 1:
1495 // Erase characters from home to cursor
1496 BuffSelectedEraseHomeToCur();
1497 break;
1498
1499 case 2:
1500 // Erase entire screen
1501 BuffSelectedEraseScreen();
1502 break;
1503 }
1504 }
1505
1506 void CSInsertLine()
1507 {
1508 // Insert lines at current position
1509 int Count, YEnd;
1510
1511 if (CursorY < CursorTop) return;
1512 if (CursorY > CursorBottom) return;
1513 if (Param[1]<1) Param[1] = 1;
1514 Count = Param[1];
1515
1516 YEnd = CursorBottom;
1517 if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1518 if (Count > YEnd+1 - CursorY) Count = YEnd+1 - CursorY;
1519
1520 BuffInsertLines(Count,YEnd);
1521 }
1522
1523 void CSLineErase()
1524 {
1525 if (Param[1] == -1) Param[1] = 0;
1526 BuffUpdateScroll();
1527 switch (Param[1]) {
1528 /* erase char from cursor to end of line */
1529 case 0:
1530 BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1531 break;
1532 /* erase char from start of line to cursor */
1533 case 1:
1534 BuffEraseCharsInLine(0,CursorX+1);
1535 break;
1536 /* erase entire line */
1537 case 2:
1538 BuffEraseCharsInLine(0,NumOfColumns);
1539 break;
1540 }
1541 }
1542
1543 void CSQSelLineErase()
1544 {
1545 if (Param[1] == -1) Param[1] = 0;
1546 BuffUpdateScroll();
1547 switch (Param[1]) {
1548 /* erase char from cursor to end of line */
1549 case 0:
1550 BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1551 break;
1552 /* erase char from start of line to cursor */
1553 case 1:
1554 BuffSelectedEraseCharsInLine(0,CursorX+1);
1555 break;
1556 /* erase entire line */
1557 case 2:
1558 BuffSelectedEraseCharsInLine(0,NumOfColumns);
1559 break;
1560 }
1561 }
1562
1563 void CSDeleteNLines()
1564 // Delete lines from current line
1565 {
1566 int Count, YEnd;
1567
1568 if (CursorY < CursorTop) return;
1569 if (CursorY > CursorBottom) return;
1570 Count = Param[1];
1571 if (Count<1) Count = 1;
1572
1573 YEnd = CursorBottom;
1574 if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1575 if (Count > YEnd+1-CursorY) Count = YEnd+1-CursorY;
1576 BuffDeleteLines(Count,YEnd);
1577 }
1578
1579 void CSDeleteCharacter()
1580 {
1581 // Delete characters in current line from cursor
1582
1583 if (Param[1]<1) Param[1] = 1;
1584 BuffUpdateScroll();
1585 BuffDeleteChars(Param[1]);
1586 }
1587
1588 void CSEraseCharacter()
1589 {
1590 if (Param[1]<1) Param[1] = 1;
1591 BuffUpdateScroll();
1592 BuffEraseChars(Param[1]);
1593 }
1594
1595 void CSScrollUP()
1596 {
1597 if (Param[1]<1) Param[1] = 1;
1598 BuffUpdateScroll();
1599 BuffRegionScrollUpNLines(Param[1]);
1600 }
1601
1602 void CSScrollDown()
1603 {
1604 if (Param[1]<1) Param[1] = 1;
1605 BuffUpdateScroll();
1606 BuffRegionScrollDownNLines(Param[1]);
1607 }
1608
1609 void CSForwardTab()
1610 {
1611 if (Param[1]<1) Param[1] = 1;
1612 CursorForwardTab(Param[1], AutoWrapMode);
1613 }
1614
1615 void CSBackwardTab()
1616 {
1617 if (Param[1]<1) Param[1] = 1;
1618 CursorBackwardTab(Param[1]);
1619 }
1620
1621 void CSMoveToColumnN()
1622 {
1623 if (Param[1]<1) Param[1] = 1;
1624 Param[1]--;
1625 if (Param[1] < 0) Param[1] = 0;
1626 if (Param[1] > NumOfColumns-1) Param[1] = NumOfColumns-1;
1627 MoveCursor(Param[1],CursorY);
1628 }
1629
1630 void CSCursorRight()
1631 {
1632 if (Param[1]<1) Param[1] = 1;
1633 if (CursorX + Param[1] > NumOfColumns-1)
1634 MoveCursor(NumOfColumns-1,CursorY);
1635 else
1636 MoveCursor(CursorX+Param[1],CursorY);
1637 }
1638
1639 void CSCursorLeft()
1640 {
1641 if (Param[1]<1) Param[1] = 1;
1642 if (CursorX-Param[1] < 0)
1643 MoveCursor(0,CursorY);
1644 else
1645 MoveCursor(CursorX-Param[1],CursorY);
1646 }
1647
1648 void CSMoveToLineN()
1649 {
1650 if (Param[1]<1) Param[1] = 1;
1651 if (RelativeOrgMode)
1652 {
1653 if (CursorTop+Param[1]-1 > CursorBottom)
1654 MoveCursor(CursorX,CursorBottom);
1655 else
1656 MoveCursor(CursorX,CursorTop+Param[1]-1);
1657 }
1658 else {
1659 if (Param[1] > NumOfLines-StatusLine)
1660 MoveCursor(CursorX,NumOfLines-1-StatusLine);
1661 else
1662 MoveCursor(CursorX,Param[1]-1);
1663 }
1664 }
1665
1666 void CSMoveToXY()
1667 {
1668 int NewX, NewY;
1669
1670 if (Param[1]<1) Param[1] = 1;
1671 if ((NParam < 2) || (Param[2]<1)) Param[2] = 1;
1672 NewX = Param[2] - 1;
1673 if (NewX > NumOfColumns-1) NewX = NumOfColumns-1;
1674
1675 if ((StatusLine>0) && (CursorY==NumOfLines-1))
1676 NewY = CursorY;
1677 else if (RelativeOrgMode)
1678 {
1679 NewY = CursorTop + Param[1] - 1;
1680 if (NewY > CursorBottom) NewY = CursorBottom;
1681 }
1682 else {
1683 NewY = Param[1] - 1;
1684 if (NewY > NumOfLines-1-StatusLine)
1685 NewY = NumOfLines-1-StatusLine;
1686 }
1687 MoveCursor(NewX,NewY);
1688 }
1689
1690 void CSDeleteTabStop()
1691 {
1692 if (Param[1]==-1) Param[1] = 0;
1693 ClearTabStop(Param[1]);
1694 }
1695
1696 void CS_h_Mode() // SM
1697 {
1698 switch (Param[1]) {
1699 case 2: // KAM
1700 KeybEnabled = FALSE; break;
1701 case 4: // IRM
1702 InsertMode = TRUE; break;
1703 case 12: // SRM
1704 ts.LocalEcho = 0;
1705 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1706 TelChangeEcho();
1707 break;
1708 case 20: // LF/NL
1709 LFMode = TRUE;
1710 ts.CRSend = IdCRLF;
1711 cv.CRSend = IdCRLF;
1712 break;
1713 case 33: // WYSTCURM
1714 if (ts.WindowFlag & WF_CURSORCHANGE) {
1715 ts.NonblinkingCursor = TRUE;
1716 ChangeCaret();
1717 }
1718 break;
1719 case 34: // WYULCURM
1720 if (ts.WindowFlag & WF_CURSORCHANGE) {
1721 ts.CursorShape = IdHCur;
1722 ChangeCaret();
1723 }
1724 break;
1725 }
1726 }
1727
1728 void CS_i_Mode() // MC
1729 {
1730 if (Param[1]==-1) Param[1] = 0;
1731 switch (Param[1]) {
1732 /* print screen */
1733 // PrintEX -- TRUE: print screen
1734 // FALSE: scroll region
1735 case 0: BuffPrint(! PrintEX); break;
1736 /* printer controller mode off */
1737 case 4: break; /* See PrnParseCS() */
1738 /* printer controller mode on */
1739 case 5:
1740 if (! AutoPrintMode)
1741 OpenPrnFile();
1742 DirectPrn = (ts.PrnDev[0]!=0);
1743 PrinterMode = TRUE;
1744 break;
1745 }
1746 }
1747
1748 void CS_l_Mode() // RM
1749 {
1750 switch (Param[1]) {
1751 case 2: // KAM
1752 KeybEnabled = TRUE; break;
1753 case 4: // IRM
1754 InsertMode = FALSE; break;
1755 case 12: // SRM
1756 ts.LocalEcho = 1;
1757 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1758 TelChangeEcho();
1759 break;
1760 case 20: // LF/NL
1761 LFMode = FALSE;
1762 ts.CRSend = IdCR;
1763 cv.CRSend = IdCR;
1764 break;
1765 case 33: // WYSTCURM
1766 if (ts.WindowFlag & WF_CURSORCHANGE) {
1767 ts.NonblinkingCursor = FALSE;
1768 ChangeCaret();
1769 }
1770 break;
1771 case 34: // WYULCURM
1772 if (ts.WindowFlag & WF_CURSORCHANGE) {
1773 ts.CursorShape = IdBlkCur;
1774 ChangeCaret();
1775 }
1776 break;
1777 }
1778 }
1779
1780 void CS_n_Mode() // DSR
1781 {
1782 char Report[16];
1783 int Y, len;
1784
1785 switch (Param[1]) {
1786 case 5:
1787 /* Device Status Report -> Ready */
1788 SendCSIstr("0n", 0);
1789 break;
1790 case 6:
1791 /* Cursor Position Report */
1792 Y = CursorY+1;
1793 if ((StatusLine>0) &&
1794 (Y==NumOfLines))
1795 Y = 1;
1796 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, CursorX+1);
1797 SendCSIstr(Report, len);
1798 break;
1799 }
1800 }
1801
1802 void CSSetAttr() // SGR
1803 {
1804 int i, P;
1805
1806 UpdateStr();
1807 for (i=1 ; i<=NParam ; i++)
1808 {
1809 P = Param[i];
1810 if (P<0) P = 0;
1811 switch (P) {
1812 case 0: /* Clear all */
1813 if (CharAttr.Attr2 & Attr2Protect) {
1814 CharAttr = DefCharAttr;
1815 CharAttr.Attr2 |= Attr2Protect;
1816 }
1817 else {
1818 CharAttr = DefCharAttr;
1819 }
1820 BuffSetCurCharAttr(CharAttr);
1821 break;
1822
1823 case 1: /* Bold */
1824 CharAttr.Attr |= AttrBold;
1825 BuffSetCurCharAttr(CharAttr);
1826 break;
1827
1828 case 4: /* Under line */
1829 CharAttr.Attr |= AttrUnder;
1830 BuffSetCurCharAttr(CharAttr);
1831 break;
1832
1833 case 5: /* Blink */
1834 CharAttr.Attr |= AttrBlink;
1835 BuffSetCurCharAttr(CharAttr);
1836 break;
1837
1838 case 7: /* Reverse */
1839 CharAttr.Attr |= AttrReverse;
1840 BuffSetCurCharAttr(CharAttr);
1841 break;
1842
1843 case 22: /* Bold off */
1844 CharAttr.Attr &= ~ AttrBold;
1845 BuffSetCurCharAttr(CharAttr);
1846 break;
1847
1848 case 24: /* Under line off */
1849 CharAttr.Attr &= ~ AttrUnder;
1850 BuffSetCurCharAttr(CharAttr);
1851 break;
1852
1853 case 25: /* Blink off */
1854 CharAttr.Attr &= ~ AttrBlink;
1855 BuffSetCurCharAttr(CharAttr);
1856 break;
1857
1858 case 27: /* Reverse off */
1859 CharAttr.Attr &= ~ AttrReverse;
1860 BuffSetCurCharAttr(CharAttr);
1861 break;
1862
1863 case 30:
1864 case 31:
1865 case 32:
1866 case 33:
1867 case 34:
1868 case 35:
1869 case 36:
1870 case 37: /* text color */
1871 CharAttr.Attr2 |= Attr2Fore;
1872 CharAttr.Fore = P - 30;
1873 BuffSetCurCharAttr(CharAttr);
1874 break;
1875
1876 case 38: /* text color (256color mode) */
1877 if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1878 i++;
1879 if (i < NParam) {
1880 P = Param[++i];
1881 if (P<0) {
1882 P = 0;
1883 }
1884 CharAttr.Attr2 |= Attr2Fore;
1885 CharAttr.Fore = P;
1886 BuffSetCurCharAttr(CharAttr);
1887 }
1888 }
1889 break;
1890
1891 case 39: /* Reset text color */
1892 CharAttr.Attr2 &= ~ Attr2Fore;
1893 CharAttr.Fore = AttrDefaultFG;
1894 BuffSetCurCharAttr(CharAttr);
1895 break;
1896
1897 case 40:
1898 case 41:
1899 case 42:
1900 case 43:
1901 case 44:
1902 case 45:
1903 case 46:
1904 case 47: /* Back color */
1905 CharAttr.Attr2 |= Attr2Back;
1906 CharAttr.Back = P - 40;
1907 BuffSetCurCharAttr(CharAttr);
1908 break;
1909
1910 case 48: /* Back color (256color mode) */
1911 if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1912 i++;
1913 if (i < NParam) {
1914 P = Param[++i];
1915 if (P<0) {
1916 P = 0;
1917 }
1918 CharAttr.Attr2 |= Attr2Back;
1919 CharAttr.Back = P;
1920 BuffSetCurCharAttr(CharAttr);
1921 }
1922 }
1923 break;
1924
1925 case 49: /* Reset back color */
1926 CharAttr.Attr2 &= ~ Attr2Back;
1927 CharAttr.Back = AttrDefaultBG;
1928 BuffSetCurCharAttr(CharAttr);
1929 break;
1930
1931 case 90:
1932 case 91:
1933 case 92:
1934 case 93:
1935 case 94:
1936 case 95:
1937 case 96:
1938 case 97: /* aixterm style text color */
1939 if (ts.ColorFlag & CF_AIXTERM16) {
1940 CharAttr.Attr2 |= Attr2Fore;
1941 CharAttr.Fore = P - 90 + 8;
1942 BuffSetCurCharAttr(CharAttr);
1943 }
1944 break;
1945
1946 case 100:
1947 if (! (ts.ColorFlag & CF_AIXTERM16)) {
1948 /* Reset text and back color */
1949 CharAttr.Attr2 &= ~ (Attr2Fore | Attr2Back);
1950 CharAttr.Fore = AttrDefaultFG;
1951 CharAttr.Back = AttrDefaultBG;
1952 BuffSetCurCharAttr(CharAttr);
1953 break;
1954 }
1955 /* fall through to aixterm style back color */
1956
1957 case 101:
1958 case 102:
1959 case 103:
1960 case 104:
1961 case 105:
1962 case 106:
1963 case 107: /* aixterm style back color */
1964 if (ts.ColorFlag & CF_AIXTERM16) {
1965 CharAttr.Attr2 |= Attr2Back;
1966 CharAttr.Back = P - 100 + 8;
1967 BuffSetCurCharAttr(CharAttr);
1968 }
1969 break;
1970 }
1971 }
1972 }
1973
1974 void CSSetScrollRegion()
1975 {
1976 if ((StatusLine>0) &&
1977 (CursorY==NumOfLines-1))
1978 {
1979 MoveCursor(0,CursorY);
1980 return;
1981 }
1982 if (Param[1]<1) Param[1] =1;
1983 if ((NParam < 2) | (Param[2]<1))
1984 Param[2] = NumOfLines-StatusLine;
1985 Param[1]--;
1986 Param[2]--;
1987 if (Param[1] > NumOfLines-1-StatusLine)
1988 Param[1] = NumOfLines-1-StatusLine;
1989 if (Param[2] > NumOfLines-1-StatusLine)
1990 Param[2] = NumOfLines-1-StatusLine;
1991 if (Param[1] >= Param[2]) return;
1992 CursorTop = Param[1];
1993 CursorBottom = Param[2];
1994 if (RelativeOrgMode) MoveCursor(0,CursorTop);
1995 else MoveCursor(0,0);
1996 }
1997
1998 void CSSunSequence() /* Sun terminal private sequences */
1999 {
2000 int x, y, len;
2001 char Report[TitleBuffSize*2+10];
2002
2003 switch (Param[1]) {
2004 case 1: // De-iconify window
2005 if (ts.WindowFlag & WF_WINDOWCHANGE)
2006 DispShowWindow(WINDOW_RESTORE);
2007 break;
2008 case 2: // Iconify window
2009 if (ts.WindowFlag & WF_WINDOWCHANGE)
2010 DispShowWindow(WINDOW_MINIMIZE);
2011 break;
2012 case 3: // set window position
2013 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2014 if (NParam < 2) Param[2] = 0;
2015 if (NParam < 3) Param[3] = 0;
2016 DispMoveWindow(Param[2], Param[3]);
2017 }
2018 break;
2019 case 4: // set window size
2020 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2021 if (NParam < 2) Param[2] = 0;
2022 if (NParam < 3) Param[3] = 0;
2023 DispResizeWin(Param[3], Param[2]);
2024 }
2025 break;
2026 case 5: // Raise window
2027 if (ts.WindowFlag & WF_WINDOWCHANGE)
2028 DispShowWindow(WINDOW_RAISE);
2029 break;
2030 case 6: // Lower window
2031 if (ts.WindowFlag & WF_WINDOWCHANGE)
2032 DispShowWindow(WINDOW_LOWER);
2033 break;
2034 case 7: // Refresh window
2035 if (ts.WindowFlag & WF_WINDOWCHANGE)
2036 DispShowWindow(WINDOW_REFRESH);
2037 break;
2038 case 8: /* set terminal size */
2039 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2040 if ((Param[2]<=1) || (NParam<2)) Param[2] = 24;
2041 if ((Param[3]<=1) || (NParam<3)) Param[3] = 80;
2042 ChangeTerminalSize(Param[3],Param[2]);
2043 }
2044 break;
2045 case 9: // Maximize/Restore window
2046 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2047 if (NParam < 2 || Param[2] == 0) {
2048 DispShowWindow(WINDOW_RESTORE);
2049 }
2050 else if (Param[2] == 1) {
2051 DispShowWindow(WINDOW_MAXIMIZE);
2052 }
2053 }
2054 break;
2055 case 11: // Report window state
2056 if (ts.WindowFlag & WF_WINDOWREPORT) {
2057 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
2058 SendCSIstr(Report, len);
2059 }
2060 break;
2061 case 13: // Report window position
2062 if (ts.WindowFlag & WF_WINDOWREPORT) {
2063 DispGetWindowPos(&x, &y);
2064 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%d;%dt", CLocale, x, y);
2065 SendCSIstr(Report, len);
2066 }
2067 break;
2068 case 14: /* get window size */
2069 if (ts.WindowFlag & WF_WINDOWREPORT) {
2070 DispGetWindowSize(&x, &y);
2071 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "4;%d;%dt", CLocale, y, x);
2072 SendCSIstr(Report, len);
2073 }
2074 break;
2075 case 18: /* get terminal size */
2076 if (ts.WindowFlag & WF_WINDOWREPORT) {
2077 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%u;t", CLocale,
2078 NumOfLines-StatusLine, NumOfColumns);
2079 SendCSIstr(Report, len);
2080 }
2081 break;
2082 case 19: // Report display size (character)
2083 if (ts.WindowFlag & WF_WINDOWREPORT) {
2084 DispGetRootWinSize(&x, &y);
2085 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
2086 SendCSIstr(Report, len);
2087 }
2088 break;
2089 case 20: // Report icon label
2090 switch (ts.WindowFlag & WF_TITLEREPORT) {
2091 case IdTitleReportIgnore:
2092 // nothing to do
2093 break;
2094 case IdTitleReportAccept:
2095 switch (ts.AcceptTitleChangeRequest) {
2096 case IdTitleChangeRequestOff:
2097 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2098 break;
2099 case IdTitleChangeRequestAhead:
2100 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, cv.TitleRemote, ts.Title);
2101 break;
2102 case IdTitleChangeRequestLast:
2103 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, ts.Title, cv.TitleRemote);
2104 break;
2105 default:
2106 if (cv.TitleRemote[0] == 0) {
2107 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2108 }
2109 else {
2110 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, cv.TitleRemote);
2111 }
2112 }
2113 SendOSCstr(Report, len);
2114 break;
2115 default: // IdTitleReportEmpty:
2116 SendOSCstr("L", 0);
2117 break;
2118 }
2119 break;
2120 case 21: // Report window title
2121 switch (ts.WindowFlag & WF_TITLEREPORT) {
2122 case IdTitleReportIgnore:
2123 // nothing to do
2124 break;
2125 case IdTitleReportAccept:
2126 switch (ts.AcceptTitleChangeRequest) {
2127 case IdTitleChangeRequestOff:
2128 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2129 break;
2130 case IdTitleChangeRequestAhead:
2131 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, cv.TitleRemote, ts.Title);
2132 break;
2133 case IdTitleChangeRequestLast:
2134 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, ts.Title, cv.TitleRemote);
2135 break;
2136 default:
2137 if (cv.TitleRemote[0] == 0) {
2138 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2139 }
2140 else {
2141 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, cv.TitleRemote);
2142 }
2143 }
2144 SendOSCstr(Report, len);
2145 break;
2146 default: // IdTitleReportEmpty:
2147 SendOSCstr("l", 0);
2148 break;
2149 }
2150 break;
2151 }
2152 }
2153
2154 void CSLT(BYTE b)
2155 {
2156 switch (b) {
2157 case 'r':
2158 if (CanUseIME()) {
2159 SetIMEOpenStatus(IMEstat);
2160 }
2161 break;
2162
2163 case 's':
2164 if (CanUseIME()) {
2165 IMEstat = GetIMEOpenStatus();
2166 }
2167 break;
2168
2169 case 't':
2170 if (CanUseIME()) {
2171 SetIMEOpenStatus(Param[1] == 1);
2172 }
2173 break;
2174 }
2175 }
2176
2177 void CSEQ(BYTE b)
2178 {
2179 char Report[16];
2180 int len;
2181
2182 switch (b) {
2183 case 'c': /* Tertiary terminal report (Tertiary DA) */
2184 if (Param[1] < 1) {
2185 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "!|%8s", CLocale, ts.TerminalUID);
2186 SendDCSstr(Report, len);
2187 }
2188 break;
2189 }
2190 }
2191
2192 void CSGT(BYTE b)
2193 {
2194 switch (b) {
2195 case 'c': /* second terminal report (Secondary DA) */
2196 if (Param[1] < 1) {
2197 SendCSIstr(">32;100;2c", 0); /* VT382 */
2198 }
2199 break;
2200 case 'J': // IO-8256 terminal
2201 if (Param[1]==3) {
2202 if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2203 if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2204 if (Param[4] < 1 || NParam < 4) Param[4] = NumOfLines-StatusLine;
2205 if (Param[5] < 1 || NParam < 5) Param[5] = NumOfColumns;
2206 BuffEraseBox(Param[3]-1, Param[2]-1, Param[5]-1, Param[4]-1);
2207 }
2208 break;
2209 case 'K': // IO-8256 terminal
2210 switch (Param[1]) {
2211 case 3:
2212 if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2213 if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2214 BuffEraseCharsInLine(Param[2]-1, Param[3]-Param[2]+1);
2215 break;
2216 case 5:
2217 if (NParam < 2) Param[2] = 0;
2218 if (NParam < 3) Param[3] = 0;
2219 switch (Param[2]) {
2220 case 3:
2221 case 4:
2222 case 5:
2223 case 6: // Draw Line
2224 BuffDrawLine(CharAttr, Param[2], Param[3]);
2225 break;
2226
2227 case 12: // Text color
2228 if ((Param[3]>=0) && (Param[3]<=7)) {
2229 switch (Param[3]) {
2230 case 3: CharAttr.Fore = IdBlue; break;
2231 case 4: CharAttr.Fore = IdCyan; break;
2232 case 5: CharAttr.Fore = IdYellow; break;
2233 case 6: CharAttr.Fore = IdMagenta; break;
2234 default: CharAttr.Fore = Param[3]; break;
2235 }
2236 CharAttr.Attr2 |= Attr2Fore;
2237 BuffSetCurCharAttr(CharAttr);
2238 }
2239 break;
2240 }
2241 break;
2242 }
2243 break;
2244 }
2245 }
2246
2247 void CSQExchangeColor() // DECSCNM / Visual Bell
2248 {
2249 COLORREF ColorRef;
2250
2251 BuffUpdateScroll();
2252
2253 if (ts.ColorFlag & CF_REVERSECOLOR) {
2254 ColorRef = ts.VTColor[0];
2255 ts.VTColor[0] = ts.VTReverseColor[0];
2256 ts.VTReverseColor[0] = ColorRef;
2257 ColorRef = ts.VTColor[1];
2258 ts.VTColor[1] = ts.VTReverseColor[1];
2259 ts.VTReverseColor[1] = ColorRef;
2260 }
2261 else {
2262 ColorRef = ts.VTColor[0];
2263 ts.VTColor[0] = ts.VTColor[1];
2264 ts.VTColor[1] = ColorRef;
2265 }
2266
2267 ColorRef = ts.VTBoldColor[0];
2268 ts.VTBoldColor[0] = ts.VTBoldColor[1];
2269 ts.VTBoldColor[1] = ColorRef;
2270
2271 ColorRef = ts.VTBlinkColor[0];
2272 ts.VTBlinkColor[0] = ts.VTBlinkColor[1];
2273 ts.VTBlinkColor[1] = ColorRef;
2274
2275 ColorRef = ts.URLColor[0];
2276 ts.URLColor[0] = ts.URLColor[1];
2277 ts.URLColor[1] = ColorRef;
2278
2279 ts.ColorFlag ^= CF_REVERSEVIDEO;
2280
2281 #ifdef ALPHABLEND_TYPE2
2282 BGExchangeColor();
2283 #endif
2284 DispChangeBackground();
2285 UpdateWindow(HVTWin);
2286 }
2287
2288 void CSQChangeColumnMode(int width) // DECCOLM
2289 {
2290 ChangeTerminalSize(width, NumOfLines-StatusLine);
2291 if ((ts.TermFlag & TF_CLEARONRESIZE) == 0) {
2292 MoveCursor(0, 0);
2293 BuffClearScreen();
2294 UpdateWindow(HVTWin);
2295 }
2296 }
2297
2298 void CSQ_h_Mode() // DECSET
2299 {
2300 int i;
2301
2302 for (i = 1 ; i<=NParam ; i++)
2303 switch (Param[i]) {
2304 case 1: AppliCursorMode = TRUE; break; // DECCKM
2305 case 3: CSQChangeColumnMode(132); break; // DECCOLM
2306 case 5: /* Reverse Video (DECSCNM) */
2307 if (!(ts.ColorFlag & CF_REVERSEVIDEO))
2308 CSQExchangeColor(); /* Exchange text/back color */
2309 break;
2310 case 6: // DECOM
2311 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2312 MoveCursor(0,CursorY);
2313 else {
2314 RelativeOrgMode = TRUE;
2315 MoveCursor(0,CursorTop);
2316 }
2317 break;
2318 case 7: AutoWrapMode = TRUE; break; // DECAWM
2319 case 8: AutoRepeatMode = TRUE; break; // DECARM
2320 case 9: /* X10 Mouse Tracking */
2321 if (ts.MouseEventTracking)
2322 MouseReportMode = IdMouseTrackX10;
2323 break;
2324 case 12: /* att610 cursor blinking */
2325 if (ts.WindowFlag & WF_CURSORCHANGE) {
2326 ts.NonblinkingCursor = FALSE;
2327 ChangeCaret();
2328 }
2329 break;
2330 case 19: PrintEX = TRUE; break; // DECPEX
2331 case 25: DispEnableCaret(TRUE); break; // cursor on (DECTCEM)
2332 case 38: // DECTEK
2333 if (ts.AutoWinSwitch>0)
2334 ChangeEmu = IdTEK; /* Enter TEK Mode */
2335 break;
2336 case 47: // Alternate Screen Buffer
2337 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2338 BuffSaveScreen();
2339 AltScr = TRUE;
2340 }
2341 break;
2342 case 59:
2343 if (ts.Language==IdJapanese)
2344 { /* kanji terminal */
2345 Gn[0] = IdASCII;
2346 Gn[1] = IdKatakana;
2347 Gn[2] = IdKatakana;
2348 Gn[3] = IdKanji;
2349 Glr[0] = 0;
2350 if ((ts.KanjiCode==IdJIS) &&
2351 (ts.JIS7Katakana==0))
2352 Glr[1] = 2; // 8-bit katakana
2353 else
2354 Glr[1] = 3;
2355 }
2356 break;
2357 case 66: AppliKeyMode = TRUE; break; // DECNKM
2358 case 67: ts.BSKey = IdBS; break; // DECBKM
2359 case 1000: // Mouse Tracking
2360 if (ts.MouseEventTracking)
2361 MouseReportMode = IdMouseTrackVT200;
2362 break;
2363 case 1001: // Hilite Mouse Tracking
2364 if (ts.MouseEventTracking)
2365 MouseReportMode = IdMouseTrackVT200Hl;
2366 break;
2367 case 1002: // Button-Event Mouse Tracking
2368 if (ts.MouseEventTracking)
2369 MouseReportMode = IdMouseTrackBtnEvent;
2370 break;
2371 case 1003: // Any-Event Mouse Tracking
2372 if (ts.MouseEventTracking)
2373 MouseReportMode = IdMouseTrackAllEvent;
2374 break;
2375 case 1004: // Focus Report
2376 if (ts.MouseEventTracking)
2377 FocusReportMode = TRUE;
2378 break;
2379 case 1047: // Alternate Screen Buffer
2380 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2381 BuffSaveScreen();
2382 AltScr = TRUE;
2383 }
2384 break;
2385 case 1048: // Save Cursor Position (Alternate Screen Buffer)
2386 if (ts.TermFlag & TF_ALTSCR) {
2387 SaveCursor();
2388 }
2389 break;
2390 case 1049: // Alternate Screen Buffer
2391 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2392 SaveCursor();
2393 BuffSaveScreen();
2394 BuffClearScreen();
2395 AltScr = TRUE;
2396 }
2397 break;
2398 case 2004: // Bracketed Paste Mode
2399 BracketedPaste = TRUE;
2400 break;
2401 case 7727: // mintty Application Escape Mode
2402 AppliEscapeMode = TRUE;
2403 break;
2404 }
2405 }
2406
2407 void CSQ_i_Mode() // DECMC
2408 {
2409 if (Param[1]==-1) Param[1] = 0;
2410 switch (Param[1]) {
2411 case 1:
2412 OpenPrnFile();
2413 BuffDumpCurrentLine(LF);
2414 if (! AutoPrintMode)
2415 ClosePrnFile();
2416 break;
2417 /* auto print mode off */
2418 case 4:
2419 if (AutoPrintMode)
2420 {
2421 ClosePrnFile();
2422 AutoPrintMode = FALSE;
2423 }
2424 break;
2425 /* auto print mode on */
2426 case 5:
2427 if (! AutoPrintMode)
2428 {
2429 OpenPrnFile();
2430 AutoPrintMode = TRUE;
2431 }
2432 break;
2433 }
2434 }
2435
2436 void CSQ_l_Mode() // DECRST
2437 {
2438 int i;
2439
2440 for (i = 1 ; i <= NParam ; i++)
2441 switch (Param[i]) {
2442 case 1: AppliCursorMode = FALSE; break; // DECCKM
2443 case 3: CSQChangeColumnMode(80); break; // DECCOLM
2444 case 5: /* Normal Video (DECSCNM) */
2445 if (ts.ColorFlag & CF_REVERSEVIDEO)
2446 CSQExchangeColor(); /* Exchange text/back color */
2447 break;
2448 case 6: // DECOM
2449 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2450 MoveCursor(0,CursorY);
2451 else {
2452 RelativeOrgMode = FALSE;
2453 MoveCursor(0,0);
2454 }
2455 break;
2456 case 7: AutoWrapMode = FALSE; break; // DECAWM
2457 case 8: AutoRepeatMode = FALSE; break; // DECARM
2458 case 9: MouseReportMode = IdMouseTrackNone; break; /* X10 Mouse Tracking */
2459 case 12: /* att610 cursor blinking */
2460 if (ts.WindowFlag & WF_CURSORCHANGE) {
2461 ts.NonblinkingCursor = TRUE;
2462 ChangeCaret();
2463 }
2464 break;
2465 case 19: PrintEX = FALSE; break; // DECPEX
2466 case 25: DispEnableCaret(FALSE); break; // cursor off (DECTCEM)
2467 case 47: // Alternate Screen Buffer
2468 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2469 BuffRestoreScreen();
2470 AltScr = FALSE;
2471 }
2472 break;
2473 case 59:
2474 if (ts.Language==IdJapanese)
2475 { /* katakana terminal */
2476 Gn[0] = IdASCII;
2477 Gn[1] = IdKatakana;
2478 Gn[2] = IdKatakana;
2479 Gn[3] = IdKanji;
2480 Glr[0] = 0;
2481 if ((ts.KanjiCode==IdJIS) &&
2482 (ts.JIS7Katakana==0))
2483 Glr[1] = 2; // 8-bit katakana
2484 else
2485 Glr[1] = 3;
2486 }
2487 break;
2488 case 66: AppliKeyMode = FALSE; break; // DECNKM
2489 case 67: ts.BSKey = IdDEL; break; // DECBKM
2490 case 1000: // Mouse Tracking
2491 case 1001: // Hilite Mouse Tracking
2492 case 1002: // Button-Event Mouse Tracking
2493 case 1003: // Any-Event Mouse Tracking
2494 MouseReportMode = IdMouseTrackNone;
2495 break;
2496 case 1004: FocusReportMode = FALSE; break; // Focus Report
2497 case 1047: // Alternate Screen Buffer
2498 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2499 BuffClearScreen();
2500 BuffRestoreScreen();
2501 AltScr = FALSE;
2502 }
2503 break;
2504 case 1048: // Save Cursor Position (Alternate Screen Buffer)
2505 if (ts.TermFlag & TF_ALTSCR) {
2506 RestoreCursor();
2507 }
2508 break;
2509 case 1049: // Alternate Screen Buffer
2510 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2511 BuffClearScreen();
2512 BuffRestoreScreen();
2513 AltScr = FALSE;
2514 RestoreCursor();
2515 }
2516 break;
2517 case 2004: // Bracketed Paste Mode
2518 BracketedPaste = FALSE;
2519 break;
2520 case 7727: // mintty Application Escape Mode
2521 AppliEscapeMode = FALSE;
2522 break;
2523 }
2524 }
2525
2526 void CSQ_n_Mode() // DECDSR
2527 {
2528 switch (Param[1]) {
2529 case 53:
2530 case 55:
2531 /* Locator Device Status Report -> Ready */
2532 SendCSIstr("?50n", 0);
2533 break;
2534 }
2535 }
2536
2537 void CSQuest(BYTE b)
2538 {
2539 switch (b) {
2540 case 'J': CSQSelScreenErase(); break; // DECSED
2541 case 'K': CSQSelLineErase(); break; // DECSEL
2542 case 'h': CSQ_h_Mode(); break; // DECSET
2543 case 'i': CSQ_i_Mode(); break; // DECMC
2544 case 'l': CSQ_l_Mode(); break; // DECRST
2545 case 'n': CSQ_n_Mode(); break; // DECDSR
2546 }
2547 }
2548
2549 void SoftReset()
2550 // called by software-reset escape sequence handler
2551 {
2552 UpdateStr();
2553 AutoRepeatMode = TRUE;
2554 DispEnableCaret(TRUE); // cursor on
2555 InsertMode = FALSE;
2556 RelativeOrgMode = FALSE;
2557 AppliKeyMode = FALSE;
2558 AppliCursorMode = FALSE;
2559 AppliEscapeMode = FALSE;
2560 if ((StatusLine>0) &&
2561 (CursorY == NumOfLines-1))
2562 MoveToMainScreen();
2563 CursorTop = 0;
2564 CursorBottom = NumOfLines-1-StatusLine;
2565 ResetCharSet();
2566
2567 /* Attribute */
2568 CharAttr = DefCharAttr;
2569 Special = FALSE;
2570 BuffSetCurCharAttr(CharAttr);
2571
2572 // status buffers
2573 ResetCurSBuffer();
2574
2575 // Saved IME status
2576 IMEstat = FALSE;
2577 }
2578
2579 void CSExc(BYTE b)
2580 {
2581 switch (b) {
2582 case 'p':
2583 /* Software reset */
2584 SoftReset();
2585 break;
2586 }
2587 }
2588
2589 void CSDouble(BYTE b)
2590 {
2591 switch (b) {
2592 case 'p': // DECSCL
2593 /* Select terminal mode (software reset) */
2594 SoftReset();
2595 if (NParam > 0) {
2596 ChangeTerminalID();
2597 if (Param[1] >= 61 && Param[1] <= 65) {
2598 if (VTlevel > Param[1] - 60) {
2599 VTlevel = Param[1] - 60;
2600 }
2601 }
2602 else {
2603 VTlevel = 1;
2604 }
2605
2606 if (VTlevel < 2 || (NParam > 1 && Param[2] == 1))
2607 Send8BitMode = FALSE;
2608 else
2609 Send8BitMode = TRUE;
2610 }
2611 break;
2612
2613 case 'q': // DECSCA
2614 if (Param[1] < 0)
2615 Param[1] = 0;
2616 switch (Param[1]) {
2617 case 0:
2618 case 2:
2619 CharAttr.Attr2 &= ~Attr2Protect;
2620 BuffSetCurCharAttr(CharAttr);
2621 break;
2622 case 1:
2623 CharAttr.Attr2 |= Attr2Protect;
2624 BuffSetCurCharAttr(CharAttr);
2625 break;
2626 default:
2627 /* nothing to do */
2628 break;
2629 }
2630 break;
2631 }
2632 }
2633
2634 void CSDol(BYTE b)
2635 {
2636 switch (b) {
2637 case 'z': // DECERA
2638 case '{': // DECSERA
2639 if (Param[1] < 1 || NParam < 1) Param[1]=1;
2640 if (Param[2] < 1 || NParam < 2) Param[2]=1;
2641 if (Param[3] < 1 || NParam < 3) Param[3]=NumOfLines-StatusLine;
2642 if (Param[4] < 1 || NParam < 4) Param[4]=NumOfColumns;
2643 if (RelativeOrgMode) {
2644 Param[1] += CursorTop;
2645 if (Param[1] > CursorBottom) {
2646 Param[1] = CursorBottom + 1;
2647 }
2648 Param[3] += CursorTop;
2649 if (Param[3] > CursorBottom) {
2650 Param[3] = CursorBottom + 1;
2651 }
2652 }
2653 if (b == 'z') {
2654 BuffEraseBox(Param[2]-1, Param[1]-1, Param[4]-1, Param[3]-1);
2655 }
2656 else {
2657 BuffSelectEraseBox(Param[2]-1, Param[1]-1, Param[4]-1, Param[3]-1);
2658 }
2659 break;
2660
2661 case '}': // DECSASD
2662 if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2663 if (StatusLine==0) return;
2664 if ((Param[1]<1) && (CursorY==NumOfLines-1))
2665 MoveToMainScreen();
2666 else if ((Param[1]==1) && (CursorY<NumOfLines-1))
2667 MoveToStatusLine();
2668 break;
2669 case '~': // DECSSDT
2670 if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2671 if (Param[1]<=1)
2672 HideStatusLine();
2673 else if ((StatusLine==0) && (Param[1]==2))
2674 ShowStatusLine(1); // show
2675 break;
2676 }
2677 }
2678
2679 void CSQuote(BYTE b)
2680 {
2681 int i, x, y;
2682 switch (b) {
2683 case 'w': // Enable Filter Rectangle (DECEFR)
2684 if (MouseReportMode == IdMouseTrackDECELR) {
2685 if (DecLocatorFlag & DecLocatorPixel) {
2686 x = LastX + 1;
2687 y = LastY + 1;
2688 }
2689 else {
2690 DispConvWinToScreen(LastX, LastY, &x, &y, NULL);
2691 x++;
2692 y++;
2693 }
2694 FilterTop = (NParam<1 || Param[1]<1)? y : Param[1];
2695 FilterLeft = (NParam<2 || Param[2]<1)? x : Param[2];
2696 FilterBottom = (NParam<3 || Param[3]<1)? y : Param[3];
2697 FilterRight = (NParam<4 || Param[4]<1)? x : Param[4];
2698 if (FilterTop > FilterBottom) {
2699 i = FilterTop; FilterTop = FilterBottom; FilterBottom = i;
2700 }
2701 if (FilterLeft > FilterRight) {
2702 i = FilterLeft; FilterLeft = FilterRight; FilterRight = i;
2703 }
2704 DecLocatorFlag |= DecLocatorFiltered;
2705 DecLocatorReport(IdMouseEventMove, 0);
2706 }
2707 break;
2708
2709 case 'z': // Enable DEC Locator reporting (DECELR)
2710 if (Param[1] < 0) {
2711 Param[1] = 0;
2712 }
2713 switch (Param[1]) {
2714 case 0:
2715 if (MouseReportMode == IdMouseTrackDECELR) {
2716 MouseReportMode = IdMouseTrackNone;
2717 }
2718 break;
2719 case 1:
2720 if (ts.MouseEventTracking) {
2721 MouseReportMode = IdMouseTrackDECELR;
2722 DecLocatorFlag &= ~DecLocatorOneShot;
2723 }
2724 break;
2725 case 2:
2726 if (ts.MouseEventTracking) {
2727 MouseReportMode = IdMouseTrackDECELR;
2728 DecLocatorFlag |= DecLocatorOneShot;
2729 }
2730 break;
2731 }
2732 if (NParam > 1 && Param[2] == 1) {
2733 DecLocatorFlag |= DecLocatorPixel;
2734 }
2735 else {
2736 DecLocatorFlag &= ~DecLocatorPixel;
2737 }
2738 break;
2739
2740 case '{': // Select Locator Events (DECSLE)
2741 for (i=1; i<=NParam; i++) {
2742 if (Param[i] < 0) {
2743 Param[i] = 0;
2744 }
2745 switch (Param[i]) {
2746 case 0:
2747 DecLocatorFlag &= ~(DecLocatorButtonUp | DecLocatorButtonDown | DecLocatorFiltered);
2748 break;
2749 case 1:
2750 DecLocatorFlag |= DecLocatorButtonDown;
2751 break;
2752 case 2:
2753 DecLocatorFlag &= ~DecLocatorButtonDown;
2754 break;
2755 case 3:
2756 DecLocatorFlag |= DecLocatorButtonUp;
2757 break;
2758 case 4:
2759 DecLocatorFlag &= ~DecLocatorButtonUp;
2760 break;
2761 }
2762 }
2763 break;
2764
2765 case '|': // Request Locator Position (DECRQLP)
2766 DecLocatorReport(IdMouseEventCurStat, 0);
2767 break;
2768 }
2769 }
2770
2771 void CSSpace(BYTE b) {
2772 switch (b) {
2773 case 'q':
2774 if (ts.WindowFlag & WF_CURSORCHANGE) {
2775 if (NParam > 0) {
2776 if (Param[1] < 0) Param[1] = 0;
2777 switch (Param[1]) {
2778 case 0:
2779 case 1:
2780 ts.CursorShape = IdBlkCur;
2781 ts.NonblinkingCursor = FALSE;
2782 break;
2783 case 2:
2784 ts.CursorShape = IdBlkCur;
2785 ts.NonblinkingCursor = TRUE;
2786 break;
2787 case 3:
2788 ts.CursorShape = IdHCur;
2789 ts.NonblinkingCursor = FALSE;
2790 break;
2791 case 4:
2792 ts.CursorShape = IdHCur;
2793 ts.NonblinkingCursor = TRUE;
2794 break;
2795 case 5:
2796 ts.CursorShape = IdVCur;
2797 ts.NonblinkingCursor = FALSE;
2798 break;
2799 case 6:
2800 ts.CursorShape = IdVCur;
2801 ts.NonblinkingCursor = TRUE;
2802 break;
2803 default:
2804 return;
2805 }
2806 ChangeCaret();
2807 }
2808 }
2809 break;
2810 }
2811 }
2812
2813 void PrnParseCS(BYTE b) // printer mode
2814 {
2815 ParseMode = ModeFirst;
2816 switch (ICount) {
2817 /* no intermediate char */
2818 case 0:
2819 switch (Prv) {
2820 /* no private parameter */
2821 case 0:
2822 switch (b) {
2823 case 'i':
2824 if (Param[1]==4)
2825 {
2826 PrinterMode = FALSE;
2827 // clear prn buff
2828 WriteToPrnFile(0,FALSE);
2829 if (! AutoPrintMode)
2830 ClosePrnFile();
2831 return;
2832 }
2833 break;
2834 } /* of case Prv=0 */
2835 break;
2836 }
2837 break;
2838 /* one intermediate char */
2839 case 1: break;
2840 } /* of case Icount */
2841
2842 WriteToPrnFile(b,TRUE);
2843 }
2844
2845 void ParseCS(BYTE b) /* b is the final char */
2846 {
2847 if (PrinterMode) { // printer mode
2848 PrnParseCS(b);
2849 return;
2850 }
2851
2852 switch (ICount) {
2853 /* no intermediate char */
2854 case 0:
2855 switch (Prv) {
2856 /* no private parameter */
2857 case 0:
2858 switch (b) {
2859 // ISO/IEC 6429 / ECMA-48 Sequence
2860 case '@': CSInsertCharacter(); break; // ICH
2861 case 'A': CSCursorUp(); break; // CUU
2862 case 'B': CSCursorDown(); break; // CUD
2863 case 'C': CSCursorRight(); break; // CUF
2864 case 'D': CSCursorLeft(); break; // CUB
2865 case 'E': CSCursorDown1(); break; // CNL
2866 case 'F': CSCursorUp1(); break; // CPL
2867 case 'G': CSMoveToColumnN(); break; // CHA
2868 case 'H': CSMoveToXY(); break; // CUP
2869 case 'I': CSForwardTab(); break; // CHT
2870 case 'J': CSScreenErase(); break; // ED
2871 case 'K': CSLineErase(); break; // EL
2872 case 'L': CSInsertLine(); break; // IL
2873 case 'M': CSDeleteNLines(); break; // DL
2874 // case 'N': break; // EF -- Not support
2875 // case 'O': break; // EA -- Not support
2876 case 'P': CSDeleteCharacter(); break; // DCH
2877 // case 'Q': break; // SEE -- Not support
2878 // case 'R': break; // CPR -- Report only, ignore.
2879 case 'S': CSScrollUP(); break; // SU
2880 case 'T': CSScrollDown(); break; // SD
2881 // case 'U': break; // NP -- Not support
2882 // case 'V': break; // PP -- Not support
2883 // case 'W': break; // CTC -- Not support
2884 case 'X': CSEraseCharacter(); break; // ECH
2885 // case 'Y': break; // CVT -- Not support
2886 case 'Z': CSBackwardTab(); break; // CBT
2887 // case '[': break; // SRS -- Not support
2888 // case '\\': break; // PTX -- Not support
2889 // case ']': break; // SDS -- Not support
2890 // case '^': break; // SIMD -- Not support
2891 case '`': CSMoveToColumnN(); break; // HPA
2892 case 'a': CSCursorRight(); break; // HPR
2893 // case 'b': break; // REP -- Not support
2894 case 'c': AnswerTerminalType(); break; // DA
2895 case 'd': CSMoveToLineN(); break; // VPA
2896 case 'e': CSCursorDown(); break; // VPR
2897 case 'f': CSMoveToXY(); break; // HVP
2898 case 'g': CSDeleteTabStop(); break; // TBC
2899 case 'h': CS_h_Mode(); break; // SM
2900 case 'i': CS_i_Mode(); break; // MC
2901 case 'j': CSCursorLeft(); break; // HPB
2902 case 'k': CSCursorUp(); // VPB
2903 case 'l': CS_l_Mode(); break; // RM
2904 case 'm': CSSetAttr(); break; // SGR
2905 case 'n': CS_n_Mode(); break; // DSR
2906 // case 'o': break; // DAQ -- Not support
2907
2908 // Private Sequence
2909 case 'r': CSSetScrollRegion(); break; // DECSTBM
2910 case 's': SaveCursor(); break; // SCP (Save cursor (ANSI.SYS/SCO?))
2911 case 't': CSSunSequence(); break; // DECSLPP / Window manipulation(dtterm?)
2912 case 'u': RestoreCursor(); break; // RCP (Restore cursor (ANSI.SYS/SCO))
2913 } /* of case Prv=0 */
2914 break;
2915 /* private parameter = '<' */
2916 case '<': CSLT(b); break;
2917 /* private parameter = '=' */
2918 case '=': CSEQ(b); break;
2919 /* private parameter = '>' */
2920 case '>': CSGT(b); break;
2921 /* private parameter = '?' */
2922 case '?': CSQuest(b); break;
2923 } /* end of siwtch (Prv) */
2924 break;
2925 /* one intermediate char */
2926 case 1:
2927 switch (IntChar[1]) {
2928 /* intermediate char = ' ' */
2929 case ' ': CSSpace(b); break;
2930 /* intermediate char = '!' */
2931 case '!': CSExc(b); break;
2932 /* intermediate char = '"' */
2933 case '"': CSDouble(b); break;
2934 /* intermediate char = '$' */
2935 case '$': CSDol(b); break;
2936 /* intermediate char = '\'' */
2937 case '\'': CSQuote(b); break;
2938 }
2939 break;
2940 } /* of case Icount */
2941
2942 ParseMode = ModeFirst;
2943 }
2944
2945 void ControlSequence(BYTE b)
2946 {
2947 if ((b<=US) || (b>=0x80) && (b<=0x9F))
2948 ParseControl(b); /* ctrl char */
2949 else if ((b>=0x40) && (b<=0x7E))
2950 ParseCS(b); /* terminate char */
2951 else {
2952 if (PrinterMode)
2953 WriteToPrnFile(b,FALSE);
2954
2955 if ((b>=0x20) && (b<=0x2F))
2956 { /* intermediate char */
2957 if (ICount<IntCharMax) ICount++;
2958 IntChar[ICount] = b;
2959 }
2960 else if ((b>=0x30) && (b<=0x39))
2961 {
2962 if (Param[NParam] < 0)
2963 Param[NParam] = 0;
2964 if (Param[NParam]<1000)
2965 Param[NParam] = Param[NParam]*10 + b - 0x30;
2966 }
2967 else if (b==0x3B)
2968 {
2969 if (NParam < NParamMax)
2970 {
2971 NParam++;
2972 Param[NParam] = -1;
2973 }
2974 }
2975 else if ((b>=0x3C) && (b<=0x3F))
2976 { /* private char */
2977 if (FirstPrm) Prv = b;
2978 }
2979 else if (b>0xA0) {
2980 ParseMode=ModeFirst;
2981 ParseFirst(b);
2982 }
2983 }
2984 FirstPrm = FALSE;
2985 }
2986
2987 void RequestStatusString(unsigned char *StrBuff, int StrLen) // DECRQSS
2988 {
2989 unsigned char RepStr[256];
2990 int len = 0;
2991
2992 switch (StrBuff[0]) {
2993 case '"':
2994 switch (StrBuff[1]) {
2995 case 'p': // DECSCL
2996 if (VTlevel > 1 && Send8BitMode) {
2997 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r6%d;0\"p", CLocale, VTlevel);
2998 }
2999 else {
3000 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r6%d;1\"p", CLocale, VTlevel);
3001 }
3002 break;
3003
3004 case 'q': // DECSCA
3005 if (CharAttr.Attr2 & Attr2Protect) {
3006 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r1\"q", CLocale);
3007 }
3008 else {
3009 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r0\"q", CLocale);
3010 }
3011 break;
3012 }
3013 break;
3014 case 'm': // SGR
3015 if (StrBuff[1] == 0) {
3016 RepStr[0] = '0';
3017 RepStr[1] = '$';
3018 RepStr[2] = 'r';
3019 len = 3;
3020 if (CharAttr.Attr & AttrBold) {
3021 RepStr[len++] = '1';
3022 RepStr[len++] = ';';
3023 }
3024 if (CharAttr.Attr & AttrUnder) {
3025 RepStr[len++] = '4';
3026 RepStr[len++] = ';';
3027 }
3028 if (CharAttr.Attr & AttrBlink) {
3029 RepStr[len++] = '5';
3030 RepStr[len++] = ';';
3031 }
3032 if (CharAttr.Attr & AttrReverse) {
3033 RepStr[len++] = '7';
3034 RepStr[len++] = ';';
3035 }
3036 if (CharAttr.Attr2 & Attr2Fore) {
3037 if (CharAttr.Fore <= 7) {
3038 RepStr[len++] = '3';
3039 RepStr[len++] = '0' + CharAttr.Fore;
3040 RepStr[len++] = ';';
3041 }
3042 else if (CharAttr.Fore <= 15) {
3043 RepStr[len++] = '9';
3044 RepStr[len++] = '0' + CharAttr.Fore - 8;
3045 RepStr[len++] = ';';
3046 }
3047 else {
3048 len += _snprintf_s_l(&RepStr[len], sizeof(RepStr) - len, _TRUNCATE, "38;5;%d;", CLocale, CharAttr.Fore);
3049 }
3050 }
3051 if (CharAttr.Attr2 & Attr2Back) {
3052 if (CharAttr.Back <= 7) {
3053 RepStr[len++] = '4';
3054 RepStr[len++] = '0' + CharAttr.Back;
3055 RepStr[len++] = ';';
3056 }
3057 else if (CharAttr.Back <= 15) {
3058 RepStr[len++] = '1';
3059 RepStr[len++] = '0';
3060 RepStr[len++] = '0' + CharAttr.Back - 8;
3061 RepStr[len++] = ';';
3062 }
3063 else {
3064 len += _snprintf_s_l(&RepStr[len], sizeof(RepStr) - len, _TRUNCATE, "48;5;%d;", CLocale, CharAttr.Back);
3065 }
3066 }
3067 if (len == 3) {
3068 RepStr[len++] = '0';
3069 }
3070 else {
3071 len--;
3072 }
3073 RepStr[len++] = 'm';
3074 RepStr[len] = 0;
3075 }
3076 break;
3077 case 'r': // DECSTBM
3078 if (StrBuff[1] == 0) {
3079 len = _snprintf_s_l(RepStr, sizeof(RepStr), _TRUNCATE, "0$r%d;%dr", CLocale, CursorTop+1, CursorBottom+1);
3080 }
3081 break;
3082 }
3083 if (len > 0) {
3084 if (ts.TermFlag & TF_INVALIDDECRPSS) {
3085 RepStr[0] = '1';
3086 }
3087 SendDCSstr(RepStr, len);
3088 }
3089 else {
3090 if (ts.TermFlag & TF_INVALIDDECRPSS) {
3091 SendDCSstr("0$r", 0);
3092 }
3093 else {
3094 SendDCSstr("1$r", 0);
3095 }
3096 }
3097 }
3098
3099 void ParseDCS(BYTE Cmd, unsigned char *StrBuff, int len) {
3100 switch (ICount) {
3101 case 0:
3102 break;
3103 case 1:
3104 switch (IntChar[1]) {
3105 case '!':
3106 if (Cmd == '{') { // DECSTUI
3107 if (! (ts.TermFlag & TF_LOCKTUID)) {
3108 int i;
3109 for (i=0; i<8 && isxdigit(StrBuff[i]); i++) {
3110 if (islower(StrBuff[i])) {
3111 StrBuff[i] = toupper(StrBuff[i]);
3112 }
3113 }
3114 if (len == 8 && i == 8) {
3115 strncpy_s(ts.TerminalUID, sizeof(ts.TerminalUID), StrBuff, _TRUNCATE);
3116 }
3117 }
3118 }
3119 break;
3120 case '$':
3121 if (Cmd == 'q') { // DECRQSS
3122 RequestStatusString(StrBuff, len);
3123 }
3124 break;
3125 default:
3126 break;
3127 }
3128 break;
3129 default:
3130 break;
3131 }
3132 }
3133
3134 #define ModeDcsFirst 1
3135 #define ModeDcsString 2
3136 void DeviceControl(BYTE b)
3137 {
3138 static unsigned char StrBuff[256];
3139 static int DcsParseMode = ModeDcsFirst;
3140 static int StrLen;
3141 static BYTE Cmd;
3142
3143 if ((ESCFlag && (b=='\\')) || (b==ST && ts.KanjiCode!=IdSJIS)) {
3144 if (DcsParseMode == ModeDcsString) {
3145 StrBuff[StrLen] = 0;
3146 ParseDCS(Cmd, StrBuff, StrLen);
3147 }
3148 ESCFlag = FALSE;
3149 ParseMode = SavedMode;
3150 DcsParseMode = ModeDcsFirst;
3151 StrLen = 0;
3152 return;
3153 }
3154
3155 if (b==ESC) {
3156 ESCFlag = TRUE;
3157 return;
3158 }
3159 else {
3160 ESCFlag = FALSE;
3161 }
3162
3163 switch (DcsParseMode) {
3164 case ModeDcsFirst:
3165 if (b<=US) {
3166 ParseControl(b);
3167 }
3168 else if ((b>=0x20) && (b<=0x2F)) {
3169 if (ICount<IntCharMax) ICount++;
3170 IntChar[ICount] = b;
3171 }
3172 else if ((b>=0x30) && (b<=0x39)) {
3173 if (Param[NParam] < 0) Param[NParam] = 0;
3174 if (Param[NParam]<1000)
3175 Param[NParam] = Param[NParam]*10 + b - 0x30;
3176 }
3177 else if (b==0x3B) {
3178 if (NParam < NParamMax) {
3179 NParam++;
3180 Param[NParam] = -1;
3181 }
3182 }
3183 else if ((b>=0x40) && (b<=0x7E)) {
3184 if (ICount == 0 && b=='|') {
3185 ParseMode = ModeDCUserKey;
3186 if (Param[1] < 1) ClearUserKey();
3187 WaitKeyId = TRUE;
3188 NewKeyId = 0;
3189 }
3190 else {
3191 Cmd = b;
3192 DcsParseMode = ModeDcsString;
3193 }
3194 }
3195 else {
3196 ParseMode = ModeSOS;
3197 }
3198 break;
3199
3200 case ModeDcsString:
3201 if (b <= US && b != HT && b != CR) {
3202 ESCFlag = FALSE;
3203 ParseMode = SavedMode;
3204 DcsParseMode = ModeDcsFirst;
3205 StrLen = 0;
3206 }
3207 else if (StrLen < sizeof(StrBuff)-1) {
3208 StrBuff[StrLen++] = b;
3209 }
3210 break;
3211 }
3212 }
3213
3214 void DCUserKey(BYTE b)
3215 {
3216 if (ESCFlag && (b=='\\') || (b==ST && ts.KanjiCode!=IdSJIS))
3217 {
3218 if (! WaitKeyId) DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
3219 ESCFlag = FALSE;
3220 ParseMode = SavedMode;
3221 return;
3222 }
3223
3224 if (b==ESC)
3225 {
3226 ESCFlag = TRUE;
3227 return;
3228 }
3229 else ESCFlag = FALSE;
3230
3231 if (WaitKeyId)
3232 {
3233 if ((b>=0x30) && (b<=0x39))
3234 {
3235 if (NewKeyId<1000)
3236 NewKeyId = NewKeyId*10 + b - 0x30;
3237 }
3238 else if (b==0x2F)
3239 {
3240 WaitKeyId = FALSE;
3241 WaitHi = TRUE;
3242 NewKeyLen = 0;
3243 }
3244 }
3245 else {
3246 if (b==0x3B)
3247 {
3248 DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
3249 WaitKeyId = TRUE;
3250 NewKeyId = 0;
3251 }
3252 else {
3253 if (NewKeyLen < FuncKeyStrMax)
3254 {
3255 if (WaitHi)
3256 {
3257 NewKeyStr[NewKeyLen] = ConvHexChar(b) << 4;
3258 WaitHi = FALSE;
3259 }
3260 else {
3261 NewKeyStr[NewKeyLen] = NewKeyStr[NewKeyLen] +
3262 ConvHexChar(b);
3263 WaitHi = TRUE;
3264 NewKeyLen++;
3265 }
3266 }
3267 }
3268 }
3269 }
3270
3271 void IgnoreString(BYTE b)
3272 {
3273 if ((ESCFlag && (b=='\\')) ||
3274 (b<=US && b!=ESC && b!=HT) ||
3275 (b==ST && ts.KanjiCode!=IdSJIS))
3276 ParseMode = SavedMode;
3277
3278 if (b==ESC) ESCFlag = TRUE;
3279 else ESCFlag = FALSE;
3280 }
3281
3282 BOOL XsParseColor(char *colspec, COLORREF *color)
3283 {
3284 unsigned int r, g, b;
3285 // double dr, dg, db;
3286
3287 r = g = b = 255;
3288
3289 if (colspec == NULL || color == NULL) {
3290 return FALSE;
3291 }
3292
3293 if (_strnicmp(colspec, "rgb:", 4) == 0) {
3294 switch (strlen(colspec)) {
3295 case 9: // rgb:R/G/B
3296 if (sscanf(colspec, "rgb:%1x/%1x/%1x", &r, &g, &b) != 3) {
3297 return FALSE;
3298 }
3299 r *= 17; g *= 17; b *= 17;
3300 break;
3301 case 12: // rgb:RR/GG/BB
3302 if (sscanf(colspec, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) {
3303 return FALSE;
3304 }
3305 break;
3306 case 15: // rgb:RRR/GGG/BBB
3307 if (sscanf(colspec, "rgb:%3x/%3x/%3x", &r, &g, &b) != 3) {
3308 return FALSE;
3309 }
3310 r >>= 4; g >>= 4; b >>= 4;
3311 break;
3312 case 18: // rgb:RRRR/GGGG/BBBB
3313 if (sscanf(colspec, "rgb:%4x/%4x/%4x", &r, &g, &b) != 3) {
3314 return FALSE;
3315 }
3316 r >>= 8; g >>= 8; b >>= 8;
3317 break;
3318 default:
3319 return FALSE;
3320 }
3321 }
3322 // else if (_strnicmp(colspec, "rgbi:", 5) == 0) {
3323 // ; /* nothing to do */
3324 // }
3325 else if (colspec[0] == '#') {
3326 switch (strlen(colspec)) {
3327 case 4: // #RGB
3328 if (sscanf(colspec, "#%1x%1x%1x", &r, &g, &b) != 3) {
3329 return<