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 4947 - (show annotations) (download) (as text)
Mon May 14 10:33:37 2012 UTC (11 years, 10 months ago) by doda
File MIME type: text/x-csrc
File size: 111857 byte(s)
余分な ; を削除。

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