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 5502 - (hide annotations) (download) (as text)
Fri Mar 7 02:48:39 2014 UTC (10 years, 1 month ago) by doda
File MIME type: text/x-csrc
File size: 129655 byte(s)
コメント追加。

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