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 5558 - (hide annotations) (download) (as text)
Thu Mar 27 03:21:01 2014 UTC (10 years ago) by doda
File MIME type: text/x-csrc
File size: 129684 byte(s)
カーソル位置復元時にBCE用情報の更新を忘れていたのを修正。

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 doda 5558 BuffSetCurCharAttr(CharAttr);
1080 maya 3227 Glr[0] = Buff->Glr[0];
1081     Glr[1] = Buff->Glr[1];
1082     for (i=0 ; i<=3; i++)
1083     Gn[i] = Buff->Gn[i];
1084     AutoWrapMode = Buff->AutoWrapMode;
1085     RelativeOrgMode = Buff->RelativeOrgMode;
1086     }
1087    
1088     void AnswerTerminalType()
1089     {
1090 doda 4244 char Tmp[50];
1091 maya 3227
1092 doda 4873 if (ts.TerminalID<IdVT320 || !Send8BitMode)
1093 maya 3227 strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1094     else
1095     strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1096    
1097     switch (ts.TerminalID) {
1098     case IdVT100:
1099     strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1100     break;
1101     case IdVT100J:
1102     strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1103     break;
1104     case IdVT101:
1105     strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1106     break;
1107     case IdVT102:
1108     strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1109     break;
1110     case IdVT102J:
1111     strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1112     break;
1113     case IdVT220J:
1114     strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1115     break;
1116     case IdVT282:
1117     strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1118     break;
1119     case IdVT320:
1120     strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1121     break;
1122     case IdVT382:
1123     strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1124     break;
1125 doda 4084 case IdVT420:
1126     strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1127     break;
1128     case IdVT520:
1129     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1130     break;
1131     case IdVT525:
1132     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1133     break;
1134 maya 3227 }
1135     strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1136    
1137     CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1138     }
1139    
1140     void ESCSpace(BYTE b)
1141     {
1142     switch (b) {
1143 doda 4246 case 'F': // S7C1T
1144     Send8BitMode = FALSE;
1145     break;
1146     case 'G': // S8C1T
1147     if (VTlevel >= 2) {
1148     Send8BitMode = TRUE;
1149     }
1150     break;
1151 maya 3227 }
1152     }
1153    
1154     void ESCSharp(BYTE b)
1155     {
1156     switch (b) {
1157 doda 4097 case '8': /* Fill screen with "E" (DECALN) */
1158 maya 3227 BuffUpdateScroll();
1159     BuffFillWithE();
1160 doda 4097 CursorTop = 0;
1161     CursorBottom = NumOfLines-1-StatusLine;
1162 doda 5324 CursorLeftM = 0;
1163     CursorRightM = NumOfColumns - 1;
1164 maya 3227 MoveCursor(0,0);
1165     ParseMode = ModeFirst;
1166     break;
1167     }
1168     }
1169    
1170     /* select double byte code set */
1171     void ESCDBCSSelect(BYTE b)
1172     {
1173     int Dist;
1174    
1175     if (ts.Language!=IdJapanese) return;
1176    
1177     switch (ICount) {
1178     case 1:
1179     if ((b=='@') || (b=='B'))
1180     {
1181     Gn[0] = IdKanji; /* Kanji -> G0 */
1182     if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1183     Glr[0] = 0; /* G0->GL */
1184     }
1185     break;
1186     case 2:
1187     /* Second intermediate char must be
1188     '(' or ')' or '*' or '+'. */
1189     Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1190     if ((b=='1') || (b=='3') ||
1191     (b=='@') || (b=='B'))
1192     {
1193     Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1194     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1195     (Dist==0))
1196     Glr[0] = 0; /* G0->GL */
1197     }
1198     break;
1199     }
1200     }
1201    
1202     void ESCSelectCode(BYTE b)
1203     {
1204     switch (b) {
1205     case '0':
1206     if (ts.AutoWinSwitch>0)
1207     ChangeEmu = IdTEK; /* enter TEK mode */
1208     break;
1209     }
1210     }
1211    
1212     /* select single byte code set */
1213     void ESCSBCSSelect(BYTE b)
1214     {
1215     int Dist;
1216    
1217     /* Intermediate char must be
1218     '(' or ')' or '*' or '+'. */
1219     Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1220    
1221     switch (b) {
1222     case '0': Gn[Dist] = IdSpecial; break;
1223     case '<': Gn[Dist] = IdASCII; break;
1224     case '>': Gn[Dist] = IdASCII; break;
1225     case 'A': Gn[Dist] = IdASCII; break;
1226     case 'B': Gn[Dist] = IdASCII; break;
1227     case 'H': Gn[Dist] = IdASCII; break;
1228     case 'I':
1229     if (ts.Language==IdJapanese)
1230     Gn[Dist] = IdKatakana;
1231     break;
1232     case 'J': Gn[Dist] = IdASCII; break;
1233     }
1234    
1235     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1236     (Dist==0))
1237     Glr[0] = 0; /* G0->GL */
1238     }
1239    
1240     void PrnParseEscape(BYTE b) // printer mode
1241     {
1242     int i;
1243    
1244     ParseMode = ModeFirst;
1245     switch (ICount) {
1246     /* no intermediate char */
1247     case 0:
1248     switch (b) {
1249     case '[': /* CSI */
1250 doda 5073 ClearParams();
1251 maya 3227 FirstPrm = TRUE;
1252     WriteToPrnFile(ESC,FALSE);
1253     WriteToPrnFile('[',FALSE);
1254     ParseMode = ModeCSI;
1255     return;
1256     } /* end of case Icount=0 */
1257     break;
1258     /* one intermediate char */
1259     case 1:
1260     switch (IntChar[1]) {
1261     case '$':
1262     if (! DirectPrn)
1263     {
1264     ESCDBCSSelect(b);
1265     return;
1266     }
1267     break;
1268     case '(':
1269     case ')':
1270     case '*':
1271     case '+':
1272     if (! DirectPrn)
1273     {
1274     ESCSBCSSelect(b);
1275     return;
1276     }
1277     break;
1278     }
1279     break;
1280     /* two intermediate char */
1281     case 2:
1282     if ((! DirectPrn) &&
1283     (IntChar[1]=='$') &&
1284     ('('<=IntChar[2]) &&
1285     (IntChar[2]<='+'))
1286     {
1287     ESCDBCSSelect(b);
1288     return;
1289     }
1290     break;
1291     }
1292     // send the uninterpreted sequence to printer
1293     WriteToPrnFile(ESC,FALSE);
1294     for (i=1; i<=ICount; i++)
1295     WriteToPrnFile(IntChar[i],FALSE);
1296     WriteToPrnFile(b,TRUE);
1297     }
1298    
1299     void ParseEscape(BYTE b) /* b is the final char */
1300     {
1301     if (PrinterMode) { // printer mode
1302     PrnParseEscape(b);
1303     return;
1304     }
1305    
1306     switch (ICount) {
1307     /* no intermediate char */
1308     case 0:
1309     switch (b) {
1310 doda 4243 case '6': // DECBI
1311 doda 5431 if (CursorY >= CursorTop && CursorY <= CursorBottom
1312     && CursorX >= CursorLeftM && CursorX <= CursorRightM)
1313     {
1314     if (CursorX == CursorLeftM)
1315     BuffScrollRight(1);
1316     else
1317     MoveCursor(CursorX-1, CursorY);
1318 doda 4243 }
1319 doda 5431 break;
1320 maya 3227 case '7': SaveCursor(); break;
1321     case '8': RestoreCursor(); break;
1322 doda 4243 case '9': // DECFI
1323 doda 5431 if (CursorY >= CursorTop && CursorY <= CursorBottom
1324     && CursorX >= CursorLeftM && CursorX <= CursorRightM)
1325     {
1326     if (CursorX == CursorRightM)
1327     BuffScrollLeft(1);
1328     else
1329     MoveCursor(CursorX+1, CursorY);
1330 doda 4243 }
1331 doda 5431 break;
1332 maya 3227 case '=': AppliKeyMode = TRUE; break;
1333     case '>': AppliKeyMode = FALSE; break;
1334     case 'D': /* IND */
1335     LineFeed(0,TRUE);
1336     break;
1337     case 'E': /* NEL */
1338     MoveCursor(0,CursorY);
1339     LineFeed(0,TRUE);
1340     break;
1341     case 'H': /* HTS */
1342 doda 4687 if (ts.TabStopFlag & TABF_HTS7) SetTabStop();
1343 maya 3227 break;
1344     case 'M': /* RI */
1345     CursorUpWithScroll();
1346     break;
1347     case 'N': /* SS2 */
1348     GLtmp = 2;
1349     SSflag = TRUE;
1350     break;
1351     case 'O': /* SS3 */
1352     GLtmp = 3;
1353     SSflag = TRUE;
1354     break;
1355     case 'P': /* DCS */
1356 doda 5073 ClearParams();
1357 maya 3227 ESCFlag = FALSE;
1358     ParseMode = ModeDCS;
1359     return;
1360     case 'X': /* SOS */
1361     ESCFlag = FALSE;
1362     ParseMode = ModeSOS;
1363     return;
1364 doda 5073 case 'Z': /* DECID */
1365     AnswerTerminalType();
1366     break;
1367 maya 3227 case '[': /* CSI */
1368 doda 5073 ClearParams();
1369 maya 3227 FirstPrm = TRUE;
1370     ParseMode = ModeCSI;
1371     return;
1372     case '\\': break; /* ST */
1373     case ']': /* XTERM sequence (OSC) */
1374 doda 5073 ClearParams();
1375 maya 3227 ParseMode = ModeXS;
1376     return;
1377     case '^':
1378     case '_': /* PM, APC */
1379     ESCFlag = FALSE;
1380     ParseMode = ModeSOS;
1381     return;
1382     case 'c': /* Hardware reset */
1383     HideStatusLine();
1384     ResetTerminal();
1385     ClearUserKey();
1386     ClearBuffer();
1387     if (ts.PortType==IdSerial) // reset serial port
1388     CommResetSerial(&ts, &cv, TRUE);
1389     break;
1390     case 'g': /* Visual Bell (screen original?) */
1391 doda 5316 RingBell(IdBeepVisual);
1392 maya 3227 break;
1393     case 'n': Glr[0] = 2; break; /* LS2 */
1394     case 'o': Glr[0] = 3; break; /* LS3 */
1395     case '|': Glr[1] = 3; break; /* LS3R */
1396     case '}': Glr[1] = 2; break; /* LS2R */
1397     case '~': Glr[1] = 1; break; /* LS1R */
1398     } /* end of case Icount=0 */
1399     break;
1400     /* one intermediate char */
1401     case 1:
1402     switch (IntChar[1]) {
1403     case ' ': ESCSpace(b); break;
1404     case '#': ESCSharp(b); break;
1405     case '$': ESCDBCSSelect(b); break;
1406     case '%': break;
1407     case '(':
1408     case ')':
1409     case '*':
1410     case '+':
1411     ESCSBCSSelect(b);
1412     break;
1413     }
1414     break;
1415     /* two intermediate char */
1416     case 2:
1417     if ((IntChar[1]=='$') &&
1418     ('('<=IntChar[2]) &&
1419     (IntChar[2]<='+'))
1420     ESCDBCSSelect(b);
1421     else if ((IntChar[1]=='%') &&
1422     (IntChar[2]=='!'))
1423     ESCSelectCode(b);
1424     break;
1425     }
1426     ParseMode = ModeFirst;
1427     }
1428    
1429     void EscapeSequence(BYTE b)
1430     {
1431     if (b<=US)
1432     ParseControl(b);
1433     else if ((b>=0x20) && (b<=0x2F))
1434     {
1435     if (ICount<IntCharMax) ICount++;
1436     IntChar[ICount] = b;
1437     }
1438     else if ((b>=0x30) && (b<=0x7E))
1439     ParseEscape(b);
1440     else if ((b>=0x80) && (b<=0x9F))
1441     ParseControl(b);
1442 doda 4256 else if (b>=0xA0) {
1443     ParseMode=ModeFirst;
1444     ParseFirst(b);
1445     }
1446 maya 3227
1447     JustAfterESC = FALSE;
1448     }
1449    
1450 doda 5325 void CSInsertCharacter() // ICH
1451 maya 3227 {
1452     // Insert space characters at cursor
1453     int Count;
1454    
1455     BuffUpdateScroll();
1456     if (Param[1]<1) Param[1] = 1;
1457     Count = Param[1];
1458     BuffInsertSpace(Count);
1459     }
1460    
1461 doda 5429 void CSCursorUp(BOOL AffectMargin) // CUU / VPB
1462     {
1463     int topMargin, NewY;
1464 maya 3227
1465 doda 5429 if (Param[1]<1)
1466     Param[1] = 1;
1467 maya 3227
1468 doda 5429 if (AffectMargin && CursorY >= CursorTop)
1469     topMargin = CursorTop;
1470     else
1471     topMargin = 0;
1472 maya 3227
1473 doda 5429 NewY = CursorY - Param[1];
1474     if (NewY < topMargin)
1475     NewY = topMargin;
1476 maya 3227
1477 doda 5429 MoveCursor(CursorX, NewY);
1478     }
1479 maya 3227
1480 doda 5429 void CSCursorUp1() // CPL
1481     {
1482     MoveCursor(CursorLeftM, CursorY);
1483     CSCursorUp(TRUE);
1484     }
1485 maya 3227
1486 doda 5429 void CSCursorDown(BOOL AffectMargin) // CUD / VPR
1487     {
1488     int bottomMargin, NewY;
1489    
1490     if (Param[1]<1)
1491     Param[1] = 1;
1492    
1493     if (AffectMargin && CursorY <= CursorBottom)
1494     bottomMargin = CursorBottom;
1495     else
1496     bottomMargin = NumOfLines-StatusLine-1;
1497    
1498     NewY = CursorY + Param[1];
1499     if (NewY > bottomMargin)
1500     NewY = bottomMargin;
1501    
1502     MoveCursor(CursorX, NewY);
1503     }
1504    
1505     void CSCursorDown1() // CNL
1506     {
1507     MoveCursor(CursorLeftM, CursorY);
1508     CSCursorDown(TRUE);
1509     }
1510    
1511 maya 3227 void CSScreenErase()
1512     {
1513     BuffUpdateScroll();
1514     switch (Param[1]) {
1515     case 0:
1516     // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1517     // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1518     // �����������������B(2005.5.29 yutaka)
1519     // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1520     if (ts.ScrollWindowClearScreen &&
1521     (CursorX == 0 && CursorY == 0)) {
1522     // Erase screen (scroll out)
1523     BuffClearScreen();
1524     UpdateWindow(HVTWin);
1525    
1526     } else {
1527     // Erase characters from cursor to the end of screen
1528     BuffEraseCurToEnd();
1529     }
1530     break;
1531    
1532     case 1:
1533     // Erase characters from home to cursor
1534     BuffEraseHomeToCur();
1535     break;
1536    
1537     case 2:
1538     // Erase screen (scroll out)
1539     BuffClearScreen();
1540     UpdateWindow(HVTWin);
1541     break;
1542     }
1543     }
1544    
1545 doda 4070 void CSQSelScreenErase()
1546     {
1547     BuffUpdateScroll();
1548     switch (Param[1]) {
1549     case 0:
1550     // Erase characters from cursor to end
1551     BuffSelectedEraseCurToEnd();
1552     break;
1553    
1554     case 1:
1555     // Erase characters from home to cursor
1556     BuffSelectedEraseHomeToCur();
1557     break;
1558    
1559     case 2:
1560     // Erase entire screen
1561     BuffSelectedEraseScreen();
1562     break;
1563     }
1564     }
1565    
1566 maya 3227 void CSInsertLine()
1567     {
1568     // Insert lines at current position
1569     int Count, YEnd;
1570    
1571     if (CursorY < CursorTop) return;
1572     if (CursorY > CursorBottom) return;
1573     if (Param[1]<1) Param[1] = 1;
1574     Count = Param[1];
1575    
1576     YEnd = CursorBottom;
1577     if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1578     if (Count > YEnd+1 - CursorY) Count = YEnd+1 - CursorY;
1579    
1580     BuffInsertLines(Count,YEnd);
1581     }
1582    
1583     void CSLineErase()
1584     {
1585     BuffUpdateScroll();
1586     switch (Param[1]) {
1587     /* erase char from cursor to end of line */
1588     case 0:
1589     BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1590     break;
1591     /* erase char from start of line to cursor */
1592     case 1:
1593     BuffEraseCharsInLine(0,CursorX+1);
1594     break;
1595     /* erase entire line */
1596     case 2:
1597     BuffEraseCharsInLine(0,NumOfColumns);
1598     break;
1599     }
1600     }
1601    
1602 doda 4070 void CSQSelLineErase()
1603     {
1604     BuffUpdateScroll();
1605     switch (Param[1]) {
1606     /* erase char from cursor to end of line */
1607     case 0:
1608     BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1609     break;
1610     /* erase char from start of line to cursor */
1611     case 1:
1612     BuffSelectedEraseCharsInLine(0,CursorX+1);
1613     break;
1614     /* erase entire line */
1615     case 2:
1616     BuffSelectedEraseCharsInLine(0,NumOfColumns);
1617     break;
1618     }
1619     }
1620    
1621 maya 3227 void CSDeleteNLines()
1622     // Delete lines from current line
1623     {
1624     int Count, YEnd;
1625    
1626     if (CursorY < CursorTop) return;
1627     if (CursorY > CursorBottom) return;
1628     Count = Param[1];
1629     if (Count<1) Count = 1;
1630    
1631     YEnd = CursorBottom;
1632     if (CursorY > YEnd) YEnd = NumOfLines-1-StatusLine;
1633     if (Count > YEnd+1-CursorY) Count = YEnd+1-CursorY;
1634     BuffDeleteLines(Count,YEnd);
1635     }
1636    
1637 doda 5325 void CSDeleteCharacter() // DCH
1638 maya 3227 {
1639     // Delete characters in current line from cursor
1640    
1641     if (Param[1]<1) Param[1] = 1;
1642     BuffUpdateScroll();
1643     BuffDeleteChars(Param[1]);
1644     }
1645    
1646 doda 5325 void CSEraseCharacter() // ECH
1647 maya 3227 {
1648     if (Param[1]<1) Param[1] = 1;
1649     BuffUpdateScroll();
1650     BuffEraseChars(Param[1]);
1651     }
1652    
1653 doda 5324 void CSScrollUp()
1654 maya 3227 {
1655     if (Param[1]<1) Param[1] = 1;
1656     BuffUpdateScroll();
1657     BuffRegionScrollUpNLines(Param[1]);
1658     }
1659    
1660     void CSScrollDown()
1661     {
1662     if (Param[1]<1) Param[1] = 1;
1663     BuffUpdateScroll();
1664     BuffRegionScrollDownNLines(Param[1]);
1665     }
1666    
1667     void CSForwardTab()
1668     {
1669     if (Param[1]<1) Param[1] = 1;
1670     CursorForwardTab(Param[1], AutoWrapMode);
1671     }
1672    
1673     void CSBackwardTab()
1674     {
1675     if (Param[1]<1) Param[1] = 1;
1676     CursorBackwardTab(Param[1]);
1677     }
1678    
1679 doda 5324 void CSMoveToColumnN() // CHA / HPA
1680     {
1681     if (Param[1]<1)
1682     Param[1] = 1;
1683 doda 5503 else if (Param[1] > NumOfColumns)
1684     Param[1] = NumOfColumns;
1685 maya 3227
1686 doda 5324 Param[1]--;
1687 maya 3227
1688 doda 5324 if (RelativeOrgMode) {
1689     if (CursorLeftM + Param[1] > CursorRightM )
1690     MoveCursor(CursorRightM, CursorY);
1691     else
1692     MoveCursor(CursorLeftM + Param[1], CursorY);
1693     }
1694     else {
1695     MoveCursor(Param[1], CursorY);
1696     }
1697     }
1698 maya 3227
1699 doda 5429 void CSCursorRight(BOOL AffectMargin) // CUF / HPR
1700 doda 5324 {
1701 doda 5429 int NewX, rightMargin;
1702 doda 5324
1703     if (Param[1] < 1)
1704     Param[1] = 1;
1705    
1706 doda 5429 if (AffectMargin && CursorX <= CursorRightM)
1707     rightMargin = CursorRightM;
1708     else
1709     rightMargin = NumOfColumns-1;
1710    
1711 doda 5324 NewX = CursorX + Param[1];
1712 doda 5429 if (NewX > rightMargin)
1713     NewX = rightMargin;
1714 doda 5324
1715     MoveCursor(NewX, CursorY);
1716     }
1717    
1718 doda 5429 void CSCursorLeft(BOOL AffectMargin) // CUB / HPB
1719 doda 5324 {
1720 doda 5429 int NewX, leftMargin;
1721 doda 5324
1722     if (Param[1] < 1)
1723     Param[1] = 1;
1724    
1725 doda 5429 if (AffectMargin && CursorX >= CursorLeftM)
1726     leftMargin = CursorLeftM;
1727 doda 5324 else
1728 doda 5429 leftMargin = 0;
1729 doda 5324
1730 doda 5429 NewX = CursorX - Param[1];
1731     if (NewX < leftMargin)
1732     NewX = leftMargin;
1733 doda 5324
1734     MoveCursor(NewX, CursorY);
1735     }
1736    
1737 doda 5502 void CSMoveToLineN() // VPA
1738 maya 3227 {
1739     if (Param[1]<1) Param[1] = 1;
1740     if (RelativeOrgMode)
1741     {
1742     if (CursorTop+Param[1]-1 > CursorBottom)
1743     MoveCursor(CursorX,CursorBottom);
1744     else
1745     MoveCursor(CursorX,CursorTop+Param[1]-1);
1746     }
1747     else {
1748     if (Param[1] > NumOfLines-StatusLine)
1749     MoveCursor(CursorX,NumOfLines-1-StatusLine);
1750     else
1751     MoveCursor(CursorX,Param[1]-1);
1752     }
1753     }
1754    
1755 doda 5324 void CSMoveToXY() // CUP / HVP
1756     {
1757     int NewX, NewY;
1758 maya 3227
1759 doda 5324 if (Param[1] < 1)
1760     Param[1] = 1;
1761     else if (Param[1] > NumOfLines-StatusLine)
1762     Param[1] = NumOfLines-StatusLine;
1763 maya 3227
1764 doda 5324 if ((NParam < 2) || (Param[2]<1))
1765     Param[2] = 1;
1766     else if (Param[2] > NumOfColumns)
1767     Param[2] = NumOfColumns;
1768 maya 3227
1769 doda 5324 NewY = Param[1] - 1;
1770     NewX = Param[2] - 1;
1771    
1772     if (isCursorOnStatusLine)
1773     NewY = CursorY;
1774     else if (RelativeOrgMode) {
1775     NewX += CursorLeftM;
1776     if (NewX > CursorRightM)
1777     NewX = CursorRightM;
1778    
1779     NewY += CursorTop;
1780     if (NewY > CursorBottom)
1781     NewY = CursorBottom;
1782     }
1783     else {
1784     NewY = Param[1] - 1;
1785     if (NewY > NumOfLines-1-StatusLine)
1786     NewY = NumOfLines-1-StatusLine;
1787     }
1788    
1789     MoveCursor(NewX, NewY);
1790     }
1791    
1792 maya 3227 void CSDeleteTabStop()
1793     {
1794     ClearTabStop(Param[1]);
1795     }
1796    
1797 doda 3742 void CS_h_Mode() // SM
1798 maya 3227 {
1799     switch (Param[1]) {
1800 doda 3311 case 2: // KAM
1801     KeybEnabled = FALSE; break;
1802     case 4: // IRM
1803     InsertMode = TRUE; break;
1804     case 12: // SRM
1805 doda 3485 ts.LocalEcho = 0;
1806     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1807     TelChangeEcho();
1808     break;
1809 doda 3311 case 20: // LF/NL
1810 doda 3485 LFMode = TRUE;
1811     ts.CRSend = IdCRLF;
1812     cv.CRSend = IdCRLF;
1813     break;
1814 doda 3311 case 33: // WYSTCURM
1815 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1816     ts.NonblinkingCursor = TRUE;
1817     ChangeCaret();
1818     }
1819     break;
1820 doda 3311 case 34: // WYULCURM
1821 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1822     ts.CursorShape = IdHCur;
1823     ChangeCaret();
1824     }
1825     break;
1826 maya 3227 }
1827     }
1828    
1829 doda 3742 void CS_i_Mode() // MC
1830 maya 3227 {
1831     switch (Param[1]) {
1832     /* print screen */
1833     // PrintEX -- TRUE: print screen
1834     // FALSE: scroll region
1835 doda 4397 case 0:
1836     if (ts.TermFlag&TF_PRINTERCTRL) {
1837     BuffPrint(! PrintEX);
1838     }
1839     break;
1840 maya 3227 /* printer controller mode off */
1841     case 4: break; /* See PrnParseCS() */
1842     /* printer controller mode on */
1843     case 5:
1844 doda 4397 if (ts.TermFlag&TF_PRINTERCTRL) {
1845     if (! AutoPrintMode)
1846     OpenPrnFile();
1847     DirectPrn = (ts.PrnDev[0]!=0);
1848     PrinterMode = TRUE;
1849     }
1850 maya 3227 break;
1851     }
1852     }
1853    
1854 doda 3742 void CS_l_Mode() // RM
1855 maya 3227 {
1856     switch (Param[1]) {
1857 doda 3311 case 2: // KAM
1858     KeybEnabled = TRUE; break;
1859     case 4: // IRM
1860     InsertMode = FALSE; break;
1861     case 12: // SRM
1862 doda 3485 ts.LocalEcho = 1;
1863     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1864     TelChangeEcho();
1865     break;
1866 doda 3311 case 20: // LF/NL
1867 doda 3485 LFMode = FALSE;
1868     ts.CRSend = IdCR;
1869     cv.CRSend = IdCR;
1870     break;
1871 doda 3311 case 33: // WYSTCURM
1872 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1873     ts.NonblinkingCursor = FALSE;
1874     ChangeCaret();
1875     }
1876     break;
1877 doda 3311 case 34: // WYULCURM
1878 doda 3485 if (ts.WindowFlag & WF_CURSORCHANGE) {
1879     ts.CursorShape = IdBlkCur;
1880     ChangeCaret();
1881     }
1882     break;
1883 maya 3227 }
1884     }
1885    
1886 doda 3742 void CS_n_Mode() // DSR
1887 maya 3227 {
1888     char Report[16];
1889 doda 5336 int X, Y, len;
1890 maya 3227
1891     switch (Param[1]) {
1892     case 5:
1893 doda 3311 /* Device Status Report -> Ready */
1894 doda 4024 SendCSIstr("0n", 0);
1895 maya 3227 break;
1896     case 6:
1897     /* Cursor Position Report */
1898 doda 5336 if (isCursorOnStatusLine) {
1899     X = CursorX + 1;
1900 maya 3227 Y = 1;
1901 doda 5336 }
1902     else if (RelativeOrgMode) {
1903     X = CursorX - CursorLeftM + 1;
1904     Y = CursorY - CursorTop + 1;
1905     }
1906     else {
1907     X = CursorX + 1;
1908 doda 5324 Y = CursorY+1;
1909 doda 5336 }
1910     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, X);
1911 doda 3471 SendCSIstr(Report, len);
1912 maya 3227 break;
1913     }
1914     }
1915    
1916 doda 5095 void ParseSGRParams(PCharAttr attr, PCharAttr mask, int start)
1917 maya 3227 {
1918 doda 5073 int i, j, P, r, g, b, color;
1919 doda 5095 TCharAttr dummy;
1920 maya 3227
1921 doda 5095 if (mask == NULL) {
1922     mask = &dummy;
1923     }
1924    
1925     for (i=start ; i<=NParam ; i++)
1926 maya 3227 {
1927     P = Param[i];
1928     switch (P) {
1929     case 0: /* Clear all */
1930 doda 5095 attr->Attr = DefCharAttr.Attr;
1931     attr->Attr2 = DefCharAttr.Attr2 | (attr->Attr2&Attr2Protect);
1932     attr->Fore = DefCharAttr.Fore;
1933     attr->Back = DefCharAttr.Back;
1934     mask->Attr = AttrSgrMask;
1935     mask->Attr2 = Attr2ColorMask;
1936 maya 3227 break;
1937    
1938     case 1: /* Bold */
1939 doda 5095 attr->Attr |= AttrBold;
1940     mask->Attr |= AttrBold;
1941 maya 3227 break;
1942    
1943     case 4: /* Under line */
1944 doda 5095 attr->Attr |= AttrUnder;
1945     mask->Attr |= AttrUnder;
1946 maya 3227 break;
1947    
1948     case 5: /* Blink */
1949 doda 5095 attr->Attr |= AttrBlink;
1950     mask->Attr |= AttrBlink;
1951 maya 3227 break;
1952    
1953     case 7: /* Reverse */
1954 doda 5095 attr->Attr |= AttrReverse;
1955     mask->Attr |= AttrReverse;
1956 maya 3227 break;
1957    
1958     case 22: /* Bold off */
1959 doda 5095 attr->Attr &= ~ AttrBold;
1960     mask->Attr |= AttrBold;
1961 maya 3227 break;
1962    
1963     case 24: /* Under line off */
1964 doda 5095 attr->Attr &= ~ AttrUnder;
1965     mask->Attr |= AttrUnder;
1966 maya 3227 break;
1967    
1968     case 25: /* Blink off */
1969 doda 5095 attr->Attr &= ~ AttrBlink;
1970     mask->Attr |= AttrBlink;
1971 maya 3227 break;
1972    
1973     case 27: /* Reverse off */
1974 doda 5095 attr->Attr &= ~ AttrReverse;
1975     mask->Attr |= AttrReverse;
1976 maya 3227 break;
1977    
1978     case 30:
1979     case 31:
1980     case 32:
1981     case 33:
1982     case 34:
1983     case 35:
1984     case 36:
1985     case 37: /* text color */
1986 doda 5095 attr->Attr2 |= Attr2Fore;
1987     mask->Attr2 |= Attr2Fore;
1988     attr->Fore = P - 30;
1989 maya 3227 break;
1990    
1991     case 38: /* text color (256color mode) */
1992 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
1993     /*
1994     * Change foreground color. accept following formats.
1995     *
1996     * 38 ; 2 ; r ; g ; b
1997     * 38 ; 2 : r : g : b
1998     * 38 : 2 : r : g : b
1999     * 38 ; 5 ; idx
2000     * 38 ; 5 : idx
2001     * 38 : 5 : idx
2002     *
2003     */
2004     color = -1;
2005     j = 0;
2006     if (NSParam[i] > 0) {
2007     P = SubParam[i][1];
2008     j++;
2009     }
2010     else if (i < NParam) {
2011     P = Param[i+1];
2012     if (P == 2 || P == 5) {
2013     i++;
2014     }
2015     }
2016     switch (P) {
2017     case 2:
2018     r = g = b = 0;
2019     if (NSParam[i] > 0) {
2020     if (j < NSParam[i]) {
2021     r = SubParam[i][++j];
2022     if (j < NSParam[i]) {
2023     g = SubParam[i][++j];
2024     }
2025     if (j < NSParam[i]) {
2026     b = SubParam[i][++j];
2027     }
2028     color = DispFindClosestColor(r, g, b);
2029     }
2030     }
2031     else if (i < NParam && NSParam[i+1] > 0) {
2032     r = Param[++i];
2033     g = SubParam[i][1];
2034     if (NSParam[i] > 1) {
2035     b = SubParam[i][2];
2036     }
2037     color = DispFindClosestColor(r, g, b);
2038     }
2039     else if (i+2 < NParam) {
2040     r = Param[++i];
2041     g = Param[++i];
2042     b = Param[++i];
2043     color = DispFindClosestColor(r, g, b);
2044     }
2045     break;
2046     case 5:
2047     if (NSParam[i] > 0) {
2048     if (j < NSParam[i]) {
2049     color = SubParam[i][++j];
2050     }
2051     }
2052     else if (i < NParam) {
2053     color = Param[++i];
2054     }
2055     break;
2056     }
2057 doda 5077 if (color >= 0 && color < 256) {
2058 doda 5095 attr->Attr2 |= Attr2Fore;
2059     mask->Attr2 |= Attr2Fore;
2060     attr->Fore = color;
2061 maya 3227 }
2062     }
2063     break;
2064    
2065     case 39: /* Reset text color */
2066 doda 5095 attr->Attr2 &= ~ Attr2Fore;
2067     mask->Attr2 |= Attr2Fore;
2068     attr->Fore = AttrDefaultFG;
2069 maya 3227 break;
2070    
2071     case 40:
2072     case 41:
2073     case 42:
2074     case 43:
2075     case 44:
2076     case 45:
2077     case 46:
2078     case 47: /* Back color */
2079 doda 5095 attr->Attr2 |= Attr2Back;
2080     mask->Attr2 |= Attr2Back;
2081     attr->Back = P - 40;
2082 maya 3227 break;
2083    
2084     case 48: /* Back color (256color mode) */
2085 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
2086     color = -1;
2087     j = 0;
2088     if (NSParam[i] > 0) {
2089     P = SubParam[i][1];
2090     j++;
2091     }
2092     else if (i < NParam) {
2093     P = Param[i+1];
2094     if (P == 2 || P == 5) {
2095     i++;
2096     }
2097     }
2098     switch (P) {
2099     case 2:
2100     r = g = b = 0;
2101     if (NSParam[i] > 0) {
2102     if (j < NSParam[i]) {
2103     r = SubParam[i][++j];
2104     if (j < NSParam[i]) {
2105     g = SubParam[i][++j];
2106     }
2107     if (j < NSParam[i]) {
2108     b = SubParam[i][++j];
2109     }
2110     color = DispFindClosestColor(r, g, b);
2111     }
2112     }
2113     else if (i < NParam && NSParam[i+1] > 0) {
2114     r = Param[++i];
2115     g = SubParam[i][1];
2116     if (NSParam[i] > 1) {
2117     b = SubParam[i][2];
2118     }
2119     color = DispFindClosestColor(r, g, b);
2120     }
2121     else if (i+2 < NParam) {
2122     r = Param[++i];
2123     g = Param[++i];
2124     b = Param[++i];
2125     color = DispFindClosestColor(r, g, b);
2126     }
2127     break;
2128     case 5:
2129     if (NSParam[i] > 0) {
2130     if (j < NSParam[i]) {
2131     color = SubParam[i][++j];
2132     }
2133     }
2134     else if (i < NParam) {
2135     color = Param[++i];
2136     }
2137     break;
2138     }
2139 doda 5077 if (color >= 0 && color < 256) {
2140 doda 5095 attr->Attr2 |= Attr2Back;
2141     mask->Attr2 |= Attr2Back;
2142     attr->Back = color;
2143 maya 3227 }
2144     }
2145     break;
2146    
2147     case 49: /* Reset back color */
2148 doda 5095 attr->Attr2 &= ~ Attr2Back;
2149     mask->Attr2 |= Attr2Back;
2150     attr->Back = AttrDefaultBG;
2151 maya 3227 break;
2152    
2153     case 90:
2154     case 91:
2155     case 92:
2156     case 93:
2157     case 94:
2158     case 95:
2159     case 96:
2160     case 97: /* aixterm style text color */
2161     if (ts.ColorFlag & CF_AIXTERM16) {
2162 doda 5095 attr->Attr2 |= Attr2Fore;
2163     mask->Attr2 |= Attr2Fore;
2164     attr->Fore = P - 90 + 8;
2165 maya 3227 }
2166     break;
2167    
2168     case 100:
2169     if (! (ts.ColorFlag & CF_AIXTERM16)) {
2170     /* Reset text and back color */
2171 doda 5095 attr->Attr2 &= ~ (Attr2Fore | Attr2Back);
2172     mask->Attr2 |= Attr2ColorMask;
2173     attr->Fore = AttrDefaultFG;
2174     attr->Back = AttrDefaultBG;
2175 maya 3227 break;
2176     }
2177     /* fall through to aixterm style back color */
2178    
2179     case 101:
2180     case 102:
2181     case 103:
2182     case 104:
2183     case 105:
2184     case 106:
2185     case 107: /* aixterm style back color */
2186     if (ts.ColorFlag & CF_AIXTERM16) {
2187 doda 5095 attr->Attr2 |= Attr2Back;
2188     mask->Attr2 |= Attr2Back;
2189     attr->Back = P - 100 + 8;
2190 maya 3227 }
2191     break;
2192     }
2193     }
2194     }
2195    
2196 doda 5095 void CSSetAttr() // SGR
2197     {
2198     UpdateStr();
2199     ParseSGRParams(&CharAttr, NULL, 1);
2200     BuffSetCurCharAttr(CharAttr);
2201     }
2202    
2203 doda 5502 void CSSetScrollRegion() // DECSTBM
2204 maya 3227 {
2205 doda 5324 if (isCursorOnStatusLine) {
2206 maya 3227 MoveCursor(0,CursorY);
2207     return;
2208     }
2209     if (Param[1]<1) Param[1] =1;
2210     if ((NParam < 2) | (Param[2]<1))
2211     Param[2] = NumOfLines-StatusLine;
2212     Param[1]--;
2213     Param[2]--;
2214     if (Param[1] > NumOfLines-1-StatusLine)
2215     Param[1] = NumOfLines-1-StatusLine;
2216     if (Param[2] > NumOfLines-1-StatusLine)
2217     Param[2] = NumOfLines-1-StatusLine;
2218     if (Param[1] >= Param[2]) return;
2219     CursorTop = Param[1];
2220     CursorBottom = Param[2];
2221     if (RelativeOrgMode) MoveCursor(0,CursorTop);
2222     else MoveCursor(0,0);
2223     }
2224    
2225 doda 5502 void CSSetLRScrollRegion() // DECSLRM
2226 doda 5324 {
2227     // if (isCursorOnStatusLine) {
2228     // MoveCursor(0,CursorY);
2229     // return;
2230     // }
2231    
2232     if (Param[1] < 1)
2233     Param[1] =1;
2234     else if (Param[1] > NumOfColumns)
2235     Param[1] = NumOfColumns;
2236    
2237     if (NParam < 2 || Param[2] < 1 || Param[2] > NumOfColumns)
2238     Param[2] = NumOfColumns;
2239    
2240     if (Param[1] >= Param[2])
2241     return;
2242    
2243     Param[1]--;
2244     Param[2]--;
2245    
2246     CursorLeftM = Param[1];
2247     CursorRightM = Param[2];
2248    
2249     if (RelativeOrgMode)
2250     MoveCursor(CursorLeftM, CursorTop);
2251     else
2252     MoveCursor(0, 0);
2253     }
2254    
2255 maya 3227 void CSSunSequence() /* Sun terminal private sequences */
2256     {
2257 doda 3471 int x, y, len;
2258 doda 3487 char Report[TitleBuffSize*2+10];
2259 doda 5096 PTStack t;
2260 maya 3227
2261     switch (Param[1]) {
2262 doda 3302 case 1: // De-iconify window
2263 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2264     DispShowWindow(WINDOW_RESTORE);
2265 doda 3302 break;
2266     case 2: // Iconify window
2267 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2268     DispShowWindow(WINDOW_MINIMIZE);
2269 doda 3302 break;
2270     case 3: // set window position
2271 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2272     if (NParam < 2) Param[2] = 0;
2273     if (NParam < 3) Param[3] = 0;
2274     DispMoveWindow(Param[2], Param[3]);
2275     }
2276 doda 3297 break;
2277 doda 3466 case 4: // set window size
2278 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2279     if (NParam < 2) Param[2] = 0;
2280     if (NParam < 3) Param[3] = 0;
2281     DispResizeWin(Param[3], Param[2]);
2282     }
2283 doda 3464 break;
2284 doda 3311 case 5: // Raise window
2285 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2286     DispShowWindow(WINDOW_RAISE);
2287 doda 3309 break;
2288 doda 3311 case 6: // Lower window
2289 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2290     DispShowWindow(WINDOW_LOWER);
2291 doda 3309 break;
2292 doda 3311 case 7: // Refresh window
2293 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE)
2294     DispShowWindow(WINDOW_REFRESH);
2295 doda 3310 break;
2296 maya 3227 case 8: /* set terminal size */
2297 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2298     if ((Param[2]<=1) || (NParam<2)) Param[2] = 24;
2299     if ((Param[3]<=1) || (NParam<3)) Param[3] = 80;
2300     ChangeTerminalSize(Param[3],Param[2]);
2301     }
2302 maya 3227 break;
2303 doda 3302 case 9: // Maximize/Restore window
2304 doda 3485 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2305     if (NParam < 2 || Param[2] == 0) {
2306     DispShowWindow(WINDOW_RESTORE);
2307     }
2308 doda 3489 else if (Param[2] == 1) {
2309 doda 3485 DispShowWindow(WINDOW_MAXIMIZE);
2310     }
2311 doda 3302 }
2312     break;
2313 doda 3466 case 11: // Report window state
2314 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2315     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
2316     SendCSIstr(Report, len);
2317     }
2318 doda 3466 break;
2319 doda 3469 case 13: // Report window position
2320 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2321     DispGetWindowPos(&x, &y);
2322 doda 4474 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%u;%ut", CLocale, (unsigned int)x, (unsigned int)y);
2323 doda 3485 SendCSIstr(Report, len);
2324     }
2325 doda 3469 break;
2326 doda 4259 case 14: /* get window size */
2327 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2328 doda 4250 DispGetWindowSize(&x, &y);
2329     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "4;%d;%dt", CLocale, y, x);
2330     SendCSIstr(Report, len);
2331 doda 3485 }
2332 maya 3227 break;
2333     case 18: /* get terminal size */
2334 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2335 doda 4947 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%ut", CLocale,
2336 doda 3485 NumOfLines-StatusLine, NumOfColumns);
2337     SendCSIstr(Report, len);
2338     }
2339 maya 3227 break;
2340 doda 3475 case 19: // Report display size (character)
2341 doda 3485 if (ts.WindowFlag & WF_WINDOWREPORT) {
2342     DispGetRootWinSize(&x, &y);
2343     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
2344     SendCSIstr(Report, len);
2345     }
2346 doda 3475 break;
2347 doda 3487 case 20: // Report icon label
2348 doda 3747 switch (ts.WindowFlag & WF_TITLEREPORT) {
2349 doda 3774 case IdTitleReportIgnore:
2350 doda 3747 // nothing to do
2351     break;
2352 doda 3774 case IdTitleReportAccept:
2353 doda 3747 switch (ts.AcceptTitleChangeRequest) {
2354     case IdTitleChangeRequestOff:
2355 doda 3487 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2356 doda 3747 break;
2357     case IdTitleChangeRequestAhead:
2358     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, cv.TitleRemote, ts.Title);
2359     break;
2360     case IdTitleChangeRequestLast:
2361     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, ts.Title, cv.TitleRemote);
2362     break;
2363     default:
2364     if (cv.TitleRemote[0] == 0) {
2365     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2366     }
2367     else {
2368     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, cv.TitleRemote);
2369     }
2370     }
2371     SendOSCstr(Report, len);
2372     break;
2373     default: // IdTitleReportEmpty:
2374 doda 4024 SendOSCstr("L", 0);
2375 doda 3747 break;
2376 doda 3487 }
2377     break;
2378     case 21: // Report window title
2379 doda 3747 switch (ts.WindowFlag & WF_TITLEREPORT) {
2380 doda 3774 case IdTitleReportIgnore:
2381 doda 3747 // nothing to do
2382     break;
2383 doda 3774 case IdTitleReportAccept:
2384 doda 3747 switch (ts.AcceptTitleChangeRequest) {
2385     case IdTitleChangeRequestOff:
2386 doda 3487 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2387 doda 3747 break;
2388     case IdTitleChangeRequestAhead:
2389     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, cv.TitleRemote, ts.Title);
2390     break;
2391     case IdTitleChangeRequestLast:
2392     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, ts.Title, cv.TitleRemote);
2393     break;
2394     default:
2395     if (cv.TitleRemote[0] == 0) {
2396     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2397     }
2398     else {
2399     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, cv.TitleRemote);
2400     }
2401     }
2402     SendOSCstr(Report, len);
2403     break;
2404     default: // IdTitleReportEmpty:
2405 doda 4024 SendOSCstr("l", 0);
2406 doda 3747 break;
2407 doda 3487 }
2408     break;
2409 doda 5096 case 22: // Push Title
2410     if (NParam < 2) {
2411     Param[2] = 0;
2412     }
2413     switch (Param[2]) {
2414     case 0:
2415     case 1:
2416     case 2:
2417     if (ts.AcceptTitleChangeRequest && (t=malloc(sizeof(TStack))) != NULL) {
2418     if ((t->title = _strdup(cv.TitleRemote)) != NULL) {
2419     t->next = TitleStack;
2420     TitleStack = t;
2421     }
2422     else {
2423     free(t);
2424     }
2425     }
2426     break;
2427     }
2428     break;
2429     case 23: // Pop Title
2430     if (NParam < 2) {
2431     Param[2] = 0;
2432     }
2433     switch (Param[2]) {
2434     case 0:
2435     case 1:
2436     case 2:
2437     if (ts.AcceptTitleChangeRequest && TitleStack != NULL) {
2438     t = TitleStack;
2439     TitleStack = t->next;
2440     strncpy_s(cv.TitleRemote, sizeof(cv.TitleRemote), t->title, _TRUNCATE);
2441     ChangeTitle();
2442     free(t->title);
2443     free(t);
2444     }
2445     break;
2446     }
2447 maya 3227 }
2448     }
2449    
2450 doda 4278 void CSLT(BYTE b)
2451     {
2452     switch (b) {
2453     case 'r':
2454     if (CanUseIME()) {
2455     SetIMEOpenStatus(IMEstat);
2456     }
2457     break;
2458    
2459     case 's':
2460     if (CanUseIME()) {
2461     IMEstat = GetIMEOpenStatus();
2462     }
2463     break;
2464    
2465     case 't':
2466     if (CanUseIME()) {
2467     SetIMEOpenStatus(Param[1] == 1);
2468     }
2469     break;
2470     }
2471     }
2472    
2473 doda 4162 void CSEQ(BYTE b)
2474     {
2475 doda 4217 char Report[16];
2476     int len;
2477    
2478 doda 4162 switch (b) {
2479     case 'c': /* Tertiary terminal report (Tertiary DA) */
2480     if (Param[1] < 1) {
2481 doda 4217 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "!|%8s", CLocale, ts.TerminalUID);
2482     SendDCSstr(Report, len);
2483 doda 4162 }
2484     break;
2485     }
2486     }
2487    
2488 maya 3227 void CSGT(BYTE b)
2489     {
2490     switch (b) {
2491 doda 3311 case 'c': /* second terminal report (Secondary DA) */
2492 doda 3472 if (Param[1] < 1) {
2493 doda 4024 SendCSIstr(">32;100;2c", 0); /* VT382 */
2494 doda 3472 }
2495 maya 3227 break;
2496 doda 4101 case 'J': // IO-8256 terminal
2497     if (Param[1]==3) {
2498     if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2499     if (Param[3] < 1 || NParam < 3) Param[3] = 1;
2500 doda 4199 if (Param[4] < 1 || NParam < 4) Param[4] = NumOfLines-StatusLine;
2501     if (Param[5] < 1 || NParam < 5) Param[5] = NumOfColumns;
2502 doda 4101 BuffEraseBox(Param[3]-1, Param[2]-1, Param[5]-1, Param[4]-1);
2503 maya 3227 }
2504     break;
2505 doda 4101 case 'K': // IO-8256 terminal
2506     switch (Param[1]) {
2507     case 3:
2508     if (Param[2] < 1 || NParam < 2) Param[2] = 1;
2509     if (Param[3]