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 5429 - (hide annotations) (download) (as text)
Sat Nov 23 14:01:20 2013 UTC (10 years, 4 months ago) by doda
File MIME type: text/x-csrc
File size: 129312 byte(s)
・VPR/VPB/HPR/HPBがスクロールマージンの影響を受けていたのを修正
・CUU/VPBで画面上端を越えてカーソルが移動する場合があった問題を修正
・VPBで関係ないモードが解除される事がある問題を修正
https://sourceforge.jp/ticket/browse.php?group_id=1412&tid=31985

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