Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


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