Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10936 - (hide annotations) (download) (as text)
Sat Sep 16 14:32:22 2023 UTC (6 months, 3 weeks ago) by zmatsuo
File MIME type: text/x-csrc
File size: 134821 byte(s)
ウィンドウタイトルをスタックに保存(CSI 22)が行えない場合があったので修正

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