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