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 5564 - (hide annotations) (download) (as text)
Mon Mar 31 08:30:11 2014 UTC (10 years ago) by doda
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 130170 byte(s)
画面全体消去(ED 2)時に、カーソル位置をホームに移動するよう動作を変更可能にした。
# DECSET 8200 で設定

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