Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4275 - (hide annotations) (download) (as text)
Tue Jan 11 17:34:29 2011 UTC (13 years, 3 months ago) by doda
File MIME type: text/x-csrc
File size: 99998 byte(s)
対応していない OSC シーケンスを正しく無視できていない場合があったのを修正。

1 maya 3227 /* 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 doda 4225 #include <ctype.h>
14 maya 3227
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 doda 4256 void ParseFirst(BYTE b);
30    
31 doda 3443 #define MAPSIZE(x) (sizeof(x)/sizeof((x)[0]))
32 doda 4246 #define Accept8BitCtrl ((VTlevel >= 2) && (ts.TermFlag & TF_ACCEPT8BITCTRL))
33 doda 3443
34 maya 3227 /* 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 doda 3997 /* 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 maya 3227 void VisualBell();
56 doda 3999 BOOL DecLocatorReport(int Event, int Button);
57 maya 3227
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 doda 3743 static BOOL AltScr;
68 doda 3872 BOOL BracketedPaste;
69 maya 3227
70 doda 4246 static int VTlevel;
71    
72 maya 3227 // 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 doda 3797 static TStatusBuff SBuff1, SBuff2, SBuff3;
84 maya 3227
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 doda 3997 /* Mouse Report */
136     int MouseReportMode;
137     unsigned int DecLocatorFlag;
138     int LastX, LastY;
139     int ButtonStat;
140 doda 3999 int FilterTop, FilterBottom, FilterLeft, FilterRight;
141 doda 3997
142 doda 3450 static _locale_t CLocale = NULL;
143 maya 3227
144 doda 3916 void ResetSBuffer(PStatusBuff sbuff)
145 maya 3227 {
146 doda 3916 sbuff->CursorX = 0;
147     sbuff->CursorY = 0;
148     sbuff->Attr = DefCharAttr;
149 maya 3227 if (ts.Language==IdJapanese)
150     {
151 doda 3916 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 maya 3227 if ((ts.KanjiCode==IdJIS) &&
157     (ts.JIS7Katakana==0))
158 doda 3916 sbuff->Glr[1] = 2; // 8-bit katakana
159 maya 3227 else
160 doda 3916 sbuff->Glr[1] = 3;
161 maya 3227 }
162     else {
163 doda 3916 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 maya 3227 }
170 doda 3916 sbuff->AutoWrapMode = TRUE;
171     sbuff->RelativeOrgMode = FALSE;
172     }
173    
174     void ResetAllSBuffers()
175     {
176     ResetSBuffer(&SBuff1);
177 maya 3227 // copy SBuff1 to SBuff2
178     SBuff2 = SBuff1;
179 doda 3797 SBuff3 = SBuff1;
180 maya 3227 }
181    
182 doda 3916 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 maya 3227 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 doda 4271 AppliEscapeMode = FALSE;
213 maya 3227 RelativeOrgMode = FALSE;
214     ts.ColorFlag &= ~CF_REVERSEVIDEO;
215     AutoRepeatMode = TRUE;
216     FocusReportMode = FALSE;
217     MouseReportMode = IdMouseTrackNone;
218 doda 3997 DecLocatorFlag = 0;
219 maya 3227
220 doda 4246 ChangeTerminalID();
221    
222 doda 3997 LastX = 0;
223     LastY = 0;
224     ButtonStat = 0;
225    
226 doda 3450 if (CLocale == NULL) {
227     CLocale = _create_locale(LC_ALL, "C");
228     }
229 maya 3227
230     /* Character sets */
231     ResetCharSet();
232    
233     /* ESC flag for device control sequence */
234     ESCFlag = FALSE;
235     /* for TEK sequence */
236     JustAfterESC = FALSE;
237    
238     /* Parse mode */
239     ParseMode = ModeFirst;
240    
241     /* Clear printer mode */
242     PrinterMode = FALSE;
243    
244     // status buffers
245 doda 3916 ResetAllSBuffers();
246 doda 3745
247     // Alternate Screen Buffer
248     AltScr = FALSE;
249 doda 3872
250     // Bracketed Paste Mode
251     BracketedPaste = FALSE;
252 maya 3227 }
253    
254     void ResetCharSet()
255     {
256     if (ts.Language==IdJapanese)
257     {
258     Gn[0] = IdASCII;
259     Gn[1] = IdKatakana;
260     Gn[2] = IdKatakana;
261     Gn[3] = IdKanji;
262     Glr[0] = 0;
263     if ((ts.KanjiCode==IdJIS) &&
264     (ts.JIS7Katakana==0))
265     Glr[1] = 2; // 8-bit katakana
266     else
267     Glr[1] = 3;
268     }
269     else {
270     Gn[0] = IdASCII;
271     Gn[1] = IdSpecial;
272     Gn[2] = IdASCII;
273     Gn[3] = IdASCII;
274     Glr[0] = 0;
275     Glr[1] = 0;
276     cv.SendCode = IdASCII;
277     cv.SendKanjiFlag = FALSE;
278     cv.EchoCode = IdASCII;
279     cv.EchoKanjiFlag = FALSE;
280     }
281     /* Kanji flag */
282     KanjiIn = FALSE;
283     EUCkanaIn = FALSE;
284     EUCsupIn = FALSE;
285     SSflag = FALSE;
286    
287     cv.Language = ts.Language;
288     cv.CRSend = ts.CRSend;
289     cv.KanjiCodeEcho = ts.KanjiCode;
290     cv.JIS7KatakanaEcho = ts.JIS7Katakana;
291     cv.KanjiCodeSend = ts.KanjiCodeSend;
292     cv.JIS7KatakanaSend = ts.JIS7KatakanaSend;
293     cv.KanjiIn = ts.KanjiIn;
294     cv.KanjiOut = ts.KanjiOut;
295     }
296    
297     void ResetKeypadMode(BOOL DisabledModeOnly)
298     {
299     if (!DisabledModeOnly || ts.DisableAppKeypad) AppliKeyMode = FALSE;
300     if (!DisabledModeOnly || ts.DisableAppCursor) AppliCursorMode = FALSE;
301     }
302    
303     void MoveToMainScreen()
304     {
305     StatusX = CursorX;
306     StatusWrap = Wrap;
307     StatusCursor = IsCaretEnabled();
308    
309     CursorTop = MainTop;
310     CursorBottom = MainBottom;
311     Wrap = MainWrap;
312     DispEnableCaret(MainCursor);
313     MoveCursor(MainX,MainY); // move to main screen
314     }
315    
316     void MoveToStatusLine()
317     {
318     MainX = CursorX;
319     MainY = CursorY;
320     MainTop = CursorTop;
321     MainBottom = CursorBottom;
322     MainWrap = Wrap;
323     MainCursor = IsCaretEnabled();
324    
325     DispEnableCaret(StatusCursor);
326     MoveCursor(StatusX,NumOfLines-1); // move to status line
327     CursorTop = NumOfLines-1;
328     CursorBottom = CursorTop;
329     Wrap = StatusWrap;
330     }
331    
332     void HideStatusLine()
333     {
334     if ((StatusLine>0) &&
335     (CursorY==NumOfLines-1))
336     MoveToMainScreen();
337     StatusX = 0;
338     StatusWrap = FALSE;
339     StatusCursor = TRUE;
340     ShowStatusLine(0); //hide
341     }
342    
343     void ChangeTerminalSize(int Nx, int Ny)
344     {
345     BuffChangeTerminalSize(Nx,Ny);
346     StatusX = 0;
347     MainX = 0;
348     MainY = 0;
349     MainTop = 0;
350     MainBottom = NumOfColumns-1;
351     }
352    
353 doda 3471 void SendCSIstr(char *str, int len) {
354 doda 4024 int l;
355    
356     if (str == NULL || len < 0)
357 doda 3471 return;
358    
359 doda 4024 if (len == 0) {
360     l = strlen(str);
361     }
362     else {
363     l = len;
364     }
365    
366 doda 3471 if (Send8BitMode)
367     CommBinaryOut(&cv,"\233", 1);
368     else
369     CommBinaryOut(&cv,"\033[", 2);
370    
371 doda 4024 CommBinaryOut(&cv, str, l);
372 doda 3471 }
373    
374     void SendOSCstr(char *str, int len) {
375 doda 4024 int l;
376    
377 doda 4104 if (str == NULL || len < 0)
378 doda 3471 return;
379    
380 doda 4024 if (len == 0) {
381     l = strlen(str);
382     }
383     else {
384     l = len;
385     }
386    
387 doda 3486 if (Send8BitMode) {
388 doda 3471 CommBinaryOut(&cv,"\235", 1);
389 doda 4024 CommBinaryOut(&cv, str, l);
390 doda 3486 CommBinaryOut(&cv,"\234", 1);
391     }
392     else {
393 doda 3471 CommBinaryOut(&cv,"\033]", 2);
394 doda 4024 CommBinaryOut(&cv, str, l);
395 doda 3486 CommBinaryOut(&cv,"\033\\", 2);
396     }
397 doda 3471
398     }
399    
400 doda 4162 void SendDCSstr(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,"\220", 1);
415     CommBinaryOut(&cv, str, l);
416     CommBinaryOut(&cv,"\234", 1);
417     }
418     else {
419     CommBinaryOut(&cv,"\033P", 2);
420     CommBinaryOut(&cv, str, l);
421     CommBinaryOut(&cv,"\033\\", 2);
422     }
423    
424     }
425    
426 maya 3227 void BackSpace()
427     {
428     if (CursorX == 0)
429     {
430     if ((CursorY>0) &&
431     ((ts.TermFlag & TF_BACKWRAP)!=0))
432     {
433     MoveCursor(NumOfColumns-1,CursorY-1);
434     // if (cv.HLogBuf!=0) Log1Byte(BS);
435     // (2005.2.20 yutaka)
436     if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
437     }
438     }
439     else if (CursorX > 0)
440     {
441     MoveCursor(CursorX-1,CursorY);
442     // if (cv.HLogBuf!=0) Log1Byte(BS);
443     // (2005.2.20 yutaka)
444     if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
445     }
446     }
447    
448     void CarriageReturn(BOOL logFlag)
449     {
450     #ifndef NO_COPYLINE_FIX
451     if (!ts.EnableContinuedLineCopy || logFlag)
452     #endif /* NO_COPYLINE_FIX */
453     if (cv.HLogBuf!=0) Log1Byte(CR);
454    
455     if (CursorX>0)
456     MoveCursor(0,CursorY);
457     }
458    
459     void LineFeed(BYTE b, BOOL logFlag)
460     {
461     /* for auto print mode */
462     if ((AutoPrintMode) &&
463     (b>=LF) && (b<=FF))
464     BuffDumpCurrentLine(b);
465    
466     #ifndef NO_COPYLINE_FIX
467     if (!ts.EnableContinuedLineCopy || logFlag)
468     #endif /* NO_COPYLINE_FIX */
469     if (cv.HLogBuf!=0) Log1Byte(LF);
470    
471     if (CursorY < CursorBottom)
472     MoveCursor(CursorX,CursorY+1);
473     else if (CursorY == CursorBottom) BuffScrollNLines(1);
474     else if (CursorY < NumOfLines-StatusLine-1)
475     MoveCursor(CursorX,CursorY+1);
476    
477 doda 3312 #ifndef NO_COPYLINE_FIX
478     ClearLineContinued();
479     #endif /* NO_COPYLINE_FIX */
480    
481 maya 3227 if (LFMode) CarriageReturn(logFlag);
482     }
483    
484     void Tab()
485     {
486     if (Wrap && !ts.VTCompatTab) {
487     CarriageReturn(FALSE);
488     LineFeed(LF,FALSE);
489     #ifndef NO_COPYLINE_FIX
490     if (ts.EnableContinuedLineCopy) {
491     SetLineContinued();
492     }
493     #endif /* NO_COPYLINE_FIX */
494     Wrap = FALSE;
495     }
496     CursorForwardTab(1, AutoWrapMode);
497     if (cv.HLogBuf!=0) Log1Byte(HT);
498     }
499    
500     void PutChar(BYTE b)
501     {
502     BOOL SpecialNew;
503     TCharAttr CharAttrTmp;
504    
505     CharAttrTmp = CharAttr;
506    
507     if (PrinterMode) { // printer mode
508     WriteToPrnFile(b,TRUE);
509     return;
510     }
511    
512     if (Wrap)
513     {
514     CarriageReturn(FALSE);
515     LineFeed(LF,FALSE);
516     #ifndef NO_COPYLINE_FIX
517     CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
518     #endif /* NO_COPYLINE_FIX */
519     }
520    
521     // if (cv.HLogBuf!=0) Log1Byte(b);
522     // (2005.2.20 yutaka)
523     if (ts.LogTypePlainText) {
524     if (__isascii(b) && !isprint(b)) {
525     // ASCII�������A���\�������������O�����������B
526     } else {
527     if (cv.HLogBuf!=0) Log1Byte(b);
528     }
529     } else {
530     if (cv.HLogBuf!=0) Log1Byte(b);
531     }
532    
533     Wrap = FALSE;
534    
535     SpecialNew = FALSE;
536     if ((b>0x5F) && (b<0x80))
537     {
538     if (SSflag)
539     SpecialNew = (Gn[GLtmp]==IdSpecial);
540     else
541     SpecialNew = (Gn[Glr[0]]==IdSpecial);
542     }
543     else if (b>0xDF)
544     {
545     if (SSflag)
546     SpecialNew = (Gn[GLtmp]==IdSpecial);
547     else
548     SpecialNew = (Gn[Glr[1]]==IdSpecial);
549     }
550    
551     if (SpecialNew != Special)
552     {
553     UpdateStr();
554     Special = SpecialNew;
555     }
556    
557     if (Special)
558     {
559     b = b & 0x7F;
560     CharAttrTmp.Attr |= AttrSpecial;
561     }
562     else
563     CharAttrTmp.Attr |= CharAttr.Attr;
564    
565     BuffPutChar(b, CharAttrTmp, InsertMode);
566    
567     if (CursorX < NumOfColumns-1)
568     MoveRight();
569     else {
570     UpdateStr();
571     Wrap = AutoWrapMode;
572     }
573     }
574    
575     void PutDecSp(BYTE b)
576     {
577     TCharAttr CharAttrTmp;
578    
579     CharAttrTmp = CharAttr;
580    
581     if (PrinterMode) { // printer mode
582     WriteToPrnFile(b, TRUE);
583     return;
584     }
585    
586     if (Wrap) {
587     CarriageReturn(FALSE);
588     LineFeed(LF, FALSE);
589     #ifndef NO_COPYLINE_FIX
590     CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
591     #endif /* NO_COPYLINE_FIX */
592     }
593    
594     if (cv.HLogBuf!=0) Log1Byte(b);
595     /*
596     if (ts.LogTypePlainText && __isascii(b) && !isprint(b)) {
597     // ASCII�������A���\�������������O�����������B
598     } else {
599     if (cv.HLogBuf!=0) Log1Byte(b);
600     }
601     */
602    
603     Wrap = FALSE;
604    
605     if (!Special) {
606     UpdateStr();
607     Special = TRUE;
608     }
609    
610     CharAttrTmp.Attr |= AttrSpecial;
611     BuffPutChar(b, CharAttrTmp, InsertMode);
612    
613     if (CursorX < NumOfColumns-1)
614     MoveRight();
615     else {
616     UpdateStr();
617     Wrap = AutoWrapMode;
618     }
619     }
620    
621     void PutKanji(BYTE b)
622     {
623     #ifndef NO_COPYLINE_FIX
624     TCharAttr CharAttrTmp;
625    
626     CharAttrTmp = CharAttr;
627     #endif /* NO_COPYLINE_FIX */
628     Kanji = Kanji + b;
629    
630     if (PrinterMode && DirectPrn)
631     {
632     WriteToPrnFile(HIBYTE(Kanji),FALSE);
633     WriteToPrnFile(LOBYTE(Kanji),TRUE);
634     return;
635     }
636    
637     if (ConvJIS)
638     Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f));
639    
640     if (PrinterMode) { // printer mode
641     WriteToPrnFile(HIBYTE(Kanji),FALSE);
642     WriteToPrnFile(LOBYTE(Kanji),TRUE);
643     return;
644     }
645    
646     if (Wrap)
647     {
648     CarriageReturn(FALSE);
649     LineFeed(LF,FALSE);
650     #ifndef NO_COPYLINE_FIX
651     if (ts.EnableContinuedLineCopy)
652     CharAttrTmp.Attr |= AttrLineContinued;
653     #endif /* NO_COPYLINE_FIX */
654     }
655     else if (CursorX > NumOfColumns-2)
656     if (AutoWrapMode)
657     {
658     #ifndef NO_COPYLINE_FIX
659     if (ts.EnableContinuedLineCopy)
660     {
661     CharAttrTmp.Attr |= AttrLineContinued;
662     if (CursorX == NumOfColumns-1)
663     BuffPutChar(0x20, CharAttr, FALSE);
664     }
665     #endif /* NO_COPYLINE_FIX */
666     CarriageReturn(FALSE);
667     LineFeed(LF,FALSE);
668     }
669     else return;
670    
671     Wrap = FALSE;
672    
673     if (cv.HLogBuf!=0)
674     {
675     Log1Byte(HIBYTE(Kanji));
676     Log1Byte(LOBYTE(Kanji));
677     }
678    
679     if (Special)
680     {
681     UpdateStr();
682     Special = FALSE;
683     }
684    
685     #ifndef NO_COPYLINE_FIX
686     BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
687     #else
688     BuffPutKanji(Kanji, CharAttr, InsertMode);
689     #endif /* NO_COPYLINE_FIX */
690    
691     if (CursorX < NumOfColumns-2)
692     {
693     MoveRight();
694     MoveRight();
695     }
696     else {
697     UpdateStr();
698     Wrap = AutoWrapMode;
699     }
700     }
701    
702     void PutDebugChar(BYTE b)
703     {
704 yutakapon 3637 static BYTE buff[3];
705     int i = 0;
706    
707     if (DebugFlag!=DEBUG_FLAG_NONE) {
708 maya 3227 InsertMode = FALSE;
709     AutoWrapMode = TRUE;
710    
711 yutakapon 3637 if (DebugFlag==DEBUG_FLAG_HEXD) {
712     _snprintf(buff,3,"%02X",(unsigned int) b);
713    
714     for (;i<2;i++)
715     PutChar(buff[i]);
716     PutChar(' ');
717     }
718     else if (DebugFlag==DEBUG_FLAG_NORM) {
719    
720 maya 3227 if ((b & 0x80) == 0x80)
721     {
722     UpdateStr();
723     CharAttr.Attr = AttrReverse;
724     b = b & 0x7f;
725     }
726    
727     if (b<=US)
728     {
729     PutChar('^');
730     PutChar((char)(b+0x40));
731     }
732     else if (b==DEL)
733     {
734     PutChar('<');
735     PutChar('D');
736     PutChar('E');
737     PutChar('L');
738     PutChar('>');
739     }
740     else
741     PutChar(b);
742 yutakapon 3637 }
743 maya 3227
744     if (CharAttr.Attr != AttrDefault)
745     {
746     UpdateStr();
747     CharAttr.Attr = AttrDefault;
748     }
749 yutakapon 3637 }
750 maya 3227 }
751    
752     void PrnParseControl(BYTE b) // printer mode
753     {
754     switch (b) {
755     case NUL: return;
756     case SO:
757     if (! DirectPrn)
758     {
759     if ((ts.Language==IdJapanese) &&
760     (ts.KanjiCode==IdJIS) &&
761     (ts.JIS7Katakana==1) &&
762     ((ts.TermFlag & TF_FIXEDJIS)!=0))
763     Gn[1] = IdKatakana;
764     Glr[0] = 1; /* LS1 */
765     return;
766     }
767     break;
768     case SI:
769     if (! DirectPrn)
770     {
771     Glr[0] = 0; /* LS0 */
772     return;
773     }
774     break;
775     case DC1:
776     case DC3: return;
777     case ESC:
778     ICount = 0;
779     JustAfterESC = TRUE;
780     ParseMode = ModeESC;
781     WriteToPrnFile(0,TRUE); // flush prn buff
782     return;
783     case CSI:
784 doda 3491 if (! Accept8BitCtrl) {
785 maya 3227 PutChar(b); /* Disp C1 char in VT100 mode */
786     return;
787     }
788     ICount = 0;
789     FirstPrm = TRUE;
790     NParam = 1;
791     Param[1] = -1;
792     Prv = 0;
793     ParseMode = ModeCSI;
794     WriteToPrnFile(0,TRUE); // flush prn buff
795     WriteToPrnFile(b,FALSE);
796     return;
797     }
798     /* send the uninterpreted character to printer */
799     WriteToPrnFile(b,TRUE);
800     }
801    
802     void ParseControl(BYTE b)
803     {
804     if (PrinterMode) { // printer mode
805     PrnParseControl(b);
806     return;
807     }
808    
809     if (b>=0x80) /* C1 char */
810     {
811     /* English mode */
812     if (ts.Language==IdEnglish)
813     {
814 doda 3491 if (!Accept8BitCtrl) {
815 maya 3227 PutChar(b); /* Disp C1 char in VT100 mode */
816     return;
817     }
818     }
819     else { /* Japanese mode */
820     if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0)
821     return; /* ignore C1 char */
822     /* C1 chars are interpreted as C0 chars in VT100 mode */
823 doda 4246 if (VTlevel < 2)
824 maya 3227 b = b & 0x7F;
825     }
826     }
827     switch (b) {
828     /* C0 group */
829     case ENQ:
830     CommBinaryOut(&cv,&(ts.Answerback[0]),ts.AnswerbackLen);
831     break;
832     case BEL:
833     switch (ts.Beep) {
834     case IdBeepOff:
835     /* nothing to do */
836     break;
837     case IdBeepOn:
838     MessageBeep(0);
839     break;
840     case IdBeepVisual:
841     VisualBell();
842     break;
843     }
844     break;
845     case BS: BackSpace(); break;
846     case HT: Tab(); break;
847    
848     case LF:
849     // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
850     // CR+LF���������������������B
851     // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
852     // (2007.1.21 yutaka)
853     if (ts.CRReceive == IdLF) {
854     CarriageReturn(TRUE);
855     LineFeed(b, TRUE);
856     break;
857     }
858    
859     case VT: LineFeed(b,TRUE); break;
860    
861     case FF:
862     if ((ts.AutoWinSwitch>0) && JustAfterESC)
863     {
864     CommInsert1Byte(&cv,b);
865     CommInsert1Byte(&cv,ESC);
866     ChangeEmu = IdTEK; /* Enter TEK Mode */
867     }
868     else
869     LineFeed(b,TRUE);
870     break;
871     case CR:
872     CarriageReturn(TRUE);
873     if (ts.CRReceive==IdCRLF)
874     CommInsert1Byte(&cv,LF);
875     break;
876     case SO:
877     if ((ts.Language==IdJapanese) &&
878     (ts.KanjiCode==IdJIS) &&
879     (ts.JIS7Katakana==1) &&
880     ((ts.TermFlag & TF_FIXEDJIS)!=0))
881     Gn[1] = IdKatakana;
882    
883     Glr[0] = 1; /* LS1 */
884     break;
885     case SI: Glr[0] = 0; break; /* LS0 */
886     case DLE:
887     if ((ts.FTFlag & FT_BPAUTO)!=0)
888     ParseMode = ModeDLE; /* Auto B-Plus activation */
889     break;
890     case CAN:
891     if ((ts.FTFlag & FT_ZAUTO)!=0)
892     ParseMode = ModeCAN; /* Auto ZMODEM activation */
893     // else if (ts.AutoWinSwitch>0)
894     // ChangeEmu = IdTEK; /* Enter TEK Mode */
895     else
896     ParseMode = ModeFirst;
897     break;
898     case SUB: ParseMode = ModeFirst; break;
899     case ESC:
900     ICount = 0;
901     JustAfterESC = TRUE;
902     ParseMode = ModeESC;
903     break;
904     case FS:
905     case GS:
906     case RS:
907     case US:
908     if (ts.AutoWinSwitch>0)
909     {
910     CommInsert1Byte(&cv,b);
911     ChangeEmu = IdTEK; /* Enter TEK Mode */
912     }
913     break;
914    
915     /* C1 char */
916     case IND: LineFeed(0,TRUE); break;
917     case NEL:
918     LineFeed(0,TRUE);
919     CarriageReturn(TRUE);
920     break;
921     case HTS: SetTabStop(); break;
922     case RI: CursorUpWithScroll(); break;
923     case SS2:
924     GLtmp = 2;
925     SSflag = TRUE;
926     break;
927     case SS3:
928     GLtmp = 3;
929     SSflag = TRUE;
930     break;
931     case DCS:
932     SavedMode = ParseMode;
933     ESCFlag = FALSE;
934 doda 4225 ICount = 0;
935 maya 3227 NParam = 1;
936     Param[1] = -1;
937 doda 4225 Prv = 0;
938 maya 3227 ParseMode = ModeDCS;
939     break;
940     case SOS:
941     SavedMode = ParseMode;
942     ESCFlag = FALSE;
943     ParseMode = ModeSOS;
944     break;
945     case CSI:
946     ICount = 0;
947     FirstPrm = TRUE;
948     NParam = 1;
949     Param[1] = -1;
950     Prv = 0;
951     ParseMode = ModeCSI;
952     break;
953     case OSC:
954     Param[1] = 0;
955     ParseMode = ModeXS;
956     break;
957     case PM:
958     case APC:
959     SavedMode = ParseMode;
960     ESCFlag = FALSE;
961     ParseMode = ModeSOS;
962     break;
963     }
964     }
965    
966     void SaveCursor()
967     {
968     int i;
969     PStatusBuff Buff;
970    
971     if ((StatusLine>0) &&
972     (CursorY==NumOfLines-1))
973     Buff = &SBuff2; // for status line
974 doda 3797 else if (AltScr)
975     Buff = &SBuff3; // for alternate screen
976 maya 3227 else
977     Buff = &SBuff1; // for main screen
978    
979     Buff->CursorX = CursorX;
980     Buff->CursorY = CursorY;
981     Buff->Attr = CharAttr;
982     Buff->Glr[0] = Glr[0];
983     Buff->Glr[1] = Glr[1];
984     for (i=0 ; i<=3; i++)
985     Buff->Gn[i] = Gn[i];
986     Buff->AutoWrapMode = AutoWrapMode;
987     Buff->RelativeOrgMode = RelativeOrgMode;
988     }
989    
990     void RestoreCursor()
991     {
992     int i;
993     PStatusBuff Buff;
994     UpdateStr();
995    
996     if ((StatusLine>0) &&
997     (CursorY==NumOfLines-1))
998     Buff = &SBuff2; // for status line
999 doda 3797 else if (AltScr)
1000     Buff = &SBuff3; // for alternate screen
1001 maya 3227 else
1002     Buff = &SBuff1; // for main screen
1003    
1004     if (Buff->CursorX > NumOfColumns-1)
1005     Buff->CursorX = NumOfColumns-1;
1006     if (Buff->CursorY > NumOfLines-1-StatusLine)
1007     Buff->CursorY = NumOfLines-1-StatusLine;
1008     MoveCursor(Buff->CursorX,Buff->CursorY);
1009     CharAttr = Buff->Attr;
1010     Glr[0] = Buff->Glr[0];
1011     Glr[1] = Buff->Glr[1];
1012     for (i=0 ; i<=3; i++)
1013     Gn[i] = Buff->Gn[i];
1014     AutoWrapMode = Buff->AutoWrapMode;
1015     RelativeOrgMode = Buff->RelativeOrgMode;
1016     }
1017    
1018     void AnswerTerminalType()
1019     {
1020 doda 4244 char Tmp[50];
1021 maya 3227
1022     if (ts.TerminalID<IdVT320)
1023     strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1024     else
1025     strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1026    
1027     switch (ts.TerminalID) {
1028     case IdVT100:
1029     strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1030     break;
1031     case IdVT100J:
1032     strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1033     break;
1034     case IdVT101:
1035     strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1036     break;
1037     case IdVT102:
1038     strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1039     break;
1040     case IdVT102J:
1041     strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1042     break;
1043     case IdVT220J:
1044     strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1045     break;
1046     case IdVT282:
1047     strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1048     break;
1049     case IdVT320:
1050     strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1051     break;
1052     case IdVT382:
1053     strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1054     break;
1055 doda 4084 case IdVT420:
1056     strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1057     break;
1058     case IdVT520:
1059     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1060     break;
1061     case IdVT525:
1062     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1063     break;
1064 maya 3227 }
1065     strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1066    
1067     CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1068     }
1069    
1070     void ESCSpace(BYTE b)
1071     {
1072     switch (b) {
1073 doda 4246 case 'F': // S7C1T
1074     Send8BitMode = FALSE;
1075     break;
1076     case 'G': // S8C1T
1077     if (VTlevel >= 2) {
1078     Send8BitMode = TRUE;
1079     }
1080     break;
1081 maya 3227 }
1082     }
1083    
1084     void ESCSharp(BYTE b)
1085     {
1086     switch (b) {
1087 doda 4097 case '8': /* Fill screen with "E" (DECALN) */
1088 maya 3227 BuffUpdateScroll();
1089     BuffFillWithE();
1090 doda 4097 CursorTop = 0;
1091     CursorBottom = NumOfLines-1-StatusLine;
1092 maya 3227 MoveCursor(0,0);
1093     ParseMode = ModeFirst;
1094     break;
1095     }
1096     }
1097    
1098     /* select double byte code set */
1099     void ESCDBCSSelect(BYTE b)
1100     {
1101     int Dist;
1102    
1103     if (ts.Language!=IdJapanese) return;
1104    
1105     switch (ICount) {
1106     case 1:
1107     if ((b=='@') || (b=='B'))
1108     {
1109     Gn[0] = IdKanji; /* Kanji -> G0 */
1110     if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1111     Glr[0] = 0; /* G0->GL */
1112     }
1113     break;
1114     case 2:
1115     /* Second intermediate char must be
1116     '(' or ')' or '*' or '+'. */
1117     Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1118     if ((b=='1') || (b=='3') ||
1119     (b=='@') || (b=='B'))
1120     {
1121     Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1122     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1123     (Dist==0))
1124     Glr[0] = 0; /* G0->GL */
1125     }
1126     break;
1127     }
1128     }
1129    
1130     void ESCSelectCode(BYTE b)
1131     {
1132     switch (b) {
1133     case '0':
1134     if (ts.AutoWinSwitch>0)
1135     ChangeEmu = IdTEK; /* enter TEK mode */
1136     break;
1137     }
1138     }
1139    
1140     /* select single byte code set */
1141     void ESCSBCSSelect(BYTE b)
1142     {
1143     int Dist;
1144    
1145     /* Intermediate char must be
1146     '(' or ')' or '*' or '+'. */
1147     Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1148    
1149     switch (b) {
1150     case '0': Gn[Dist] = IdSpecial; break;
1151     case '<': Gn[Dist] = IdASCII; break;
1152     case '>': Gn[Dist] = IdASCII; break;
1153     case 'A': Gn[Dist] = IdASCII; break;
1154     case 'B': Gn[Dist] = IdASCII; break;
1155     case 'H': Gn[Dist] = IdASCII; break;
1156     case 'I':
1157     if (ts.Language==IdJapanese)
1158     Gn[Dist] = IdKatakana;
1159     break;
1160     case 'J': Gn[Dist] = IdASCII; break;
1161     }
1162    
1163     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1164     (Dist==0))
1165     Glr[0] = 0; /* G0->GL */
1166     }
1167    
1168     void PrnParseEscape(BYTE b) // printer mode
1169     {
1170     int i;
1171    
1172     ParseMode = ModeFirst;
1173     switch (ICount) {
1174     /* no intermediate char */
1175     case 0:
1176     switch (b) {
1177     case '[': /* CSI */
1178     ICount = 0;
1179     FirstPrm = TRUE;
1180     NParam = 1;
1181     Param[1] = -1;
1182     Prv = 0;
1183     WriteToPrnFile(ESC,FALSE);
1184     WriteToPrnFile('[',FALSE);
1185     ParseMode = ModeCSI;
1186     return;
1187     } /* end of case Icount=0 */
1188     break;
1189     /* one intermediate char */
1190     case 1:
1191     switch (IntChar[1]) {
1192     case '$':
1193     if (! DirectPrn)
1194     {
1195     ESCDBCSSelect(b);
1196     return;
1197     }
1198     break;
1199     case '(':
1200     case ')':
1201     case '*':
1202     case '+':
1203     if (! DirectPrn)
1204     {
1205     ESCSBCSSelect(b);
1206     return;
1207     }
1208     break;
1209     }
1210     break;
1211     /* two intermediate char */
1212     case 2:
1213     if ((! DirectPrn) &&
1214     (IntChar[1]=='$') &&
1215     ('('<=IntChar[2]) &&
1216     (IntChar[2]<='+'))
1217     {
1218     ESCDBCSSelect(b);
1219     return;
1220     }
1221     break;
1222     }
1223     // send the uninterpreted sequence to printer
1224     WriteToPrnFile(ESC,FALSE);
1225     for (i=1; i<=ICount; i++)
1226     WriteToPrnFile(IntChar[i],FALSE);
1227     WriteToPrnFile(b,TRUE);
1228     }
1229    
1230     void ParseEscape(BYTE b) /* b is the final char */
1231     {
1232     if (PrinterMode) { // printer mode
1233     PrnParseEscape(b);
1234     return;
1235     }
1236    
1237     switch (ICount) {
1238     /* no intermediate char */
1239     case 0:
1240     switch (b) {
1241 doda 4243 case '6': // DECBI
1242     if (CursorX == 0) {
1243     BuffScrollRight(1);
1244     }
1245     else {
1246     CursorX--;
1247     }
1248 maya 3227 case '7': SaveCursor(); break;
1249     case '8': RestoreCursor(); break;
1250 doda 4243 case '9': // DECFI
1251     if (CursorX == NumOfColumns-1) {
1252     BuffScrollLeft(1);
1253     }
1254     else {
1255     CursorX++;
1256     }
1257 maya 3227 case '=': AppliKeyMode = TRUE; break;
1258     case '>': AppliKeyMode = FALSE; break;
1259     case 'D': /* IND */
1260     LineFeed(0,TRUE);
1261     break;
1262     case 'E': /* NEL */
1263     MoveCursor(0,CursorY);
1264     LineFeed(0,TRUE);
1265     break;
1266     case 'H': /* HTS */
1267     SetTabStop();
1268     break;
1269     case 'M': /* RI */
1270     CursorUpWithScroll();
1271     break;
1272     case 'N': /* SS2 */
1273     GLtmp = 2;
1274     SSflag = TRUE;
1275     break;
1276     case 'O': /* SS3 */
1277     GLtmp = 3;
1278     SSflag = TRUE;
1279     break;
1280     case 'P': /* DCS */
1281     SavedMode = ParseMode;
1282     ESCFlag = FALSE;
1283     NParam = 1;
1284     Param[1] = -1;
1285     ParseMode = ModeDCS;
1286     return;
1287     case 'X': /* SOS */
1288     SavedMode = ParseMode;
1289     ESCFlag = FALSE;
1290     ParseMode = ModeSOS;
1291     return;
1292     case 'Z': AnswerTerminalType(); break;
1293     case '[': /* CSI */
1294     ICount = 0;
1295     FirstPrm = TRUE;
1296     NParam = 1;
1297     Param[1] = -1;
1298     Prv = 0;
1299     ParseMode = ModeCSI;
1300     return;
1301     case '\\': break; /* ST */
1302     case ']': /* XTERM sequence (OSC) */
1303     NParam = 1;
1304     Param[1] = 0;
1305     ParseMode = ModeXS;
1306     return;
1307     case '^':
1308     case '_': /* PM, APC */
1309     SavedMode = ParseMode;
1310     ESCFlag = FALSE;
1311     ParseMode = ModeSOS;
1312     return;
1313     case 'c': /* Hardware reset */
1314     HideStatusLine();
1315     ResetTerminal();
1316     ClearUserKey();
1317     ClearBuffer();
1318     if (ts.PortType==IdSerial) // reset serial port
1319     CommResetSerial(&ts, &cv, TRUE);
1320     break;
1321     case 'g': /* Visual Bell (screen original?) */
1322     VisualBell();
1323     break;
1324     case 'n': Glr[0] = 2; break; /* LS2 */
1325     case 'o': Glr[0] = 3; break; /* LS3 */
1326     case '|': Glr[1] = 3; break; /* LS3R */
1327     case '}': Glr[1] = 2; break; /* LS2R */
1328     case '~': Glr[1] = 1; break; /* LS1R */
1329     } /* end of case Icount=0 */
1330     break;
1331     /* one intermediate char */
1332     case 1:
1333     switch (IntChar[1]) {
1334     case ' ': ESCSpace(b); break;
1335     case '#': ESCSharp(b); break;
1336     case '$': ESCDBCSSelect(b); break;
1337     case '%': break;
1338     case '(':
1339     case ')':
1340     case '*':
1341     case '+':
1342     ESCSBCSSelect(b);
1343     break;
1344     }
1345     break;
1346     /* two intermediate char */
1347     case 2:
1348     if ((IntChar[1]=='$') &&
1349     ('('<=IntChar[2]) &&
1350     (IntChar[2]<='+'))
1351     ESCDBCSSelect(b);
1352     else if ((IntChar[1]=='%') &&
1353     (IntChar[2]=='!'))
1354     ESCSelectCode(b);
1355     break;
1356     }
1357     ParseMode = ModeFirst;
1358     }
1359    
1360     void EscapeSequence(BYTE b)
1361     {
1362     if (b<=US)
1363     ParseControl(b);
1364     else if ((b>=0x20) && (b<=0x2F))
1365     {
1366     if (ICount<IntCharMax) ICount++;
1367     IntChar[ICount] = b;
1368     }
1369     else if ((b>=0x30) && (b<=0x7E))
1370     ParseEscape(b);
1371     else if ((b>=0x80) && (b<=0x9F))
1372     ParseControl(b);
1373 doda 4256 else if (b>=0xA0) {
1374     ParseMode=ModeFirst;
1375     ParseFirst(b);
1376     }
1377 maya 3227
1378     JustAfterESC = FALSE;
1379     }
1380    
1381     void CSInsertCharacter()
1382     {
1383     // Insert space characters at cursor
1384     int Count;
1385    
1386     BuffUpdateScroll();
1387     if (Param[1]<1) Param[1] = 1;
1388     Count = Param[1];
1389     BuffInsertSpace(Count);
1390     }
1391    
1392     void CSCursorUp()
1393     {
1394     if (Param[1]<1) Param[1] = 1;
1395    
1396     if (CursorY >= CursorTop)
1397     {
1398     if (CursorY-Param[1] > CursorTop)
1399     MoveCursor(CursorX,CursorY-Param[1]);
1400     else
1401     MoveCursor(CursorX,CursorTop);
1402     }
1403     else {
1404     if (CursorY > 0)
1405     MoveCursor(CursorX,CursorY-Param[1]);
1406     else
1407     MoveCursor(CursorX,0);
1408     }
1409     }
1410    
1411     void CSCursorUp1()
1412     {
1413     MoveCursor(0,CursorY);
1414     CSCursorUp();
1415     }
1416    
1417     void CSCursorDown()
1418     {
1419     if (Param[1]<1) Param[1] = 1;
1420    
1421     if (CursorY <= CursorBottom)
1422     {
1423     if (CursorY+Param[1] < CursorBottom)
1424     MoveCursor(CursorX,CursorY+Param[1]);
1425     else
1426     MoveCursor(CursorX,CursorBottom);
1427     }
1428     else {
1429     if (CursorY < NumOfLines-StatusLine-1)
1430     MoveCursor(CursorX,CursorY+Param[1]);
1431     else
1432     MoveCursor(CursorX,NumOfLines-StatusLine);
1433     }
1434     }
1435    
1436     void CSCursorDown1()
1437     {
1438     MoveCursor(0,CursorY);
1439     CSCursorDown();
1440     }
1441    
1442     void CSScreenErase()
1443     {
1444     if (Param[1] == -1) Param[1] = 0;
1445     BuffUpdateScroll();
1446     switch (Param[1]) {
1447     case 0:
1448     // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1449     // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1450     // �����������������B(2005.5.29 yutaka)
1451     // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1452     if (ts.ScrollWindowClearScreen &&
1453     (CursorX == 0 && CursorY == 0)) {
1454     // Erase screen (scroll out)
1455     BuffClearScreen();
1456     UpdateWindow(HVTWin);
1457    
1458     } else {
1459     // Erase characters from cursor to the end of screen
1460     BuffEraseCurToEnd();
1461     }
1462     break;
1463    
1464     case 1:
1465     // Erase characters from home to cursor
1466     BuffEraseHomeToCur();
1467     break;
1468    
1469     case 2:
1470     // Erase screen (scroll out)
1471     BuffClearScreen();
1472     UpdateWindow(HVTWin);
1473     break;
1474     }
1475     }
1476    
1477 doda 4070 void CSQSelScreenErase()
1478     {
1479     if (Param[1] == -1) Param[1] = 0;
1480     BuffUpdateScroll();
1481     switch (Param[1]) {
1482     case 0:
1483     // Erase characters from cursor to end
1484     BuffSelectedEraseCurToEnd();
1485     break;
1486    
1487     case 1:
1488     // Erase characters from home to cursor
1489     BuffSelectedEraseHomeToCur();
1490     break;
1491    
1492     case 2:
1493     // Erase entire screen
1494     BuffSelectedEraseScreen();
1495     break;
1496     }
1497     }
1498    
1499 maya 3227 void CSInsertLine()
1500     {
1501     // Insert lines at current position
1502     int Count, YEnd;
1503    
1504     if (CursorY < CursorTop) return;
1505     if (CursorY > CursorBottom) return;
1506     if (Param[1]<1) Param[1] = 1;
1507     Count = Param[1];
1508    
1509     YEnd = CursorBottom;
1510     if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1511     if (Count > YEnd+1 - CursorY) Count = YEnd+1 - CursorY;
1512    
1513     BuffInsertLines(Count,YEnd);
1514     }
1515    
1516     void CSLineErase()
1517     {
1518     if (Param[1] == -1) Param[1] = 0;
1519     BuffUpdateScroll();
1520     switch (Param[1]) {
1521     /* erase char from cursor to end of line */
1522     case 0:
1523     BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1524     break;
1525     /* erase char from start of line to cursor */
1526     case 1:
1527     BuffEraseCharsInLine(0,CursorX+1);
1528     break;
1529     /* erase entire line */
1530     case 2:
1531     BuffEraseCharsInLine(0,NumOfColumns);
1532     break;
1533     }
1534     }
1535    
1536 doda 4070 void CSQSelLineErase()
1537     {
1538     if (Param[1] == -1) Param[1] = 0;
1539     BuffUpdateScroll();
1540     switch (Param[1]) {
1541     /* erase char from cursor to end of line */
1542     case 0:
1543     BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1544     break;
1545     /* erase char from start of line to cursor */
1546     case 1:
1547     BuffSelectedEraseCharsInLine(0,CursorX+1);
1548     break;
1549     /* erase entire line */
1550     case 2:
1551     BuffSelectedEraseCharsInLine(0,NumOfColumns);
1552     break;
1553     }
1554     }
1555    
1556 maya 3227 void CSDeleteNLines()
1557     // Delete lines from current line
1558     {
1559     int Count, YEnd;
1560    
1561     if (CursorY < CursorTop) return;
1562     if (CursorY > CursorBottom) return;
1563     Count = Param[1];
1564     if (Count<1) Count = 1;
1565    
1566     YEnd = CursorBottom;
1567     if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1568     if (Count > YEnd+1-CursorY) Count = YEnd+1-CursorY;
1569     BuffDeleteLines(Count,YEnd);
1570     }
1571    
1572     void CSDeleteCharacter()
1573     {
1574     // Delete characters in current line from cursor
1575    
1576     if (Param[1]<1) Param[1] = 1;
1577     BuffUpdateScroll();
1578     BuffDeleteChars(Param[1]);
1579     }
1580    
1581     void CSEraseCharacter()
1582     {
1583     if (Param[1]<1) Param[1] = 1;
1584     BuffUpdateScroll();
1585     BuffEraseChars(Param[1]);
1586     }
1587    
1588     void CSScrollUP()
1589     {
1590     if (Param[1]<1) Param[1] = 1;
1591     BuffUpdateScroll();
1592     BuffRegionScrollUpNLines(Param[1]);
1593     }
1594    
1595     void CSScrollDown()
1596     {
1597     if (Param[1]<1) Param[1] = 1;
1598     BuffUpdateScroll();
1599     BuffRegionScrollDownNLines(Param[1]);
1600     }
1601    
1602     void CSForwardTab()
1603     {
1604     if (Param[1]<1) Param[1] = 1;
1605     CursorForwardTab(Param[1], AutoWrapMode);
1606     }
1607    
1608     void CSBackwardTab()
1609     {
1610     if (Param[1]<1) Param[1] = 1;
1611     CursorBackwardTab(Param[1]);
1612     }
1613    
1614     void CSMoveToColumnN()
1615     {
1616     if (Param[1]<1) Param[1] = 1;
1617     Param[1]--;
1618     if (Param[1] < 0) Param[1] = 0;
1619     if (Param[1] > NumOfColumns-1) Param[1] = NumOfColumns-1;
1620     MoveCursor(Param[1],CursorY);
1621     }
1622    
1623     void CSCursorRight()
1624     {
1625     if (Param[1]<1) Param[1] = 1;
1626     if (CursorX + Param[1] > NumOfColumns-1)
1627     MoveCursor(NumOfColumns-1,CursorY);
1628     else
1629     MoveCursor(CursorX+Param[1],CursorY);
1630     }
1631    
1632     void CSCursorLeft()
1633     {
1634     if (Param[1]<1) Param[1] = 1;
1635     if (CursorX-Param[1] < 0)
1636     MoveCursor(0,CursorY);
1637     else
1638     MoveCursor(CursorX-Param[1],CursorY);
1639     }
1640    
1641     void CSMoveToLineN()
1642     {
1643     if (Param[1]<1) Param[1] = 1;
1644     if (RelativeOrgMode)
1645     {
1646     if (CursorTop+Param[1]-1 > CursorBottom)
1647     MoveCursor(CursorX,CursorBottom);
1648     else
1649     MoveCursor(CursorX,CursorTop+Param[1]-1);
1650     }
1651     else {
1652     if (Param[1] > NumOfLines-StatusLine)
1653     MoveCursor(CursorX,NumOfLines-1-StatusLine);
1654     else
1655     MoveCursor(CursorX,Param[1]-1);
1656     }
1657     }
1658    
1659     void CSMoveToXY()
1660     {
1661     int NewX, NewY;
1662    
1663     if (Param[1]<1) Param[1] = 1;
1664     if ((NParam < 2) || (Param[2]<1)) Param[2] = 1;
1665     NewX = Param[2] - 1;
1666     if (NewX > NumOfColumns-1) NewX = NumOfColumns-1;
1667    
1668     if ((StatusLine>0) && (CursorY==NumOfLines-1))
1669     NewY = CursorY;
1670     else if (RelativeOrgMode)
1671     {
1672     NewY = CursorTop + Param[1] - 1;
1673     if (NewY > CursorBottom) NewY = CursorBottom;
1674     }
1675     else {
1676     NewY = Param[1] - 1;
1677     if (NewY > NumOfLines-1-StatusLine)
1678     NewY = NumOfLines-1-StatusLine;
1679     }
1680     MoveCursor(NewX,NewY);
1681     }
1682    
1683     void CSDeleteTabStop()
1684     {
1685     if (Param[1]==-1) Param[1] = 0;
1686     ClearTabStop(Param[1]);
1687     }
1688    
1689 doda 3742 void CS_h_Mode() // SM
1690 maya 3227 {
1691     switch (Param[1]) {
1692 doda 3311 case 2: // KAM
1693     KeybEnabled = FALSE; break;
1694     case 4: // IRM
1695     InsertMode = TRUE; break;
1696     case 12: // SRM
1697 doda 3485 ts.LocalEcho = 0;
1698     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1699     TelChangeEcho();
1700     break;
1701 doda 3311 case 20: // LF/NL
1702 doda 3485 LFMode = TRUE;
1703     ts.CRSend = IdCRLF;
1704     cv.CRSend = IdCRLF;
1705     break;
1706 doda 3311 case 33: // WYSTCURM
1707 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1708     ts.NonblinkingCursor = TRUE;
1709     ChangeCaret();
1710     }
1711     break;
1712 doda 3311 case 34: // WYULCURM
1713 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1714     ts.CursorShape = IdHCur;
1715     ChangeCaret();
1716     }
1717     break;
1718 maya 3227 }
1719     }
1720    
1721 doda 3742 void CS_i_Mode() // MC
1722 maya 3227 {
1723     if (Param[1]==-1) Param[1] = 0;
1724     switch (Param[1]) {
1725     /* print screen */
1726     // PrintEX -- TRUE: print screen
1727     // FALSE: scroll region
1728     case 0: BuffPrint(! PrintEX); break;
1729     /* printer controller mode off */
1730     case 4: break; /* See PrnParseCS() */
1731     /* printer controller mode on */
1732     case 5:
1733     if (! AutoPrintMode)
1734     OpenPrnFile();
1735     DirectPrn = (ts.PrnDev[0]!=0);
1736     PrinterMode = TRUE;
1737     break;
1738     }
1739     }
1740    
1741 doda 3742 void CS_l_Mode() // RM
1742 maya 3227 {
1743     switch (Param[1]) {
1744 doda 3311 case 2: // KAM
1745     KeybEnabled = TRUE; break;
1746     case 4: // IRM
1747     InsertMode = FALSE; break;
1748     case 12: // SRM
1749 doda 3485 ts.LocalEcho = 1;
1750     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1751     TelChangeEcho();
1752     break;
1753 doda 3311 case 20: // LF/NL
1754 doda 3485 LFMode = FALSE;
1755     ts.CRSend = IdCR;
1756     cv.CRSend = IdCR;
1757     break;
1758 doda 3311 case 33: // WYSTCURM
1759 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1760     ts.NonblinkingCursor = FALSE;
1761     ChangeCaret();
1762     }
1763     break;
1764 doda 3311 case 34: // WYULCURM
1765 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1766     ts.CursorShape = IdBlkCur;
1767     ChangeCaret();
1768     }
1769     break;
1770 maya 3227 }
1771     }
1772    
1773 doda 3742 void CS_n_Mode() // DSR
1774 maya 3227 {
1775     char Report[16];
1776 doda 3471 int Y, len;
1777 maya 3227
1778     switch (Param[1]) {
1779     case 5:
1780 doda 3311 /* Device Status Report -> Ready */
1781 doda 4024 SendCSIstr("0n", 0);
1782 maya 3227 break;
1783     case 6:
1784     /* Cursor Position Report */
1785     Y = CursorY+1;
1786     if ((StatusLine>0) &&
1787     (Y==NumOfLines))
1788     Y = 1;
1789 doda 3471 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, CursorX+1);
1790     SendCSIstr(Report, len);
1791 maya 3227 break;
1792     }
1793     }
1794    
1795 doda 3742 void CSSetAttr() // SGR
1796 maya 3227 {
1797     int i, P;
1798    
1799     UpdateStr();
1800     for (i=1 ; i<=NParam ; i++)
1801     {
1802     P = Param[i];
1803     if (P<0) P = 0;
1804     switch (P) {
1805     case 0: /* Clear all */
1806 doda 4070 if (CharAttr.Attr2 & Attr2Protect) {
1807     CharAttr = DefCharAttr;
1808     CharAttr.Attr2 |= Attr2Protect;
1809     }
1810     else {
1811     CharAttr = DefCharAttr;
1812     }
1813 maya 3227 BuffSetCurCharAttr(CharAttr);
1814     break;
1815    
1816     case 1: /* Bold */
1817     CharAttr.Attr |= AttrBold;
1818     BuffSetCurCharAttr(CharAttr);
1819     break;
1820    
1821     case 4: /* Under line */
1822     CharAttr.Attr |= AttrUnder;
1823     BuffSetCurCharAttr(CharAttr);
1824     break;
1825    
1826     case 5: /* Blink */
1827     CharAttr.Attr |= AttrBlink;
1828     BuffSetCurCharAttr(CharAttr);
1829     break;
1830    
1831     case 7: /* Reverse */
1832     CharAttr.Attr |= AttrReverse;
1833     BuffSetCurCharAttr(CharAttr);
1834     break;
1835    
1836     case 22: /* Bold off */
1837     CharAttr.Attr &= ~ AttrBold;
1838     BuffSetCurCharAttr(CharAttr);
1839     break;
1840    
1841     case 24: /* Under line off */
1842     CharAttr.Attr &= ~ AttrUnder;
1843     BuffSetCurCharAttr(CharAttr);
1844     break;
1845    
1846     case 25: /* Blink off */
1847     CharAttr.Attr &= ~ AttrBlink;
1848     BuffSetCurCharAttr(CharAttr);
1849     break;
1850    
1851     case 27: /* Reverse off */
1852     CharAttr.Attr &= ~ AttrReverse;
1853     BuffSetCurCharAttr(CharAttr);
1854     break;
1855    
1856     case 30:
1857     case 31:
1858     case 32:
1859     case 33:
1860     case 34:
1861     case 35:
1862     case 36:
1863     case 37: /* text color */
1864     CharAttr.Attr2 |= Attr2Fore;
1865     CharAttr.Fore = P - 30;
1866     BuffSetCurCharAttr(CharAttr);
1867     break;
1868    
1869     case 38: /* text color (256color mode) */
1870     if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1871     i++;
1872     if (i < NParam) {
1873     P = Param[++i];
1874     if (P<0) {
1875     P = 0;
1876     }
1877     CharAttr.Attr2 |= Attr2Fore;
1878     CharAttr.Fore = P;
1879     BuffSetCurCharAttr(CharAttr);
1880     }
1881     }
1882     break;
1883    
1884     case 39: /* Reset text color */
1885     CharAttr.Attr2 &= ~ Attr2Fore;
1886     CharAttr.Fore = AttrDefaultFG;
1887     BuffSetCurCharAttr(CharAttr);
1888     break;
1889    
1890     case 40:
1891     case 41:
1892     case 42:
1893     case 43:
1894     case 44:
1895     case 45:
1896     case 46:
1897     case 47: /* Back color */
1898     CharAttr.Attr2 |= Attr2Back;
1899     CharAttr.Back = P - 40;
1900     BuffSetCurCharAttr(CharAttr);
1901     break;
1902    
1903     case 48: /* Back color (256color mode) */
1904     if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1905     i++;
1906     if (i < NParam) {
1907     P = Param[++i];
1908     if (P<0) {
1909     P = 0;
1910     }
1911     CharAttr.Attr2 |= Attr2Back;
1912     CharAttr.Back = P;
1913     BuffSetCurCharAttr(CharAttr);
1914     }
1915     }
1916     break;
1917    
1918     case 49: /* Reset back color */
1919     CharAttr.Attr2 &= ~ Attr2Back;
1920     CharAttr.Back = AttrDefaultBG;
1921     BuffSetCurCharAttr(CharAttr);
1922     break;
1923    
1924     case 90:
1925     case 91:
1926     case 92:
1927     case 93:
1928     case 94:
1929     case 95:
1930     case 96:
1931     case 97: /* aixterm style text color */
1932     if (ts.ColorFlag & CF_AIXTERM16) {
1933     CharAttr.Attr2 |= Attr2Fore;
1934     CharAttr.Fore = P - 90 + 8;
1935     BuffSetCurCharAttr(CharAttr);
1936     }
1937     break;
1938    
1939     case 100:
1940     if (! (ts.ColorFlag & CF_AIXTERM16)) {
1941     /* Reset text and back color */
1942     CharAttr.Attr2 &= ~ (Attr2Fore | Attr2Back);
1943     CharAttr.Fore = AttrDefaultFG;
1944     CharAttr.Back = AttrDefaultBG;
1945     BuffSetCurCharAttr(CharAttr);
1946     break;
1947     }
1948     /* fall through to aixterm style back color */
1949    
1950     case 101:
1951     case 102:
1952     case 103:
1953     case 104:
1954     case 105:
1955     case 106:
1956     case 107: /* aixterm style back color */
1957     if (ts.ColorFlag & CF_AIXTERM16) {
1958     CharAttr.Attr2 |= Attr2Back;
1959     CharAttr.Back = P - 100 + 8;
1960     BuffSetCurCharAttr(CharAttr);
1961     }
1962     break;
1963     }
1964     }
1965     }
1966    
1967     void CSSetScrollRegion()
1968     {
1969     if ((StatusLine>0) &&
1970     (CursorY==NumOfLines-1))
1971     {
1972     MoveCursor(0,CursorY);
1973     return;
1974     }
1975     if (Param[1]<1) Param[1] =1;
1976     if ((NParam < 2) | (Param[2]<1))
1977     Param[2] = NumOfLines-StatusLine;
1978     Param[1]--;
1979     Param[2]--;
1980     if (Param[1] > NumOfLines-1-StatusLine)
1981     Param[1] = NumOfLines-1-StatusLine;
1982     if (Param[2] > NumOfLines-1-StatusLine)
1983     Param[2] = NumOfLines-1-StatusLine;
1984     if (Param[1] >= Param[2]) return;
1985     CursorTop = Param[1];
1986     CursorBottom = Param[2];
1987     if (RelativeOrgMode) MoveCursor(0,CursorTop);
1988     else MoveCursor(0,0);
1989     }
1990    
1991     void CSSunSequence() /* Sun terminal private sequences */
1992     {
1993 doda 3471 int x, y, len;
1994 doda 3487 char Report[TitleBuffSize*2+10];
1995 maya 3227
1996     switch (Param[1]) {
1997 doda 3302 case 1: // De-iconify window
1998 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
1999     DispShowWindow(WINDOW_RESTORE);
2000 doda 3302 break;
2001     case 2: // Iconify window
2002 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2003     DispShowWindow(WINDOW_MINIMIZE);
2004 doda 3302 break;
2005     case 3: // set window position
2006 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2007     if (NParam < 2) Param[2] = 0;
2008     if (NParam < 3) Param[3] = 0;
2009     DispMoveWindow(Param[2], Param[3]);
2010     }
2011 doda 3297 break;
2012 doda 3466 case 4: // set window size
2013 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2014     if (NParam < 2) Param[2] = 0;
2015     if (NParam < 3) Param[3] = 0;
2016     DispResizeWin(Param[3], Param[2]);
2017     }
2018 doda 3464 break;
2019 doda 3311 case 5: // Raise window
2020 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2021     DispShowWindow(WINDOW_RAISE);
2022 doda 3309 break;
2023 doda 3311 case 6: // Lower window
2024 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2025     DispShowWindow(WINDOW_LOWER);
2026 doda 3309 break;
2027 doda 3311 case 7: // Refresh window
2028 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2029     DispShowWindow(WINDOW_REFRESH);
2030 doda 3310 break;
2031 maya 3227 case 8: /* set terminal size */
2032 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2033     if ((Param[2]<=1) || (NParam<2)) Param[2] = 24;
2034     if ((Param[3]<=1) || (NParam<3)) Param[3] = 80;
2035     ChangeTerminalSize(Param[3],Param[2]);
2036     }
2037 maya 3227 break;
2038 doda 3302 case 9: // Maximize/Restore window
2039 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2040     if (NParam < 2 || Param[2] == 0) {
2041     DispShowWindow(WINDOW_RESTORE);
2042     }
2043 doda 3489 else if (Param[2] == 1) {
2044 doda 3485 DispShowWindow(WINDOW_MAXIMIZE);
2045     }
2046 doda 3302 }
2047     break;
2048 doda 3466 case 11: // Report window state
2049 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2050     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
2051     SendCSIstr(Report, len);
2052     }
2053 doda 3466 break;
2054 doda 3469 case 13: // Report window position
2055 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2056     DispGetWindowPos(&x, &y);
2057     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%d;%dt", CLocale, x, y);
2058     SendCSIstr(Report, len);
2059     }
2060 doda 3469 break;
2061 doda 4259 case 14: /* get window size */
2062 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2063 doda 4250 DispGetWindowSize(&x, &y);
2064     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "4;%d;%dt", CLocale, y, x);
2065     SendCSIstr(Report, len);
2066 doda 3485 }
2067 maya 3227 break;
2068     case 18: /* get terminal size */
2069 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2070     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%u;t", CLocale,
2071     NumOfLines-StatusLine, NumOfColumns);
2072     SendCSIstr(Report, len);
2073     }
2074 maya 3227 break;
2075 doda 3475 case 19: // Report display size (character)
2076 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2077     DispGetRootWinSize(&x, &y);
2078     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
2079     SendCSIstr(Report, len);
2080     }
2081 doda 3475 break;
2082 doda 3487 case 20: // Report icon label
2083 doda 3747 switch (ts.WindowFlag & WF_TITLEREPORT) {
2084 doda 3774 case IdTitleReportIgnore:
2085 doda 3747 // nothing to do
2086     break;
2087 doda 3774 case IdTitleReportAccept:
2088 doda 3747 switch (ts.AcceptTitleChangeRequest) {
2089     case IdTitleChangeRequestOff:
2090 doda 3487 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2091 doda 3747 break;
2092     case IdTitleChangeRequestAhead:
2093     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, cv.TitleRemote, ts.Title);
2094     break;
2095     case IdTitleChangeRequestLast:
2096     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, ts.Title, cv.TitleRemote);
2097     break;
2098     default:
2099     if (cv.TitleRemote[0] == 0) {
2100     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2101     }
2102     else {
2103     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, cv.TitleRemote);
2104     }
2105     }
2106     SendOSCstr(Report, len);
2107     break;
2108     default: // IdTitleReportEmpty:
2109 doda 4024 SendOSCstr("L", 0);
2110 doda 3747 break;
2111 doda 3487 }
2112     break;
2113     case 21: // Report window title
2114 doda 3747 switch (ts.WindowFlag & WF_TITLEREPORT) {
2115 doda 3774 case IdTitleReportIgnore:
2116 doda 3747 // nothing to do
2117     break;
2118 doda 3774 case IdTitleReportAccept:
2119 doda 3747 switch (ts.AcceptTitleChangeRequest) {
2120     case IdTitleChangeRequestOff:
2121 doda 3487 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2122 doda 3747 break;
2123     case IdTitleChangeRequestAhead:
2124     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, cv.TitleRemote, ts.Title);
2125     break;
2126     case IdTitleChangeRequestLast:
2127     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, ts.Title, cv.TitleRemote);
2128     break;
2129     default:
2130     if (cv.TitleRemote[0] == 0) {
2131     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2132     }
2133     else {
2134     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, cv.TitleRemote);
2135     }
2136     }
2137     SendOSCstr(Report, len);
2138     break;
2139     default: // IdTitleReportEmpty:
2140 doda 4024 SendOSCstr("l", 0);
2141 doda 3747 break;
2142 doda 3487 }
2143     break;
2144 maya 3227 }
2145     }
2146    
2147 doda 4162 void CSEQ(BYTE b)
2148     {
2149 doda 4217 char Report[16];
2150     int len;
2151    
2152 doda 4162 switch (b) {
2153     case 'c': /* Tertiary terminal report (Tertiary DA) */
2154     if (Param[1] < 1) {
2155 doda 4217 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "!|%8s", CLocale, ts.TerminalUID);
2156     SendDCSstr(Report, len);
2157 doda 4162 }
2158     break;
2159     }
2160     }
2161    
2162 maya 3227 void CSGT(BYTE b)
2163     {
2164     switch (b) {
2165 doda 3311 case 'c': /* second terminal report (Secondary DA) */
2166 doda 3472 if (Param[1] < 1) {
2167 doda 4024 SendCSIstr(">32;100;2c", 0); /* VT382 */
2168 doda 3472 }
2169 maya 3227 break;
2170 doda 4101 case 'J': // IO-8256 terminal
2171     if (Param[1]==3) {
2172     if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2173     if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2174 doda 4199 if (Param[4] < 1 || NParam < 4) Param[4] = NumOfLines-StatusLine;
2175     if (Param[5] < 1 || NParam < 5) Param[5] = NumOfColumns;
2176 doda 4101 BuffEraseBox(Param[3]-1, Param[2]-1, Param[5]-1, Param[4]-1);
2177 maya 3227 }
2178     break;
2179 doda 4101 case 'K': // IO-8256 terminal
2180     switch (Param[1]) {
2181     case 3:
2182     if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2183     if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2184     BuffEraseCharsInLine(Param[2]-1, Param[3]-Param[2]+1);
2185     break;
2186     case 5:
2187     if (NParam < 2) Param[2] = 0;
2188     if (NParam < 3) Param[3] = 0;
2189     switch (Param[2]) {
2190     case 3:
2191     case 4:
2192     case 5:
2193     case 6: // Draw Line
2194     BuffDrawLine(CharAttr, Param[2], Param[3]);
2195     break;
2196    
2197     case 12: // Text color
2198     if ((Param[3]>=0) && (Param[3]<=7)) {
2199     switch (Param[3]) {
2200     case 3: CharAttr.Fore = IdBlue; break;
2201     case 4: CharAttr.Fore = IdCyan; break;
2202     case 5: CharAttr.Fore = IdYellow; break;
2203     case 6: CharAttr.Fore = IdMagenta; break;
2204     default: CharAttr.Fore = Param[3]; break;
2205     }
2206     CharAttr.Attr2 |= Attr2Fore;
2207     BuffSetCurCharAttr(CharAttr);
2208 maya 3227 }
2209 doda 4101 break;
2210     }
2211     break;
2212 maya 3227 }
2213     break;
2214     }
2215     }
2216    
2217 doda 3742 void CSQExchangeColor() // DECSCNM / Visual Bell
2218 maya 3227 {
2219     COLORREF ColorRef;
2220    
2221     BuffUpdateScroll();
2222    
2223     if (ts.ColorFlag & CF_REVERSECOLOR) {
2224     ColorRef = ts.VTColor[0];
2225     ts.VTColor[0] = ts.VTReverseColor[0];
2226     ts.VTReverseColor[0] = ColorRef;
2227     ColorRef = ts.VTColor[1];
2228     ts.VTColor[1] = ts.VTReverseColor[1];
2229     ts.VTReverseColor[1] = ColorRef;
2230     }
2231     else {
2232     ColorRef = ts.VTColor[0];
2233     ts.VTColor[0] = ts.VTColor[1];
2234     ts.VTColor[1] = ColorRef;
2235     }
2236    
2237     ColorRef = ts.VTBoldColor[0];
2238     ts.VTBoldColor[0] = ts.VTBoldColor[1];
2239     ts.VTBoldColor[1] = ColorRef;
2240    
2241     ColorRef = ts.VTBlinkColor[0];
2242     ts.VTBlinkColor[0] = ts.VTBlinkColor[1];
2243     ts.VTBlinkColor[1] = ColorRef;
2244    
2245     ColorRef = ts.URLColor[0];
2246     ts.URLColor[0] = ts.URLColor[1];
2247     ts.URLColor[1] = ColorRef;
2248    
2249     ts.ColorFlag ^= CF_REVERSEVIDEO;
2250    
2251     #ifdef ALPHABLEND_TYPE2
2252 doda 3715 BGExchangeColor();
2253 maya 3227 #endif
2254     DispChangeBackground();
2255     UpdateWindow(HVTWin);
2256     }
2257    
2258 doda 3802 void CSQChangeColumnMode(int width) // DECCOLM
2259     {
2260     ChangeTerminalSize(width, NumOfLines-StatusLine);
2261 doda 3804 if ((ts.TermFlag & TF_CLEARONRESIZE) == 0) {
2262     MoveCursor(0, 0);
2263     BuffClearScreen();
2264     UpdateWindow(HVTWin);
2265     }
2266 doda 3802 }
2267    
2268 doda 3742 void CSQ_h_Mode() // DECSET
2269 maya 3227 {
2270     int i;
2271    
2272     for (i = 1 ; i<=NParam ; i++)
2273     switch (Param[i]) {
2274 doda 3742 case 1: AppliCursorMode = TRUE; break; // DECCKM
2275 doda 3802 case 3: CSQChangeColumnMode(132); break; // DECCOLM
2276 doda 3742 case 5: /* Reverse Video (DECSCNM) */
2277 maya 3227 if (!(ts.ColorFlag & CF_REVERSEVIDEO))
2278     CSQExchangeColor(); /* Exchange text/back color */
2279     break;
2280 doda 3742 case 6: // DECOM
2281 doda 3485 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2282 maya 3227 MoveCursor(0,CursorY);
2283     else {
2284     RelativeOrgMode = TRUE;
2285     MoveCursor(0,CursorTop);
2286     }
2287     break;
2288 doda 3742 case 7: AutoWrapMode = TRUE; break; // DECAWM
2289     case 8: AutoRepeatMode = TRUE; break; // DECARM
2290     case 9: /* X10 Mouse Tracking */
2291 maya 3227 if (ts.MouseEventTracking)
2292     MouseReportMode = IdMouseTrackX10;
2293     break;
2294 doda 3742 case 12: /* att610 cursor blinking */
2295 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
2296     ts.NonblinkingCursor = FALSE;
2297     ChangeCaret();
2298     }
2299     break;
2300 doda 3742 case 19: PrintEX = TRUE; break; // DECPEX
2301     case 25: DispEnableCaret(TRUE); break; // cursor on (DECTCEM)
2302     case 38: // DECTEK
2303 maya 3227 if (ts.AutoWinSwitch>0)
2304     ChangeEmu = IdTEK; /* Enter TEK Mode */
2305     break;
2306 doda 3743 case 47: // Alternate Screen Buffer
2307     if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2308     BuffSaveScreen();
2309     AltScr = TRUE;
2310     }
2311     break;
2312 maya 3227 case 59:
2313     if (ts.Language==IdJapanese)
2314     { /* kanji terminal */
2315     Gn[0] = IdASCII;
2316     Gn[1] = IdKatakana;
2317     Gn[2] = IdKatakana;
2318     Gn[3] = IdKanji;
2319     Glr[0] = 0;
2320     if ((ts.KanjiCode==IdJIS) &&
2321     (ts.JIS7Katakana==0))
2322     Glr[1] = 2; // 8-bit katakana
2323     else
2324     Glr[1] = 3;
2325     }
2326     break;
2327 doda 3742 case 66: AppliKeyMode = TRUE; break; // DECNKM
2328     case 67: ts.BSKey = IdBS; break; // DECBKM
2329     case 1000: // Mouse Tracking
2330 maya 3227 if (ts.MouseEventTracking)
2331     MouseReportMode = IdMouseTrackVT200;
2332     break;
2333 doda 3742 case 1001: // Hilite Mouse Tracking
2334 maya 3227 if (ts.MouseEventTracking)
2335     MouseReportMode = IdMouseTrackVT200Hl;
2336     break;
2337 doda 3742 case 1002: // Button-Event Mouse Tracking
2338 maya 3227 if (ts.MouseEventTracking)
2339     MouseReportMode = IdMouseTrackBtnEvent;
2340     break;
2341 doda 3742 case 1003: // Any-Event Mouse Tracking
2342 maya 3227 if (ts.MouseEventTracking)
2343     MouseReportMode = IdMouseTrackAllEvent;
2344     break;
2345 doda 3742 case 1004: // Focus Report
2346 maya 3227 if (ts.MouseEventTracking)
2347     FocusReportMode = TRUE;
2348     break;
2349 doda 3744 case 1047: // Alternate Screen Buffer
2350     if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2351     BuffSaveScreen();
2352     AltScr = TRUE;
2353     }
2354     break;
2355     case 1048: // Save Cursor Position (Alternate Screen Buffer)
2356     if (ts.TermFlag & TF_ALTSCR) {
2357     SaveCursor();
2358     }
2359 doda 3800 break;
2360 doda 3744 case 1049: // Alternate Screen Buffer
2361     if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
2362     SaveCursor();
2363     BuffSaveScreen();
2364     BuffClearScreen();
2365     AltScr = TRUE;
2366     }
2367 doda 3872 break;
2368     case 2004: // Bracketed Paste Mode
2369     BracketedPaste = TRUE;
2370     break;
2371 doda 4271 case 7727: // mintty Application Escape Mode
2372     AppliEscapeMode = TRUE;
2373     break;
2374 doda 3744 }
2375 maya 3227 }
2376    
2377 doda 4041 void CSQ_i_Mode() // DECMC
2378 maya 3227 {
2379     if (Param[1]==-1) Param[1] = 0;
2380     switch (Param[1]) {
2381     case 1:
2382     OpenPrnFile();
2383     BuffDumpCurrentLine(LF);
2384     if (! AutoPrintMode)
2385     ClosePrnFile();
2386     break;
2387     /* auto print mode off */
2388     case 4:
2389     if (AutoPrintMode)
2390     {
2391     ClosePrnFile();
2392     AutoPrintMode = FALSE;
2393     }
2394     break;
2395     /* auto print mode on */
2396     case 5:
2397     if (! AutoPrintMode)
2398     {
2399     OpenPrnFile();
2400     AutoPrintMode = TRUE;
2401     }
2402     break;
2403     }
2404     }
2405    
2406 doda 3742 void CSQ_l_Mode() // DECRST
2407 maya 3227 {
2408     int i;
2409    
2410     for (i = 1 ; i <= NParam ; i++)
2411     switch (Param[i]) {
2412 doda 3742 case 1: AppliCursorMode = FALSE; break; // DECCKM
2413 doda 3802 case 3: CSQChangeColumnMode(80); break; // DECCOLM
2414 doda 3742 case 5: /* Normal Video (DECSCNM) */
2415 maya 3227 if (ts.ColorFlag & CF_REVERSEVIDEO)
2416     CSQExchangeColor(); /* Exchange text/back color */
2417     break;
2418 doda 3742 case 6: // DECOM
2419 doda 3485 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2420 maya 3227 MoveCursor(0,CursorY);
2421     else {
2422     RelativeOrgMode = FALSE;
2423     MoveCursor(0,0);
2424     }
2425     break;
2426 doda 3742 case 7: AutoWrapMode = FALSE; break; // DECAWM
2427     case 8: AutoRepeatMode = FALSE; break; // DECARM
2428     case 9: MouseReportMode = IdMouseTrackNone; break; /* X10 Mouse Tracking */
2429     case 12: /* att610 cursor blinking */
2430 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
2431     ts.NonblinkingCursor = TRUE;
2432     ChangeCaret();
2433     }
2434     break;
2435 doda 3742 case 19: PrintEX = FALSE; break; // DECPEX
2436     case 25: DispEnableCaret(FALSE); break; // cursor off (DECTCEM)
2437 doda 3743 case 47: // Alternate Screen Buffer
2438     if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2439     BuffRestoreScreen();
2440     AltScr = FALSE;
2441     }
2442     break;
2443 maya 3227 case 59:
2444     if (ts.Language==IdJapanese)
2445     { /* katakana terminal */
2446     Gn[0] = IdASCII;
2447     Gn[1] = IdKatakana;
2448     Gn[2] = IdKatakana;
2449     Gn[3] = IdKanji;
2450     Glr[0] = 0;
2451     if ((ts.KanjiCode==IdJIS) &&
2452     (ts.JIS7Katakana==0))
2453     Glr[1] = 2; // 8-bit katakana
2454     else
2455     Glr[1] = 3;
2456     }
2457     break;
2458 doda 3742 case 66: AppliKeyMode = FALSE; break; // DECNKM
2459     case 67: ts.BSKey = IdDEL; break; // DECBKM
2460     case 1000: // Mouse Tracking
2461     case 1001: // Hilite Mouse Tracking
2462     case 1002: // Button-Event Mouse Tracking
2463 doda 3997 case 1003: // Any-Event Mouse Tracking
2464     MouseReportMode = IdMouseTrackNone;
2465     break;
2466 doda 3742 case 1004: FocusReportMode = FALSE; break; // Focus Report
2467 doda 3744 case 1047: // Alternate Screen Buffer
2468     if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2469     BuffClearScreen();
2470     BuffRestoreScreen();
2471     AltScr = FALSE;
2472     }
2473     break;
2474     case 1048: // Save Cursor Position (Alternate Screen Buffer)
2475     if (ts.TermFlag & TF_ALTSCR) {
2476     RestoreCursor();
2477     }
2478     break;
2479     case 1049: // Alternate Screen Buffer
2480     if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
2481     BuffClearScreen();
2482     BuffRestoreScreen();
2483 doda 3812 AltScr = FALSE;
2484 doda 3744 RestoreCursor();
2485     }
2486     break;
2487 doda 3872 case 2004: // Bracketed Paste Mode
2488     BracketedPaste = FALSE;
2489     break;
2490 doda 4271 case 7727: // mintty Application Escape Mode
2491     AppliEscapeMode = FALSE;
2492     break;
2493 maya 3227 }
2494     }
2495    
2496 doda 4041 void CSQ_n_Mode() // DECDSR
2497 maya 3227 {
2498 doda 4023 switch (Param[1]) {
2499     case 53:
2500 doda 4041 case 55:
2501 doda 4023 /* Locator Device Status Report -> Ready */
2502 doda 4024 SendCSIstr("?50n", 0);
2503 doda 4023 break;
2504     }
2505 maya 3227 }
2506    
2507     void CSQuest(BYTE b)
2508     {
2509     switch (b) {
2510 doda 4070 case 'J': CSQSelScreenErase(); break; // DECSED
2511     case 'K': CSQSelLineErase(); break; // DECSEL
2512 doda 3742 case 'h': CSQ_h_Mode(); break; // DECSET
2513 doda 4041 case 'i': CSQ_i_Mode(); break; // DECMC
2514 doda 3742 case 'l': CSQ_l_Mode(); break; // DECRST
2515 doda 4041 case 'n': CSQ_n_Mode(); break; // DECDSR
2516 maya 3227 }
2517     }
2518    
2519     void SoftReset()
2520     // called by software-reset escape sequence handler
2521     {
2522     UpdateStr();
2523     AutoRepeatMode = TRUE;
2524     DispEnableCaret(TRUE); // cursor on
2525     InsertMode = FALSE;
2526     RelativeOrgMode = FALSE;
2527     AppliKeyMode = FALSE;
2528     AppliCursorMode = FALSE;
2529 doda 4271 AppliEscapeMode = FALSE;
2530 maya 3227 if ((StatusLine>0) &&
2531     (CursorY == NumOfLines-1))
2532     MoveToMainScreen();
2533     CursorTop = 0;
2534     CursorBottom = NumOfLines-1-StatusLine;
2535     ResetCharSet();
2536    
2537     /* Attribute */
2538     CharAttr = DefCharAttr;
2539     Special = FALSE;
2540     BuffSetCurCharAttr(CharAttr);
2541    
2542     // status buffers
2543 doda 3916 ResetCurSBuffer();
2544 maya 3227 }
2545