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 4291 - (hide annotations) (download) (as text)
Tue Feb 1 05:27:32 2011 UTC (13 years, 2 months ago) by doda
File MIME type: text/x-csrc
File size: 102434 byte(s)
DCS/SOS/APC/PM の直後の文字が正しく表示できないのを修正。

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