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 8861 - (hide annotations) (download) (as text)
Sat Jul 25 16:00:36 2020 UTC (3 years, 8 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 154447 byte(s)
ログ/マクロ送信を別の文字コードで行えるようにした

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