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 5089 - (show annotations) (download) (as text)
Tue Dec 4 00:54:13 2012 UTC (11 years, 4 months ago) by doda
File MIME type: text/x-csrc
File size: 116308 byte(s)
DECCRAに仮対応

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