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 8904 - (hide annotations) (download) (as text)
Tue Aug 18 15:31:14 2020 UTC (3 years, 7 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 152634 byte(s)
ログファイルへの文字コードの変換を filesys_log で行うようにした

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