Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8329 - (hide annotations) (download) (as text)
Thu Oct 24 10:41:21 2019 UTC (4 years, 5 months ago) by doda
File MIME type: text/x-csrc
File size: 141281 byte(s)
REP 制御シーケンスに対応した。

Ticket: #39451

問題:
  REP 制御シーケンスに対応していない。
  ncurses-6.1 付属の terminfo の xterm エントリでは rep が定義されて
  いる為、これを参照および使用するプログラムの表示が正しく行われない
  可能性がある。

対処:
  REP 制御シーケンスに対応した。

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