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 8897 - (hide annotations) (download) (as text)
Tue Aug 18 15:27:54 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 155352 byte(s)
ログに関するコードを filesys_log.c に移動した

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