Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8822 - (hide annotations) (download) (as text)
Thu Jul 2 15:41:37 2020 UTC (3 years, 9 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 152774 byte(s)
ログが取れなくなっていたので修正

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