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 8860 - (hide annotations) (download) (as text)
Sat Jul 25 16:00:24 2020 UTC (3 years, 8 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 152926 byte(s)
マクロ(ttmacro)用送信バッファの分離

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