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 5118 - (show annotations) (download) (as text)
Wed Feb 6 03:46:10 2013 UTC (11 years, 2 months ago) by doda
File MIME type: text/x-csrc
File size: 120122 byte(s)
制御文字列中にUTF-8文字列を含められるようにした。

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