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 6512 - (hide annotations) (download) (as text)
Thu Oct 27 03:06:36 2016 UTC (7 years, 5 months ago) by doda
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 132962 byte(s)
EUC 設定で UTF-8 文字列を表示した後に UTF-8 設定に切り替えた時に、
漢字が正しく表示できなくなる事がある問題を修正。

再現手順:
  1. EUC 設定に変更
  2. echo "あ" | nkf -w ; cat を実行
  3. UTF-8 設定に変更
  4. Ctrl-C で cat を中断
  5. 以降、漢字が正しく表示できなくなる

原因:
  ConvJIS フラグのクリア漏れ

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