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 9115 - (hide annotations) (download) (as text)
Mon Dec 28 14:29:48 2020 UTC (3 years, 3 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 153874 byte(s)
エスケープシーケンスからの印字を修正

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