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 5628 - (hide annotations) (download) (as text)
Tue Jul 1 03:19:07 2014 UTC (9 years, 9 months ago) by doda
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 133412 byte(s)
・DA2応答を変更。emacsのterm/xterm.elがDA2応答の第3パラメータを0に決め打ちしているため、それに合わせる。
・色問い合わせの応答を4桁に変更。xterm.elが4桁に決め打ちしているため、それに合わせる。


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