Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8910 - (show annotations) (download) (as text)
Tue Aug 18 15:32:07 2020 UTC (3 years, 7 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 152938 byte(s)
タイムスタンプがうまく出なかったので修正
1 /*
2 * Copyright (C) 1994-1998 T. Teranishi
3 * (C) 2004-2020 TeraTerm Project
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 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 *
18 * 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 */
29
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 #include <ctype.h>
38 #if !defined(_CRTDBG_MAP_ALLOC)
39 #define _CRTDBG_MAP_ALLOC
40 #endif
41 #include <stdlib.h>
42 #include <crtdbg.h>
43 #include <assert.h>
44
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 #include "ttime.h"
57 #include "clipboar.h"
58 #include "codeconv.h"
59 #include "unicode.h"
60 #include "ttdde.h"
61 #include "checkeol.h"
62
63 #include "vtterm.h"
64
65 #include "unicode_test.h"
66
67 static void ParseFirst(BYTE b);
68
69 #define Accept8BitCtrl ((VTlevel >= 2) && (ts.TermFlag & TF_ACCEPT8BITCTRL))
70
71 /* 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 #define ModeIgnore 9
82
83 #define NParamMax 16
84 #define NSParamMax 16
85 #define IntCharMax 5
86
87 /* 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 void RingBell(int type);
95 void VisualBell();
96 BOOL DecLocatorReport(int Event, int Button);
97
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 static BOOL ClearThenHome;
106 static BOOL AutoWrapMode;
107 static BOOL FocusReportMode;
108 static BOOL AltScr;
109 static BOOL LRMarginMode;
110 static BOOL RectangleMode;
111 static BOOL BracketedPaste;
112
113 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
118 static int VTlevel;
119
120 static BOOL AcceptWheelToCursor;
121
122 // save/restore cursor
123 typedef struct {
124 int CursorX, CursorY;
125 TCharAttr Attr;
126 int Glr[2], Gn[4]; // G0-G3, GL & GR
127 BOOL AutoWrapMode;
128 BOOL RelativeOrgMode;
129 } TStatusBuff;
130 typedef TStatusBuff *PStatusBuff;
131
132 // currently only used for AUTO CR/LF receive mode
133 static BYTE PrevCharacter;
134 static BOOL PrevCRorLFGeneratedCRLF; // indicates that previous CR or LF really generated a CR+LF
135
136 static BYTE LastPutCharacter;
137
138 // status buffer for main screen & status line
139 static TStatusBuff SBuff1, SBuff2, SBuff3;
140
141 static BOOL ESCFlag, JustAfterESC;
142 static BOOL KanjiIn; // TRUE = MBCS��1byte�������M��������
143 static BOOL EUCkanaIn, EUCsupIn;
144 static int EUCcount;
145 static BOOL Special;
146
147 static int Param[NParamMax+1];
148 static int SubParam[NParamMax+1][NSParamMax+1];
149 static int NParam, NSParam[NParamMax+1];
150 static BOOL FirstPrm;
151 static BYTE IntChar[IntCharMax+1];
152 static int ICount;
153 static BYTE Prv;
154 static int ParseMode;
155 static int ChangeEmu;
156
157 typedef struct tstack {
158 char *title;
159 struct tstack *next;
160 } TStack;
161 typedef TStack *PTStack;
162 static PTStack TitleStack = NULL;
163
164 /* 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 static BOOL Fallbacked;
179
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 static BOOL PrintEX = TRUE; // printing extent
191 // (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 /* Mouse Report */
201 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
208 /* Saved IME status */
209 static BOOL SavedIMEstatus;
210
211 /* Beep over-used */
212 static DWORD BeepStartTime = 0;
213 static DWORD BeepSuppressTime = 0;
214 static DWORD BeepOverUsedCount = 0;
215
216 static _locale_t CLocale = NULL;
217
218 typedef struct {
219 CheckEOLData_t *check_eol;
220 int log_cr_type;
221 } vtterm_work_t;
222
223 static vtterm_work_t vtterm_work;
224
225 void ClearParams()
226 {
227 ICount = 0;
228 NParam = 1;
229 NSParam[1] = 0;
230 Param[1] = 0;
231 Prv = 0;
232 }
233
234 void ResetSBuffer(PStatusBuff sbuff)
235 {
236 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 }
261
262 void ResetAllSBuffers()
263 {
264 ResetSBuffer(&SBuff1);
265 // copy SBuff1 to SBuff2
266 SBuff2 = SBuff1;
267 SBuff3 = SBuff1;
268 }
269
270 void ResetCurSBuffer()
271 {
272 PStatusBuff Buff;
273
274 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 }
283
284 void ResetTerminal() /*reset variables but don't update screen */
285 {
286 DispReset();
287 BuffReset();
288
289 /* Attribute */
290 CharAttr = DefCharAttr;
291 Special = FALSE;
292 BuffSetCurCharAttr(CharAttr);
293
294 /* 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 RectangleMode = FALSE;
311
312 ChangeTerminalID();
313
314 LastX = 0;
315 LastY = 0;
316 ButtonStat = 0;
317
318 if (CLocale == NULL) {
319 CLocale = _create_locale(LC_ALL, "C");
320 }
321
322 /* Character sets */
323 ResetCharSet();
324
325 /* ESC flag for device control sequence */
326 ESCFlag = FALSE;
327 /* for TEK sequence */
328 JustAfterESC = FALSE;
329
330 /* Parse mode */
331 ParseMode = ModeFirst;
332
333 /* Clear printer mode */
334 PrinterMode = FALSE;
335
336 // status buffers
337 ResetAllSBuffers();
338
339 // Alternate Screen Buffer
340 AltScr = FALSE;
341
342 // Left/Right Margin Mode
343 LRMarginMode = FALSE;
344
345 // Bracketed Paste Mode
346 BracketedPaste = FALSE;
347
348 // Saved IME Status
349 SavedIMEstatus = FALSE;
350
351 // previous received character
352 PrevCharacter = -1; // none
353 PrevCRorLFGeneratedCRLF = FALSE;
354
355 LastPutCharacter = 0;
356
357 // Beep over-used
358 BeepStartTime = GetTickCount();
359 BeepSuppressTime = BeepStartTime - ts.BeepSuppressTime * 1000;
360 BeepStartTime -= (ts.BeepOverUsedTime * 1000);
361 BeepOverUsedCount = ts.BeepOverUsedCount;
362
363 {
364 vtterm_work_t *vtterm = &vtterm_work;
365 vtterm->check_eol = CheckEOLCreate();
366 vtterm->log_cr_type = 0;
367 }
368 }
369
370 void ResetCharSet()
371 {
372 char *result;
373 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
404 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
413 // ���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 // �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 if (result)
428 ts.CodePage = atoi(strrchr(result, '.')+1);
429 else
430 ts.CodePage = GetACP();
431 }
432
433 void ResetKeypadMode(BOOL DisabledModeOnly)
434 {
435 if (!DisabledModeOnly || ts.DisableAppKeypad)
436 AppliKeyMode = FALSE;
437 if (!DisabledModeOnly || ts.DisableAppCursor)
438 AppliCursorMode = FALSE;
439 }
440
441 void MoveToMainScreen()
442 {
443 StatusX = CursorX;
444 StatusWrap = Wrap;
445 StatusCursor = IsCaretEnabled();
446
447 CursorTop = MainTop;
448 CursorBottom = MainBottom;
449 Wrap = MainWrap;
450 DispEnableCaret(MainCursor);
451 MoveCursor(MainX, MainY); // move to main screen
452 }
453
454 /**
455 * 1�L�����N�^(unsigned int, char32_t)��macro���o��
456 */
457 static void DDEPut1U32(unsigned int u32)
458 {
459 if (DDELog) {
460 // UTF-8 ���o������
461 char u8_buf[4];
462 size_t u8_len = UTF32ToUTF8(u32, u8_buf, _countof(u8_buf));
463 size_t i;
464 for (i = 0; i < u8_len; i++) {
465 BYTE b = u8_buf[i];
466 DDEPut1(b);
467 }
468 }
469 }
470
471 /**
472 * ���O���������������s�R�[�h���o��
473 */
474 static void OutputLogNewLine(vtterm_work_t *vtterm)
475 {
476 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 }
491 }
492
493 /**
494 * 1�L�����N�^(unsigned int, char32_t)�����O(or/and macro���M�o�b�t�@)���o��
495 */
496 static void OutputLogUTF32(unsigned int u32)
497 {
498 vtterm_work_t *vtterm;
499 CheckEOLRet r;
500
501 if (!FLogIsOpendText() && !DDELog) {
502 return;
503 }
504 vtterm = &vtterm_work;
505 r = CheckEOLCheck(vtterm->check_eol, u32);
506 if ((r & CheckEOLOutputEOL) != 0) {
507 // ���O�A���s���o��
508 if (FLogIsOpendText()) {
509 OutputLogNewLine(vtterm);
510 }
511
512 // �}�N���A���s���o��
513 if (DDELog) {
514 DDEPut1(CR);
515 DDEPut1(LF);
516 }
517 }
518 if ((r & CheckEOLOutputChar) != 0) {
519 // ���O�Au32���o��
520 if (FLogIsOpendText()) {
521 FLogPutUTF32(u32);
522 }
523
524 // �}�N���Au32���o��
525 if (DDELog) {
526 DDEPut1U32(u32);
527 }
528 }
529 }
530
531 /**
532 * 1�L�����N�^(BYTE)�����O(or/and macro���M�o�b�t�@)���o��
533 */
534 static void OutputLogByte(BYTE b)
535 {
536 OutputLogUTF32(b);
537 }
538
539 /**
540 * ���O(or/and Macro���M�o�b�t�@)�o�����K�v��������?
541 */
542 static BOOL NeedsOutputBufs(void)
543 {
544 return FLogIsOpendText() || DDELog;
545 }
546
547 void MoveToStatusLine()
548 {
549 MainX = CursorX;
550 MainY = CursorY;
551 MainTop = CursorTop;
552 MainBottom = CursorBottom;
553 MainWrap = Wrap;
554 MainCursor = IsCaretEnabled();
555
556 DispEnableCaret(StatusCursor);
557 MoveCursor(StatusX, NumOfLines-1); // move to status line
558 CursorTop = NumOfLines-1;
559 CursorBottom = CursorTop;
560 Wrap = StatusWrap;
561 }
562
563 void HideStatusLine()
564 {
565 if (isCursorOnStatusLine)
566 MoveToMainScreen();
567 StatusX = 0;
568 StatusWrap = FALSE;
569 StatusCursor = TRUE;
570 ShowStatusLine(0); //hide
571 }
572
573 void ChangeTerminalSize(int Nx, int Ny)
574 {
575 BuffChangeTerminalSize(Nx, Ny);
576 StatusX = 0;
577 MainX = 0;
578 MainY = 0;
579 MainTop = 0;
580 MainBottom = NumOfLines-StatusLine-1;
581 }
582
583 void SendCSIstr(char *str, int len) {
584 int l;
585
586 if (str == NULL || len < 0)
587 return;
588
589 if (len == 0) {
590 l = strlen(str);
591 }
592 else {
593 l = len;
594 }
595
596 if (Send8BitMode)
597 CommBinaryOut(&cv,"\233", 1);
598 else
599 CommBinaryOut(&cv,"\033[", 2);
600
601 CommBinaryOut(&cv, str, l);
602 }
603
604 void SendOSCstr(char *str, int len, char TermChar) {
605 int l;
606
607 if (str == NULL || len < 0)
608 return;
609
610 if (len == 0) {
611 l = strlen(str);
612 }
613 else {
614 l = len;
615 }
616
617 if (TermChar == BEL) {
618 CommBinaryOut(&cv,"\033]", 2);
619 CommBinaryOut(&cv, str, l);
620 CommBinaryOut(&cv,"\007", 1);
621 }
622 else if (Send8BitMode) {
623 CommBinaryOut(&cv,"\235", 1);
624 CommBinaryOut(&cv, str, l);
625 CommBinaryOut(&cv,"\234", 1);
626 }
627 else {
628 CommBinaryOut(&cv,"\033]", 2);
629 CommBinaryOut(&cv, str, l);
630 CommBinaryOut(&cv,"\033\\", 2);
631 }
632
633 }
634
635 void SendDCSstr(char *str, int len) {
636 int l;
637
638 if (str == NULL || len < 0)
639 return;
640
641 if (len == 0) {
642 l = strlen(str);
643 }
644 else {
645 l = len;
646 }
647
648 if (Send8BitMode) {
649 CommBinaryOut(&cv,"\220", 1);
650 CommBinaryOut(&cv, str, l);
651 CommBinaryOut(&cv,"\234", 1);
652 }
653 else {
654 CommBinaryOut(&cv,"\033P", 2);
655 CommBinaryOut(&cv, str, l);
656 CommBinaryOut(&cv,"\033\\", 2);
657 }
658
659 }
660
661 void BackSpace()
662 {
663 if (CursorX == CursorLeftM || CursorX == 0) {
664 if (CursorY > 0 && (ts.TermFlag & TF_BACKWRAP)) {
665 MoveCursor(CursorRightM, CursorY-1);
666 if (NeedsOutputBufs() && !ts.LogTypePlainText) OutputLogByte(BS);
667 }
668 }
669 else if (CursorX > 0) {
670 MoveCursor(CursorX-1, CursorY);
671 if (NeedsOutputBufs() && !ts.LogTypePlainText) OutputLogByte(BS);
672 }
673 }
674
675 static void CarriageReturn(BOOL logFlag)
676 {
677 if (!ts.EnableContinuedLineCopy || logFlag)
678 if (NeedsOutputBufs()) OutputLogByte(CR);
679
680 if (RelativeOrgMode || CursorX > CursorLeftM)
681 MoveCursor(CursorLeftM, CursorY);
682 else if (CursorX < CursorLeftM)
683 MoveCursor(0, CursorY);
684
685 Fallbacked = FALSE;
686 }
687
688 static void LineFeed(BYTE b, BOOL logFlag)
689 {
690 /* for auto print mode */
691 if ((AutoPrintMode) &&
692 (b>=LF) && (b<=FF))
693 BuffDumpCurrentLine(b);
694
695 if (!ts.EnableContinuedLineCopy || logFlag)
696 if (NeedsOutputBufs()) OutputLogByte(LF);
697
698 if (CursorY < CursorBottom)
699 MoveCursor(CursorX,CursorY+1);
700 else if (CursorY == CursorBottom) BuffScrollNLines(1);
701 else if (CursorY < NumOfLines-StatusLine-1)
702 MoveCursor(CursorX,CursorY+1);
703
704 ClearLineContinued();
705
706 if (LFMode) CarriageReturn(logFlag);
707
708 Fallbacked = FALSE;
709 }
710
711 void Tab()
712 {
713 if (Wrap && !ts.VTCompatTab) {
714 CarriageReturn(FALSE);
715 LineFeed(LF,FALSE);
716 if (ts.EnableContinuedLineCopy) {
717 SetLineContinued();
718 }
719 Wrap = FALSE;
720 }
721 CursorForwardTab(1, AutoWrapMode);
722 if (NeedsOutputBufs()) OutputLogByte(HT);
723 }
724
725 void RepeatChar(BYTE b, int count)
726 {
727 int i;
728 BOOL SpecialNew;
729 TCharAttr CharAttrTmp, CharAttrWrap;
730
731 if (b <= US || b == DEL)
732 return;
733
734 CharAttrTmp = CharAttr;
735 LastPutCharacter = 0;
736
737 SpecialNew = FALSE;
738 if ((b>0x5F) && (b<0x80)) {
739 if (SSflag)
740 SpecialNew = (Gn[GLtmp]==IdSpecial);
741 else
742 SpecialNew = (Gn[Glr[0]]==IdSpecial);
743 }
744 else if (b>0xDF) {
745 if (SSflag)
746 SpecialNew = (Gn[GLtmp]==IdSpecial);
747 else
748 SpecialNew = (Gn[Glr[1]]==IdSpecial);
749 }
750
751 if (SpecialNew != Special) {
752 UpdateStr();
753 Special = SpecialNew;
754 }
755
756 if (Special) {
757 b = b & 0x7F;
758 CharAttrTmp.Attr |= AttrSpecial;
759 }
760 else
761 CharAttrTmp.Attr |= CharAttr.Attr;
762 CharAttrTmp.AttrEx = CharAttrTmp.Attr;
763
764 CharAttrWrap = CharAttrTmp;
765 CharAttrWrap.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
766
767 for (i=0; i<count; i++) {
768 if (Wrap) {
769 CarriageReturn(FALSE);
770 LineFeed(LF,FALSE);
771 }
772
773 BuffPutChar(b, Wrap ? CharAttrWrap : CharAttrTmp, InsertMode);
774
775 if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) {
776 UpdateStr();
777 Wrap = AutoWrapMode;
778 }
779 else {
780 Wrap = FALSE;
781 MoveRight();
782 }
783 }
784 }
785
786 static void PutChar(BYTE b)
787 {
788 BOOL SpecialNew;
789 TCharAttr CharAttrTmp;
790
791 CharAttrTmp = CharAttr;
792
793 LastPutCharacter = b;
794
795 if (PrinterMode) { // printer mode
796 WriteToPrnFile(b,TRUE);
797 return;
798 }
799
800 if (Wrap) {
801 #if UNICODE_INTERNAL_BUFF
802 TCharAttr t = BuffGetCursorCharAttr(CursorX, CursorY);
803 t.Attr |= AttrLineContinued;
804 t.AttrEx = t.Attr;
805 BuffSetCursorCharAttr(CursorX, CursorY, t);
806 #endif
807 CarriageReturn(FALSE);
808 LineFeed(LF,FALSE);
809 #if !UNICODE_INTERNAL_BUFF
810 CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
811 #else
812 CharAttrTmp.Attr |= AttrLineContinued;
813 t.AttrEx = t.Attr;
814 #endif
815 }
816
817 if (NeedsOutputBufs()) {
818 // (2005.2.20 yutaka)
819 if (ts.LogTypePlainText) {
820 if (__isascii(b) && !isprint(b)) {
821 // ASCII�������A���\�������������O�����������B
822 } else {
823 OutputLogByte(b);
824 }
825 } else {
826 OutputLogByte(b);
827 }
828 }
829
830 Wrap = FALSE;
831
832 SpecialNew = FALSE;
833 if ((b>0x5F) && (b<0x80)) {
834 if (SSflag)
835 SpecialNew = (Gn[GLtmp]==IdSpecial);
836 else
837 SpecialNew = (Gn[Glr[0]]==IdSpecial);
838 }
839 else if (b>0xDF) {
840 if (SSflag)
841 SpecialNew = (Gn[GLtmp]==IdSpecial);
842 else
843 SpecialNew = (Gn[Glr[1]]==IdSpecial);
844 }
845
846 if (SpecialNew != Special) {
847 UpdateStr();
848 Special = SpecialNew;
849 }
850
851 if (Special) {
852 b = b & 0x7F;
853 CharAttrTmp.Attr |= AttrSpecial;
854 }
855 else
856 CharAttrTmp.Attr |= CharAttr.Attr;
857
858 #if 0
859 if (CursorX == CursorRightM || CursorX >= NumOfColumns - 1) {
860 CharAttrTmp.Attr |= AttrLineContinued;
861 }
862 #endif
863
864 #if UNICODE_INTERNAL_BUFF
865 CharAttrTmp.AttrEx = CharAttrTmp.Attr;
866 if (ts.Language == IdJapanese) {
867 unsigned long u32;
868 switch (ts.KanjiCode) {
869 // case IdJIS:
870 // b = JIS2SJIS(b);
871 case IdSJIS:
872 u32 = MBCP_UTF32(b, 932);
873 BuffPutUnicode(u32, CharAttrTmp, InsertMode);
874 break;
875 case IdUTF8:
876 BuffPutUnicode(b, CharAttrTmp, InsertMode);
877 break;
878 default:
879 BuffPutUnicode(b, CharAttrTmp, InsertMode);
880 break;
881 }
882 } else if (ts.Language == IdRussian) {
883 BYTE c = RussConv(ts.RussHost, IdWindows, b);
884 unsigned long u32 = MBCP_UTF32(c, 1251);
885 BuffPutUnicode(u32, CharAttrTmp, InsertMode);
886 } else {
887 BuffPutUnicode(b, CharAttrTmp, InsertMode);
888 }
889 #else
890 BuffPutChar(b, CharAttrTmp, InsertMode);
891 #endif
892
893 if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) {
894 UpdateStr();
895 Wrap = AutoWrapMode;
896 }
897 else {
898 MoveRight();
899 }
900 }
901
902 static void PutDecSp(BYTE b)
903 {
904 TCharAttr CharAttrTmp;
905
906 CharAttrTmp = CharAttr;
907
908 if (PrinterMode) { // printer mode
909 WriteToPrnFile(b, TRUE);
910 return;
911 }
912
913 if (Wrap) {
914 CarriageReturn(FALSE);
915 LineFeed(LF, FALSE);
916 CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
917 }
918
919 if (NeedsOutputBufs()) OutputLogByte(b);
920 /*
921 if (ts.LogTypePlainText && __isascii(b) && !isprint(b)) {
922 // ASCII�������A���\�������������O�����������B
923 } else {
924 if (NeedsOutputBufs()) OutputLogByte(b);
925 }
926 */
927
928 Wrap = FALSE;
929
930 if (!Special) {
931 UpdateStr();
932 Special = TRUE;
933 }
934
935 CharAttrTmp.Attr |= AttrSpecial;
936 #if UNICODE_INTERNAL_BUFF
937 CharAttrTmp.AttrEx = CharAttrTmp.Attr;
938 #endif
939 BuffPutChar(b, CharAttrTmp, InsertMode);
940
941 if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) {
942 UpdateStr();
943 Wrap = AutoWrapMode;
944 }
945 else {
946 MoveRight();
947 }
948 }
949
950 /**
951 * mbcs���o��
952 */
953 static void PutKanji(BYTE b)
954 {
955 int LineEnd;
956 TCharAttr CharAttrTmp;
957 CharAttrTmp = CharAttr;
958
959 Kanji = Kanji + b;
960
961 if (PrinterMode && DirectPrn) {
962 WriteToPrnFile(HIBYTE(Kanji),FALSE);
963 WriteToPrnFile(LOBYTE(Kanji),TRUE);
964 return;
965 }
966
967 if (ConvJIS)
968 Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f));
969
970 if (PrinterMode) { // printer mode
971 WriteToPrnFile(HIBYTE(Kanji),FALSE);
972 WriteToPrnFile(LOBYTE(Kanji),TRUE);
973 return;
974 }
975
976 if (CursorX > CursorRightM)
977 LineEnd = NumOfColumns - 1;
978 else
979 LineEnd = CursorRightM;
980
981 if (Wrap) {
982 CarriageReturn(FALSE);
983 LineFeed(LF,FALSE);
984 #if !UNICODE_INTERNAL_BUFF
985 if (ts.EnableContinuedLineCopy)
986 CharAttrTmp.Attr |= AttrLineContinued;
987 #else
988 if (ts.EnableContinuedLineCopy) {
989 CharAttrTmp.Attr |= AttrLineContinued;
990 CharAttrTmp.AttrEx = CharAttrTmp.Attr;
991 }
992 #endif
993 }
994 else if (CursorX > LineEnd - 1) {
995 if (AutoWrapMode) {
996 if (ts.EnableContinuedLineCopy) {
997 CharAttrTmp.Attr |= AttrLineContinued;
998 #if UNICODE_INTERNAL_BUFF
999 CharAttrTmp.AttrEx = CharAttrTmp.Attr;
1000 #endif
1001 if (CursorX == LineEnd)
1002 BuffPutChar(0x20, CharAttr, FALSE);
1003 }
1004 CarriageReturn(FALSE);
1005 LineFeed(LF,FALSE);
1006 }
1007 else {
1008 return;
1009 }
1010 }
1011
1012 Wrap = FALSE;
1013
1014 if (NeedsOutputBufs()) {
1015 OutputLogByte(HIBYTE(Kanji));
1016 OutputLogByte(LOBYTE(Kanji));
1017 }
1018
1019 if (Special) {
1020 UpdateStr();
1021 Special = FALSE;
1022 }
1023
1024 #if UNICODE_INTERNAL_BUFF
1025 {
1026 // codepage����
1027 // https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-ucoderef/28fefe92-d66c-4b03-90a9-97b473223d43
1028 unsigned long u32 = 0;
1029 switch (ts.Language) {
1030 case IdJapanese:
1031 // �������������_��CP932������������
1032 u32 = CP932ToUTF32(Kanji);
1033 break;
1034 case IdKorean:
1035 if (ts.KanjiCode == IdKoreanCP51949) {
1036 // CP51949
1037 u32 = MBCP_UTF32(Kanji, 51949);
1038 }
1039 else {
1040 assert(FALSE);
1041 goto default_;
1042 }
1043 break;
1044 case IdChinese:
1045 if (ts.KanjiCode == IdCnGB2312) {
1046 // CP936 GB2312
1047 u32 = MBCP_UTF32(Kanji, 936);
1048 }
1049 else if (ts.KanjiCode == IdCnBig5) {
1050 // CP950 Big5
1051 u32 = MBCP_UTF32(Kanji, 950);
1052 }
1053 else {
1054 assert(FALSE);
1055 goto default_;
1056 }
1057 break;
1058 default:
1059 default_:
1060 assert(FALSE);
1061 u32 = MBCP_UTF32(Kanji, ts.CodePage);
1062 break;
1063 }
1064 CharAttrTmp.AttrEx = CharAttrTmp.Attr;
1065 BuffPutUnicode(u32, CharAttrTmp, InsertMode);
1066 }
1067 #else
1068 BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
1069 #endif
1070
1071 if (CursorX < LineEnd - 1) {
1072 MoveRight();
1073 MoveRight();
1074 }
1075 else {
1076 if (CursorX == LineEnd - 1) {
1077 MoveRight();
1078 }
1079 UpdateStr();
1080 Wrap = AutoWrapMode;
1081 }
1082 }
1083
1084 void PutDebugChar(BYTE b)
1085 {
1086 static BYTE buff[3];
1087 int i;
1088 BOOL svInsertMode, svAutoWrapMode;
1089 BYTE svCharAttr;
1090
1091 if (DebugFlag!=DEBUG_FLAG_NOUT) {
1092 svInsertMode = InsertMode;
1093 svAutoWrapMode = AutoWrapMode;
1094 InsertMode = FALSE;
1095 AutoWrapMode = TRUE;
1096
1097 svCharAttr = CharAttr.Attr;
1098 if (CharAttr.Attr != AttrDefault) {
1099 UpdateStr();
1100 CharAttr.Attr = AttrDefault;
1101 }
1102
1103 if (DebugFlag==DEBUG_FLAG_HEXD) {
1104 _snprintf(buff, 3, "%02X", (unsigned int) b);
1105
1106 for (i=0; i<2; i++)
1107 PutChar(buff[i]);
1108 PutChar(' ');
1109 }
1110 else if (DebugFlag==DEBUG_FLAG_NORM) {
1111
1112 if ((b & 0x80) == 0x80) {
1113 UpdateStr();
1114 CharAttr.Attr = AttrReverse;
1115 b = b & 0x7f;
1116 }
1117
1118 if (b<=US) {
1119 PutChar('^');
1120 PutChar((char)(b+0x40));
1121 }
1122 else if (b==DEL) {
1123 PutChar('<');
1124 PutChar('D');
1125 PutChar('E');
1126 PutChar('L');
1127 PutChar('>');
1128 }
1129 else
1130 PutChar(b);
1131 }
1132
1133 if (CharAttr.Attr != svCharAttr) {
1134 UpdateStr();
1135 CharAttr.Attr = svCharAttr;
1136 }
1137 InsertMode = svInsertMode;
1138 AutoWrapMode = svAutoWrapMode;
1139 }
1140 }
1141
1142 static void PrnParseControl(BYTE b) // printer mode
1143 {
1144 switch (b) {
1145 case NUL:
1146 return;
1147 case SO:
1148 if ((ts.ISO2022Flag & ISO2022_SO) && ! DirectPrn) {
1149 if ((ts.Language==IdJapanese) &&
1150 (ts.KanjiCode==IdJIS) &&
1151 (ts.JIS7Katakana==1) &&
1152 ((ts.TermFlag & TF_FIXEDJIS)!=0))
1153 {
1154 Gn[1] = IdKatakana;
1155 }
1156 Glr[0] = 1; /* LS1 */
1157 return;
1158 }
1159 break;
1160 case SI:
1161 if ((ts.ISO2022Flag & ISO2022_SI) && ! DirectPrn) {
1162 Glr[0] = 0; /* LS0 */
1163 return;
1164 }
1165 break;
1166 case DC1:
1167 case DC3:
1168 return;
1169 case ESC:
1170 ICount = 0;
1171 JustAfterESC = TRUE;
1172 ParseMode = ModeESC;
1173 WriteToPrnFile(0, TRUE); // flush prn buff
1174 return;
1175 case CSI:
1176 if (! Accept8BitCtrl) {
1177 PutChar(b); /* Disp C1 char in VT100 mode */
1178 return;
1179 }
1180 ClearParams();
1181 FirstPrm = TRUE;
1182 ParseMode = ModeCSI;
1183 WriteToPrnFile(0, TRUE); // flush prn buff
1184 WriteToPrnFile(b, FALSE);
1185 return;
1186 }
1187 /* send the uninterpreted character to printer */
1188 WriteToPrnFile(b, TRUE);
1189 }
1190
1191 static void ParseControl(BYTE b)
1192 {
1193 if (PrinterMode) { // printer mode
1194 PrnParseControl(b);
1195 return;
1196 }
1197
1198 if (b>=0x80) { /* C1 char */
1199 if (ts.Language==IdEnglish) { /* English mode */
1200 if (!Accept8BitCtrl) {
1201 PutChar(b); /* Disp C1 char in VT100 mode */
1202 return;
1203 }
1204 }
1205 else { /* Japanese mode */
1206 if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0) {
1207 return; /* ignore C1 char */
1208 }
1209 /* C1 chars are interpreted as C0 chars in VT100 mode */
1210 if (VTlevel < 2) {
1211 b = b & 0x7F;
1212 }
1213 }
1214 }
1215 switch (b) {
1216 /* C0 group */
1217 case ENQ:
1218 CommBinaryOut(&cv, &(ts.Answerback[0]), ts.AnswerbackLen);
1219 break;
1220 case BEL:
1221 if (ts.Beep != IdBeepOff)
1222 RingBell(ts.Beep);
1223 break;
1224 case BS:
1225 BackSpace();
1226 break;
1227 case HT:
1228 Tab();
1229 break;
1230 case LF:
1231 if (ts.CRReceive == IdLF) {
1232 // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
1233 // CR+LF���������������������B
1234 // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
1235 // (2007.1.21 yutaka)
1236 CarriageReturn(TRUE);
1237 LineFeed(b, TRUE);
1238 break;
1239 }
1240 else if (ts.CRReceive == IdAUTO) {
1241 // 9th Apr 2012: AUTO CR/LF mode (tentner)
1242 // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
1243 if(PrevCharacter != CR || !PrevCRorLFGeneratedCRLF) {
1244 CarriageReturn(TRUE);
1245 LineFeed(b, TRUE);
1246 PrevCRorLFGeneratedCRLF = TRUE;
1247 }
1248 else {
1249 PrevCRorLFGeneratedCRLF = FALSE;
1250 }
1251 break;
1252 }
1253
1254 case VT:
1255 LineFeed(b, TRUE);
1256 break;
1257
1258 case FF:
1259 if ((ts.AutoWinSwitch>0) && JustAfterESC) {
1260 CommInsert1Byte(&cv, b);
1261 CommInsert1Byte(&cv, ESC);
1262 ChangeEmu = IdTEK; /* Enter TEK Mode */
1263 }
1264 else
1265 LineFeed(b, TRUE);
1266 break;
1267 case CR:
1268 if (ts.CRReceive == IdAUTO) {
1269 // 9th Apr 2012: AUTO CR/LF mode (tentner)
1270 // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
1271 if(PrevCharacter != LF || !PrevCRorLFGeneratedCRLF) {
1272 CarriageReturn(TRUE);
1273 LineFeed(b, TRUE);
1274 PrevCRorLFGeneratedCRLF = TRUE;
1275 }
1276 else {
1277 PrevCRorLFGeneratedCRLF = FALSE;
1278 }
1279 }
1280 else {
1281 CarriageReturn(TRUE);
1282 if (ts.CRReceive==IdCRLF) {
1283 CommInsert1Byte(&cv, LF);
1284 }
1285 }
1286 break;
1287 case SO: /* LS1 */
1288 if (ts.ISO2022Flag & ISO2022_SO) {
1289 if ((ts.Language==IdJapanese) &&
1290 (ts.KanjiCode==IdJIS) &&
1291 (ts.JIS7Katakana==1) &&
1292 ((ts.TermFlag & TF_FIXEDJIS)!=0))
1293 {
1294 Gn[1] = IdKatakana;
1295 }
1296
1297 Glr[0] = 1;
1298 }
1299 break;
1300 case SI: /* LS0 */
1301 if (ts.ISO2022Flag & ISO2022_SI) {
1302 Glr[0] = 0;
1303 }
1304 break;
1305 case DLE:
1306 if ((ts.FTFlag & FT_BPAUTO)!=0)
1307 ParseMode = ModeDLE; /* Auto B-Plus activation */
1308 break;
1309 case CAN:
1310 if ((ts.FTFlag & FT_ZAUTO)!=0)
1311 ParseMode = ModeCAN; /* Auto ZMODEM activation */
1312 // else if (ts.AutoWinSwitch>0)
1313 // ChangeEmu = IdTEK; /* Enter TEK Mode */
1314 else
1315 ParseMode = ModeFirst;
1316 break;
1317 case SUB:
1318 ParseMode = ModeFirst;
1319 break;
1320 case ESC:
1321 ICount = 0;
1322 JustAfterESC = TRUE;
1323 ParseMode = ModeESC;
1324 break;
1325 case FS:
1326 case GS:
1327 case RS:
1328 case US:
1329 if (ts.AutoWinSwitch>0) {
1330 CommInsert1Byte(&cv, b);
1331 ChangeEmu = IdTEK; /* Enter TEK Mode */
1332 }
1333 break;
1334
1335 /* C1 char */
1336 case IND:
1337 LineFeed(0, TRUE);
1338 break;
1339 case NEL:
1340 LineFeed(0, TRUE);
1341 CarriageReturn(TRUE);
1342 break;
1343 case HTS:
1344 if (ts.TabStopFlag & TABF_HTS8)
1345 SetTabStop();
1346 break;
1347 case RI:
1348 CursorUpWithScroll();
1349 break;
1350 case SS2:
1351 if (ts.ISO2022Flag & ISO2022_SS2) {
1352 GLtmp = 2;
1353 SSflag = TRUE;
1354 }
1355 break;
1356 case SS3:
1357 if (ts.ISO2022Flag & ISO2022_SS3) {
1358 GLtmp = 3;
1359 SSflag = TRUE;
1360 }
1361 break;
1362 case DCS:
1363 ClearParams();
1364 ESCFlag = FALSE;
1365 ParseMode = ModeDCS;
1366 break;
1367 case SOS:
1368 ESCFlag = FALSE;
1369 ParseMode = ModeIgnore;
1370 break;
1371 case CSI:
1372 ClearParams();
1373 FirstPrm = TRUE;
1374 ParseMode = ModeCSI;
1375 break;
1376 case OSC:
1377 ClearParams();
1378 ParseMode = ModeXS;
1379 break;
1380 case PM:
1381 case APC:
1382 ESCFlag = FALSE;
1383 ParseMode = ModeIgnore;
1384 break;
1385 }
1386 }
1387
1388 void SaveCursor()
1389 {
1390 int i;
1391 PStatusBuff Buff;
1392
1393 if (isCursorOnStatusLine)
1394 Buff = &SBuff2; // for status line
1395 else if (AltScr)
1396 Buff = &SBuff3; // for alternate screen
1397 else
1398 Buff = &SBuff1; // for main screen
1399
1400 Buff->CursorX = CursorX;
1401 Buff->CursorY = CursorY;
1402 Buff->Attr = CharAttr;
1403
1404 Buff->Glr[0] = Glr[0];
1405 Buff->Glr[1] = Glr[1];
1406 for (i=0 ; i<=3; i++)
1407 Buff->Gn[i] = Gn[i];
1408
1409 Buff->AutoWrapMode = AutoWrapMode;
1410 Buff->RelativeOrgMode = RelativeOrgMode;
1411 }
1412
1413 void RestoreCursor()
1414 {
1415 int i;
1416 PStatusBuff Buff;
1417
1418 UpdateStr();
1419
1420 if (isCursorOnStatusLine)
1421 Buff = &SBuff2; // for status line
1422 else if (AltScr)
1423 Buff = &SBuff3; // for alternate screen
1424 else
1425 Buff = &SBuff1; // for main screen
1426
1427 if (Buff->CursorX > NumOfColumns-1)
1428 Buff->CursorX = NumOfColumns-1;
1429 if (Buff->CursorY > NumOfLines-1-StatusLine)
1430 Buff->CursorY = NumOfLines-1-StatusLine;
1431 MoveCursor(Buff->CursorX, Buff->CursorY);
1432
1433 CharAttr = Buff->Attr;
1434 BuffSetCurCharAttr(CharAttr);
1435
1436 Glr[0] = Buff->Glr[0];
1437 Glr[1] = Buff->Glr[1];
1438 for (i=0 ; i<=3; i++)
1439 Gn[i] = Buff->Gn[i];
1440
1441 AutoWrapMode = Buff->AutoWrapMode;
1442 RelativeOrgMode = Buff->RelativeOrgMode;
1443 }
1444
1445 void AnswerTerminalType()
1446 {
1447 char Tmp[50];
1448
1449 if (ts.TerminalID<IdVT320 || !Send8BitMode)
1450 strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1451 else
1452 strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1453
1454 switch (ts.TerminalID) {
1455 case IdVT100:
1456 strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1457 break;
1458 case IdVT100J:
1459 strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1460 break;
1461 case IdVT101:
1462 strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1463 break;
1464 case IdVT102:
1465 strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1466 break;
1467 case IdVT102J:
1468 strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1469 break;
1470 case IdVT220J:
1471 strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1472 break;
1473 case IdVT282:
1474 strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1475 break;
1476 case IdVT320:
1477 strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1478 break;
1479 case IdVT382:
1480 strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1481 break;
1482 case IdVT420:
1483 strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1484 break;
1485 case IdVT520:
1486 strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1487 break;
1488 case IdVT525:
1489 strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1490 break;
1491 }
1492 strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1493
1494 CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1495 }
1496
1497 void ESCSpace(BYTE b)
1498 {
1499 switch (b) {
1500 case 'F': // S7C1T
1501 Send8BitMode = FALSE;
1502 break;
1503 case 'G': // S8C1T
1504 if (VTlevel >= 2) {
1505 Send8BitMode = TRUE;
1506 }
1507 break;
1508 }
1509 }
1510
1511 void ESCSharp(BYTE b)
1512 {
1513 switch (b) {
1514 case '8': /* Fill screen with "E" (DECALN) */
1515 BuffUpdateScroll();
1516 BuffFillWithE();
1517 CursorTop = 0;
1518 CursorBottom = NumOfLines-1-StatusLine;
1519 CursorLeftM = 0;
1520 CursorRightM = NumOfColumns - 1;
1521 MoveCursor(0, 0);
1522 ParseMode = ModeFirst;
1523 break;
1524 }
1525 }
1526
1527 /* select double byte code set */
1528 void ESCDBCSSelect(BYTE b)
1529 {
1530 int Dist;
1531
1532 if (ts.Language!=IdJapanese) return;
1533
1534 switch (ICount) {
1535 case 1:
1536 if ((b=='@') || (b=='B'))
1537 {
1538 Gn[0] = IdKanji; /* Kanji -> G0 */
1539 if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1540 Glr[0] = 0; /* G0->GL */
1541 }
1542 break;
1543 case 2:
1544 /* Second intermediate char must be
1545 '(' or ')' or '*' or '+'. */
1546 Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1547 if ((b=='1') || (b=='3') ||
1548 (b=='@') || (b=='B'))
1549 {
1550 Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1551 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1552 (Dist==0))
1553 Glr[0] = 0; /* G0->GL */
1554 }
1555 break;
1556 }
1557 }
1558
1559 void ESCSelectCode(BYTE b)
1560 {
1561 switch (b) {
1562 case '0':
1563 if (ts.AutoWinSwitch>0)
1564 ChangeEmu = IdTEK; /* enter TEK mode */
1565 break;
1566 }
1567 }
1568
1569 /* select single byte code set */
1570 void ESCSBCSSelect(BYTE b)
1571 {
1572 int Dist;
1573
1574 /* Intermediate char must be '(' or ')' or '*' or '+'. */
1575 Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1576
1577 switch (b) {
1578 case '0': Gn[Dist] = IdSpecial; break;
1579 case '<': Gn[Dist] = IdASCII; break;
1580 case '>': Gn[Dist] = IdASCII; break;
1581 case 'A': Gn[Dist] = IdASCII; break;
1582 case 'B': Gn[Dist] = IdASCII; break;
1583 case 'H': Gn[Dist] = IdASCII; break;
1584 case 'I':
1585 if (ts.Language==IdJapanese)
1586 Gn[Dist] = IdKatakana;
1587 break;
1588 case 'J': Gn[Dist] = IdASCII; break;
1589 }
1590
1591 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) && (Dist==0))
1592 Glr[0] = 0; /* G0->GL */
1593 }
1594
1595 void PrnParseEscape(BYTE b) // printer mode
1596 {
1597 int i;
1598
1599 ParseMode = ModeFirst;
1600 switch (ICount) {
1601 /* no intermediate char */
1602 case 0:
1603 switch (b) {
1604 case '[': /* CSI */
1605 ClearParams();
1606 FirstPrm = TRUE;
1607 WriteToPrnFile(ESC,FALSE);
1608 WriteToPrnFile('[',FALSE);
1609 ParseMode = ModeCSI;
1610 return;
1611 } /* end of case Icount=0 */
1612 break;
1613 /* one intermediate char */
1614 case 1:
1615 switch (IntChar[1]) {
1616 case '$':
1617 if (! DirectPrn) {
1618 ESCDBCSSelect(b);
1619 return;
1620 }
1621 break;
1622 case '(':
1623 case ')':
1624 case '*':
1625 case '+':
1626 if (! DirectPrn) {
1627 ESCSBCSSelect(b);
1628 return;
1629 }
1630 break;
1631 }
1632 break;
1633 /* two intermediate char */
1634 case 2:
1635 if ((! DirectPrn) &&
1636 (IntChar[1]=='$') &&
1637 ('('<=IntChar[2]) &&
1638 (IntChar[2]<='+'))
1639 {
1640 ESCDBCSSelect(b);
1641 return;
1642 }
1643 break;
1644 }
1645 // send the uninterpreted sequence to printer
1646 WriteToPrnFile(ESC,FALSE);
1647 for (i=1; i<=ICount; i++)
1648 WriteToPrnFile(IntChar[i],FALSE);
1649 WriteToPrnFile(b,TRUE);
1650 }
1651
1652 void ParseEscape(BYTE b) /* b is the final char */
1653 {
1654 if (PrinterMode) { // printer mode
1655 PrnParseEscape(b);
1656 return;
1657 }
1658
1659 switch (ICount) {
1660 case 0: /* no intermediate char */
1661 switch (b) {
1662 case '6': // DECBI
1663 if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1664 CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1665 if (CursorX == CursorLeftM)
1666 BuffScrollRight(1);
1667 else
1668 MoveCursor(CursorX-1, CursorY);
1669 }
1670 break;
1671 case '7': SaveCursor(); break;
1672 case '8': RestoreCursor(); break;
1673 case '9': // DECFI
1674 if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1675 CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1676 if (CursorX == CursorRightM)
1677 BuffScrollLeft(1);
1678 else
1679 MoveCursor(CursorX+1, CursorY);
1680 }
1681 break;
1682 case '=': AppliKeyMode = TRUE; break;
1683 case '>': AppliKeyMode = FALSE; break;
1684 case 'D': /* IND */
1685 LineFeed(0,TRUE);
1686 break;
1687 case 'E': /* NEL */
1688 MoveCursor(0,CursorY);
1689 LineFeed(0,TRUE);
1690 break;
1691 case 'H': /* HTS */
1692 if (ts.TabStopFlag & TABF_HTS7)
1693 SetTabStop();
1694 break;
1695 case 'M': /* RI */
1696 CursorUpWithScroll();
1697 break;
1698 case 'N': /* SS2 */
1699 if (ts.ISO2022Flag & ISO2022_SS2) {
1700 GLtmp = 2;
1701 SSflag = TRUE;
1702 }
1703 break;
1704 case 'O': /* SS3 */
1705 if (ts.ISO2022Flag & ISO2022_SS3) {
1706 GLtmp = 3;
1707 SSflag = TRUE;
1708 }
1709 break;
1710 case 'P': /* DCS */
1711 ClearParams();
1712 ESCFlag = FALSE;
1713 ParseMode = ModeDCS;
1714 return;
1715 case 'X': /* SOS */
1716 case '^': /* APC */
1717 case '_': /* PM */
1718 ESCFlag = FALSE;
1719 ParseMode = ModeIgnore;
1720 return;
1721 case 'Z': /* DECID */
1722 AnswerTerminalType();
1723 break;
1724 case '[': /* CSI */
1725 ClearParams();
1726 FirstPrm = TRUE;
1727 ParseMode = ModeCSI;
1728 return;
1729 case '\\': break; /* ST */
1730 case ']': /* XTERM sequence (OSC) */
1731 ClearParams();
1732 ParseMode = ModeXS;
1733 return;
1734 case 'c': /* Hardware reset */
1735 HideStatusLine();
1736 ResetTerminal();
1737 ClearUserKey();
1738 ClearBuffer();
1739 if (ts.PortType==IdSerial) // reset serial port
1740 CommResetSerial(&ts, &cv, TRUE);
1741 break;
1742 case 'g': /* Visual Bell (screen original?) */
1743 RingBell(IdBeepVisual);
1744 break;
1745 case 'n': /* LS2 */
1746 if (ts.ISO2022Flag & ISO2022_LS2) {
1747 Glr[0] = 2;
1748 }
1749 break;
1750 case 'o': /* LS3 */
1751 if (ts.ISO2022Flag & ISO2022_LS3) {
1752 Glr[0] = 3;
1753 }
1754 break;
1755 case '|': /* LS3R */
1756 if (ts.ISO2022Flag & ISO2022_LS3R) {
1757 Glr[1] = 3;
1758 }
1759 break;
1760 case '}': /* LS2R */
1761 if (ts.ISO2022Flag & ISO2022_LS2R) {
1762 Glr[1] = 2;
1763 }
1764 break;
1765 case '~': /* LS1R */
1766 if (ts.ISO2022Flag & ISO2022_LS1R) {
1767 Glr[1] = 1;
1768 }
1769 break;
1770 }
1771 break;
1772 /* end of case Icount=0 */
1773
1774 case 1: /* one intermediate char */
1775 switch (IntChar[1]) {
1776 case ' ': ESCSpace(b); break;
1777 case '#': ESCSharp(b); break;
1778 case '$': ESCDBCSSelect(b); break;
1779 case '%': break;
1780 case '(':
1781 case ')':
1782 case '*':
1783 case '+':
1784 ESCSBCSSelect(b);
1785 break;
1786 }
1787 break;
1788
1789 case 2: /* two intermediate char */
1790 if ((IntChar[1]=='$') && ('('<=IntChar[2]) && (IntChar[2]<='+'))
1791 ESCDBCSSelect(b);
1792 else if ((IntChar[1]=='%') && (IntChar[2]=='!'))
1793 ESCSelectCode(b);
1794 break;
1795 }
1796 ParseMode = ModeFirst;
1797 }
1798
1799 void EscapeSequence(BYTE b)
1800 {
1801 if (b<=US)
1802 ParseControl(b);
1803 else if ((b>=0x20) && (b<=0x2F)) {
1804 // TODO: ICount �� IntCharMax ���B�������A������ IntChar ���u����������������?
1805 if (ICount<IntCharMax)
1806 ICount++;
1807 IntChar[ICount] = b;
1808 }
1809 else if ((b>=0x30) && (b<=0x7E))
1810 ParseEscape(b);
1811 else if ((b>=0x80) && (b<=0x9F))
1812 ParseControl(b);
1813 else if (b>=0xA0) {
1814 ParseMode=ModeFirst;
1815 ParseFirst(b);
1816 }
1817
1818 JustAfterESC = FALSE;
1819 }
1820
1821 #define CheckParamVal(p,m) \
1822 if ((p) == 0) { \
1823 (p) = 1; \
1824 } \
1825 else if ((p) > (m) || p < 0) { \
1826 (p) = (m); \
1827 }
1828
1829 #define CheckParamValMax(p,m) \
1830 if ((p) > (m) || p <= 0) { \
1831 (p) = (m); \
1832 }
1833
1834 #define RequiredParams(n) \
1835 if ((n) > 1) { \
1836 while (NParam < n) { \
1837 NParam++; \
1838 Param[NParam] = 0; \
1839 NSParam[NParam] = 0; \
1840 } \
1841 }
1842
1843 // ICH
1844 static void CSInsertCharacter(void)
1845 {
1846 // Insert space characters at cursor
1847 CheckParamVal(Param[1], NumOfColumns);
1848
1849 BuffUpdateScroll();
1850 BuffInsertSpace(Param[1]);
1851 }
1852
1853 void CSCursorUp(BOOL AffectMargin) // CUU / VPB
1854 {
1855 int topMargin, NewY;
1856
1857 CheckParamVal(Param[1], CursorY);
1858
1859 if (AffectMargin && CursorY >= CursorTop)
1860 topMargin = CursorTop;
1861 else
1862 topMargin = 0;
1863
1864 NewY = CursorY - Param[1];
1865 if (NewY < topMargin)
1866 NewY = topMargin;
1867
1868 MoveCursor(CursorX, NewY);
1869 }
1870
1871 void CSCursorUp1() // CPL
1872 {
1873 MoveCursor(CursorLeftM, CursorY);
1874 CSCursorUp(TRUE);
1875 }
1876
1877 void CSCursorDown(BOOL AffectMargin) // CUD / VPR
1878 {
1879 int bottomMargin, NewY;
1880
1881 if (AffectMargin && CursorY <= CursorBottom)
1882 bottomMargin = CursorBottom;
1883 else
1884 bottomMargin = NumOfLines-StatusLine-1;
1885
1886 CheckParamVal(Param[1], bottomMargin);
1887
1888 NewY = CursorY + Param[1];
1889 if (NewY > bottomMargin)
1890 NewY = bottomMargin;
1891
1892 MoveCursor(CursorX, NewY);
1893 }
1894
1895 void CSCursorDown1() // CNL
1896 {
1897 MoveCursor(CursorLeftM, CursorY);
1898 CSCursorDown(TRUE);
1899 }
1900
1901 void CSScreenErase()
1902 {
1903 BuffUpdateScroll();
1904 switch (Param[1]) {
1905 case 0:
1906 // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1907 // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1908 // �����������������B(2005.5.29 yutaka)
1909 // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1910 if (ts.ScrollWindowClearScreen &&
1911 (CursorX == 0 && CursorY == 0)) {
1912 // Erase screen (scroll out)
1913 BuffClearScreen();
1914 UpdateWindow(HVTWin);
1915
1916 } else {
1917 // Erase characters from cursor to the end of screen
1918 BuffEraseCurToEnd();
1919 }
1920 break;
1921
1922 case 1:
1923 // Erase characters from home to cursor
1924 BuffEraseHomeToCur();
1925 break;
1926
1927 case 2:
1928 // Erase screen (scroll out)
1929 BuffClearScreen();
1930 UpdateWindow(HVTWin);
1931 if (ClearThenHome && !isCursorOnStatusLine) {
1932 if (RelativeOrgMode) {
1933 MoveCursor(0, 0);
1934 }
1935 else {
1936 MoveCursor(CursorLeftM, CursorTop);
1937 }
1938 }
1939 break;
1940
1941 case 3:
1942 if (ts.TermFlag & TF_REMOTECLEARSBUFF) {
1943 ClearBuffer();
1944 }
1945 break;
1946 }
1947 }
1948
1949 void CSQSelScreenErase()
1950 {
1951 BuffUpdateScroll();
1952 switch (Param[1]) {
1953 case 0:
1954 // Erase characters from cursor to end
1955 BuffSelectedEraseCurToEnd();
1956 break;
1957
1958 case 1:
1959 // Erase characters from home to cursor
1960 BuffSelectedEraseHomeToCur();
1961 break;
1962
1963 case 2:
1964 // Erase entire screen
1965 BuffSelectedEraseScreen();
1966 break;
1967
1968 case 3:
1969 if (ts.TermFlag & TF_REMOTECLEARSBUFF) {
1970 ClearBuffer();
1971 }
1972 break;
1973 }
1974 }
1975
1976 void CSInsertLine()
1977 {
1978 // Insert lines at current position
1979 int Count, YEnd;
1980
1981 if (CursorY < CursorTop || CursorY > CursorBottom) {
1982 return;
1983 }
1984
1985 CheckParamVal(Param[1], NumOfLines);
1986
1987 Count = Param[1];
1988
1989 YEnd = CursorBottom;
1990 if (CursorY > YEnd)
1991 YEnd = NumOfLines-1-StatusLine;
1992
1993 if (Count > YEnd+1 - CursorY)
1994 Count = YEnd+1 - CursorY;
1995
1996 BuffInsertLines(Count,YEnd);
1997 }
1998
1999 void CSLineErase()
2000 {
2001 BuffUpdateScroll();
2002 switch (Param[1]) {
2003 case 0: /* erase char from cursor to end of line */
2004 BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
2005 break;
2006
2007 case 1: /* erase char from start of line to cursor */
2008 BuffEraseCharsInLine(0,CursorX+1);
2009 break;
2010
2011 case 2: /* erase entire line */
2012 BuffEraseCharsInLine(0,NumOfColumns);
2013 break;
2014 }
2015 }
2016
2017 static void CSQSelLineErase(void)
2018 {
2019 BuffUpdateScroll();
2020 switch (Param[1]) {
2021 case 0: /* erase char from cursor to end of line */
2022 BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
2023 break;
2024
2025 case 1: /* erase char from start of line to cursor */
2026 BuffSelectedEraseCharsInLine(0,CursorX+1);
2027 break;
2028
2029 case 2: /* erase entire line */
2030 BuffSelectedEraseCharsInLine(0,NumOfColumns);
2031 break;
2032 }
2033 }
2034
2035 void CSDeleteNLines()
2036 // Delete lines from current line
2037 {
2038 int Count, YEnd;
2039
2040 if (CursorY < CursorTop || CursorY > CursorBottom) {
2041 return;
2042 }
2043
2044 CheckParamVal(Param[1], NumOfLines);
2045 Count = Param[1];
2046
2047 YEnd = CursorBottom;
2048 if (CursorY > YEnd)
2049 YEnd = NumOfLines-1-StatusLine;
2050
2051 if (Count > YEnd+1-CursorY)
2052 Count = YEnd+1-CursorY;
2053
2054 BuffDeleteLines(Count,YEnd);
2055 }
2056
2057 // DCH
2058 static void CSDeleteCharacter(void)
2059 {
2060 // Delete characters in current line from cursor
2061 CheckParamVal(Param[1], NumOfColumns);
2062
2063 BuffUpdateScroll();
2064 BuffDeleteChars(Param[1]);
2065 }
2066
2067 // ECH
2068 static void CSEraseCharacter(void)
2069 {
2070 CheckParamVal(Param[1], NumOfColumns);
2071
2072 BuffUpdateScroll();
2073 BuffEraseChars(Param[1]);
2074 }
2075
2076 void CSRepeatCharacter()
2077 {
2078 CheckParamVal(Param[1], NumOfColumns * NumOfLines);
2079
2080 BuffUpdateScroll();
2081 RepeatChar(LastPutCharacter, Param[1]);
2082 }
2083
2084 void CSScrollUp()
2085 {
2086 // TODO: �X�N���[���������l���[���s�����������������v����
2087 CheckParamVal(Param[1], INT_MAX);
2088
2089 BuffUpdateScroll();
2090 BuffRegionScrollUpNLines(Param[1]);
2091 }
2092
2093 void CSScrollDown()
2094 {
2095 CheckParamVal(Param[1], NumOfLines);
2096
2097 BuffUpdateScroll();
2098 BuffRegionScrollDownNLines(Param[1]);
2099 }
2100
2101 void CSForwardTab()
2102 {
2103 CheckParamVal(Param[1], NumOfColumns);
2104 CursorForwardTab(Param[1], AutoWrapMode);
2105 }
2106
2107 void CSBackwardTab()
2108 {
2109 CheckParamVal(Param[1], NumOfColumns);
2110 CursorBackwardTab(Param[1]);
2111 }
2112
2113 void CSMoveToColumnN() // CHA / HPA
2114 {
2115 CheckParamVal(Param[1], NumOfColumns);
2116
2117 Param[1]--;
2118
2119 if (RelativeOrgMode) {
2120 if (CursorLeftM + Param[1] > CursorRightM )
2121 MoveCursor(CursorRightM, CursorY);
2122 else
2123 MoveCursor(CursorLeftM + Param[1], CursorY);
2124 }
2125 else {
2126 MoveCursor(Param[1], CursorY);
2127 }
2128 }
2129
2130 void CSCursorRight(BOOL AffectMargin) // CUF / HPR
2131 {
2132 int NewX, rightMargin;
2133
2134 CheckParamVal(Param[1], NumOfColumns);
2135
2136 if (AffectMargin && CursorX <= CursorRightM) {
2137 rightMargin = CursorRightM;
2138 }
2139 else {
2140 rightMargin = NumOfColumns-1;
2141 }
2142
2143 NewX = CursorX + Param[1];
2144 if (NewX > rightMargin)
2145 NewX = rightMargin;
2146
2147 MoveCursor(NewX, CursorY);
2148 }
2149
2150 void CSCursorLeft(BOOL AffectMargin) // CUB / HPB
2151 {
2152 int NewX, leftMargin;
2153
2154 CheckParamVal(Param[1], NumOfColumns);
2155
2156 if (AffectMargin && CursorX >= CursorLeftM) {
2157 leftMargin = CursorLeftM;
2158 }
2159 else {
2160 leftMargin = 0;
2161 }
2162
2163 NewX = CursorX - Param[1];
2164 if (NewX < leftMargin) {
2165 NewX = leftMargin;
2166 }
2167
2168 MoveCursor(NewX, CursorY);
2169 }
2170
2171 void CSMoveToLineN() // VPA
2172 {
2173 CheckParamVal(Param[1], NumOfLines-StatusLine);
2174
2175 if (RelativeOrgMode) {
2176 if (CursorTop+Param[1]-1 > CursorBottom)
2177 MoveCursor(CursorX,CursorBottom);
2178 else
2179 MoveCursor(CursorX,CursorTop+Param[1]-1);
2180 }
2181 else {
2182 if (Param[1] > NumOfLines-StatusLine)
2183 MoveCursor(CursorX,NumOfLines-1-StatusLine);
2184 else
2185 MoveCursor(CursorX,Param[1]-1);
2186 }
2187 Fallbacked = FALSE;
2188 }
2189
2190 void CSMoveToXY() // CUP / HVP
2191 {
2192 int NewX, NewY;
2193
2194 RequiredParams(2);
2195 CheckParamVal(Param[1], NumOfLines-StatusLine);
2196 CheckParamVal(Param[2], NumOfColumns);
2197
2198 NewY = Param[1] - 1;
2199 NewX = Param[2] - 1;
2200
2201 if (isCursorOnStatusLine)
2202 NewY = CursorY;
2203 else if (RelativeOrgMode) {
2204 NewX += CursorLeftM;
2205 if (NewX > CursorRightM)
2206 NewX = CursorRightM;
2207
2208 NewY += CursorTop;
2209 if (NewY > CursorBottom)
2210 NewY = CursorBottom;
2211 }
2212 else {
2213 if (NewY > NumOfLines-1-StatusLine)
2214 NewY = NumOfLines-1-StatusLine;
2215 }
2216
2217 MoveCursor(NewX, NewY);
2218 Fallbacked = FALSE;
2219 }
2220
2221 void CSDeleteTabStop()
2222 {
2223 ClearTabStop(Param[1]);
2224 }
2225
2226 void CS_h_Mode() // SM
2227 {
2228 switch (Param[1]) {
2229 case 2: // KAM
2230 KeybEnabled = FALSE; break;
2231 case 4: // IRM
2232 InsertMode = TRUE; break;
2233 case 12: // SRM
2234 ts.LocalEcho = 0;
2235 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
2236 TelChangeEcho();
2237 break;
2238 case 20: // LF/NL
2239 LFMode = TRUE;
2240 ts.CRSend = IdCRLF;
2241 cv.CRSend = IdCRLF;
2242 break;
2243 case 33: // WYSTCURM
2244 if (ts.WindowFlag & WF_CURSORCHANGE) {
2245 ts.NonblinkingCursor = TRUE;
2246 ChangeCaret();
2247 }
2248 break;
2249 case 34: // WYULCURM
2250 if (ts.WindowFlag & WF_CURSORCHANGE) {
2251 ts.CursorShape = IdHCur;
2252 ChangeCaret();
2253 }
2254 break;
2255 }
2256 }
2257
2258 void CS_i_Mode() // MC
2259 {
2260 switch (Param[1]) {
2261 /* print screen */
2262 // PrintEX -- TRUE: print screen
2263 // FALSE: scroll region
2264 case 0:
2265 if (ts.TermFlag&TF_PRINTERCTRL) {
2266 BuffPrint(! PrintEX);
2267 }
2268 break;
2269 /* printer controller mode off */
2270 case 4: break; /* See PrnParseCS() */
2271 /* printer controller mode on */
2272 case 5:
2273 if (ts.TermFlag&TF_PRINTERCTRL) {
2274 if (! AutoPrintMode)
2275 OpenPrnFile();
2276 DirectPrn = (ts.PrnDev[0]!=0);
2277 PrinterMode = TRUE;
2278 }
2279 break;
2280 }
2281 }
2282
2283 void CS_l_Mode() // RM
2284 {
2285 switch (Param[1]) {
2286 case 2: // KAM
2287 KeybEnabled = TRUE; break;
2288 case 4: // IRM
2289 InsertMode = FALSE; break;
2290 case 12: // SRM
2291 ts.LocalEcho = 1;
2292 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
2293 TelChangeEcho();
2294 break;
2295 case 20: // LF/NL
2296 LFMode = FALSE;
2297 ts.CRSend = IdCR;
2298 cv.CRSend = IdCR;
2299 break;
2300 case 33: // WYSTCURM
2301 if (ts.WindowFlag & WF_CURSORCHANGE) {
2302 ts.NonblinkingCursor = FALSE;
2303 ChangeCaret();
2304 }
2305 break;
2306 case 34: // WYULCURM
2307 if (ts.WindowFlag & WF_CURSORCHANGE) {
2308 ts.CursorShape = IdBlkCur;
2309 ChangeCaret();
2310 }
2311 break;
2312 }
2313 }
2314
2315 void CS_n_Mode() // DSR
2316 {
2317 char Report[16];
2318 int X, Y, len;
2319
2320 switch (Param[1]) {
2321 case 5:
2322 /* Device Status Report -> Ready */
2323 SendCSIstr("0n", 0);
2324 break;
2325 case 6:
2326 /* Cursor Position Report */
2327 if (isCursorOnStatusLine) {
2328 X = CursorX + 1;
2329 Y = 1;
2330 }
2331 else if (RelativeOrgMode) {
2332 X = CursorX - CursorLeftM + 1;
2333 Y = CursorY - CursorTop + 1;
2334 }
2335 else {
2336 X = CursorX + 1;
2337 Y = CursorY+1;
2338 }
2339 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, X);
2340 SendCSIstr(Report, len);
2341 break;
2342 }
2343 }
2344
2345 void ParseSGRParams(PCharAttr attr, PCharAttr mask, int start)
2346 {
2347 int i, j, P, r, g, b, color;
2348 TCharAttr dummy;
2349
2350 if (mask == NULL) {
2351 mask = &dummy;
2352 }
2353
2354 for (i=start ; i<=NParam ; i++) {
2355 P = Param[i];
2356 switch (P) {
2357 case 0: /* Clear all */
2358 attr->Attr = DefCharAttr.Attr;
2359 attr->Attr2 = DefCharAttr.Attr2 | (attr->Attr2&Attr2Protect);
2360 #if UNICODE_INTERNAL_BUFF
2361 attr->AttrEx = attr->Attr;
2362 #endif
2363 attr->Fore = DefCharAttr.Fore;
2364 attr->Back = DefCharAttr.Back;
2365 mask->Attr = AttrSgrMask;
2366 mask->Attr2 = Attr2ColorMask;
2367 break;
2368
2369 case 1: /* Bold */
2370 attr->Attr |= AttrBold;
2371 mask->Attr |= AttrBold;
2372 break;
2373
2374 case 4: /* Under line */
2375 attr->Attr |= AttrUnder;
2376 mask->Attr |= AttrUnder;
2377 break;
2378
2379 case 5: /* Blink */
2380 attr->Attr |= AttrBlink;
2381 mask->Attr |= AttrBlink;
2382 break;
2383
2384 case 7: /* Reverse */
2385 attr->Attr |= AttrReverse;
2386 mask->Attr |= AttrReverse;
2387 break;
2388
2389 case 22: /* Bold off */
2390 attr->Attr &= ~ AttrBold;
2391 mask->Attr |= AttrBold;
2392 break;
2393
2394 case 24: /* Under line off */
2395 attr->Attr &= ~ AttrUnder;
2396 mask->Attr |= AttrUnder;
2397 break;
2398
2399 case 25: /* Blink off */
2400 attr->Attr &= ~ AttrBlink;
2401 mask->Attr |= AttrBlink;
2402 break;
2403
2404 case 27: /* Reverse off */
2405 attr->Attr &= ~ AttrReverse;
2406 mask->Attr |= AttrReverse;
2407 break;
2408
2409 case 30:
2410 case 31:
2411 case 32:
2412 case 33:
2413 case 34:
2414 case 35:
2415 case 36:
2416 case 37: /* text color */
2417 attr->Attr2 |= Attr2Fore;
2418 mask->Attr2 |= Attr2Fore;
2419 attr->Fore = P - 30;
2420 break;
2421
2422 case 38: /* text color (256color mode) */
2423 if (ts.ColorFlag & CF_XTERM256) {
2424 /*
2425 * Change foreground color. accept following formats.
2426 *
2427 * 38 ; 2 ; r ; g ; b
2428 * 38 ; 2 : r : g : b
2429 * 38 : 2 : r : g : b
2430 * 38 ; 5 ; idx
2431 * 38 ; 5 : idx
2432 * 38 : 5 : idx
2433 *
2434 */
2435 color = -1;
2436 j = 0;
2437 if (NSParam[i] > 0) {
2438 P = SubParam[i][1];
2439 j++;
2440 }
2441 else if (i < NParam) {
2442 P = Param[i+1];
2443 if (P == 2 || P == 5) {
2444 i++;
2445 }
2446 }
2447 switch (P) {
2448 case 2:
2449 r = g = b = 0;
2450 if (NSParam[i] > 0) {
2451 if (j < NSParam[i]) {
2452 r = SubParam[i][++j];
2453 if (j < NSParam[i]) {
2454 g = SubParam[i][++j];
2455 }
2456 if (j < NSParam[i]) {
2457 b = SubParam[i][++j];
2458 }
2459 color = DispFindClosestColor(r, g, b);
2460 }
2461 }
2462 else if (i < NParam && NSParam[i+1] > 0) {
2463 r = Param[++i];
2464 g = SubParam[i][1];
2465 if (NSParam[i] > 1) {
2466 b = SubParam[i][2];
2467 }
2468 color = DispFindClosestColor(r, g, b);
2469 }
2470 else if (i+2 < NParam) {
2471 r = Param[++i];
2472 g = Param[++i];
2473 b = Param[++i];
2474 color = DispFindClosestColor(r, g, b);
2475 }
2476 break;
2477 case 5:
2478 if (NSParam[i] > 0) {
2479 if (j < NSParam[i]) {
2480 color = SubParam[i][++j];
2481 }
2482 }
2483 else if (i < NParam) {
2484 color = Param[++i];
2485 }
2486 break;
2487 }
2488 if (color >= 0 && color < 256) {
2489 attr->Attr2 |= Attr2Fore;
2490 mask->Attr2 |= Attr2Fore;
2491 attr->Fore = color;
2492 }
2493 }
2494 break;
2495
2496 case 39: /* Reset text color */
2497 attr->Attr2 &= ~ Attr2Fore;
2498 mask->Attr2 |= Attr2Fore;
2499 attr->Fore = AttrDefaultFG;
2500 break;
2501
2502 case 40:
2503 case 41:
2504 case 42:
2505 case 43:
2506 case 44:
2507 case 45:
2508 case 46:
2509 case 47: /* Back color */
2510 attr->Attr2 |= Attr2Back;
2511 mask->Attr2 |= Attr2Back;
2512 attr->Back = P - 40;
2513 break;
2514
2515 case 48: /* Back color (256color mode) */
2516 if (ts.ColorFlag & CF_XTERM256) {
2517 color = -1;
2518 j = 0;
2519 if (NSParam[i] > 0) {
2520 P = SubParam[i][1];
2521 j++;
2522 }
2523 else if (i < NParam) {
2524 P = Param[i+1];
2525 if (P == 2 || P == 5) {
2526 i++;
2527 }
2528 }
2529 switch (P) {
2530 case 2:
2531 r = g = b = 0;
2532 if (NSParam[i] > 0) {
2533 if (j < NSParam[i]) {
2534 r = SubParam[i][++j];
2535 if (j < NSParam[i]) {
2536 g = SubParam[i][++j];
2537 }
2538 if (j < NSParam[i]) {
2539 b = SubParam[i][++j];
2540 }
2541 color = DispFindClosestColor(r, g, b);
2542 }
2543 }
2544 else if (i < NParam && NSParam[i+1] > 0) {
2545 r = Param[++i];
2546 g = SubParam[i][1];
2547 if (NSParam[i] > 1) {
2548 b = SubParam[i][2];
2549 }
2550 color = DispFindClosestColor(r, g, b);
2551 }
2552 else if (i+2 < NParam) {
2553 r = Param[++i];
2554 g = Param[++i];
2555 b = Param[++i];
2556 color = DispFindClosestColor(r, g, b);
2557 }
2558 break;
2559 case 5:
2560 if (NSParam[i] > 0) {
2561 if (j < NSParam[i]) {
2562 color = SubParam[i][++j];
2563 }
2564 }
2565 else if (i < NParam) {
2566 color = Param[++i];
2567 }
2568 break;
2569 }
2570 if (color >= 0 && color < 256) {
2571 attr->Attr2 |= Attr2Back;
2572 mask->Attr2 |= Attr2Back;
2573 attr->Back = color;
2574 }
2575 }
2576 break;
2577
2578 case 49: /* Reset back color */
2579 attr->Attr2 &= ~ Attr2Back;
2580 mask->Attr2 |= Attr2Back;
2581 attr->Back = AttrDefaultBG;
2582 break;
2583
2584 case 90:
2585 case 91:
2586 case 92:
2587 case 93:
2588 case 94:
2589 case 95:
2590 case 96:
2591 case 97: /* aixterm style text color */
2592 if (ts.ColorFlag & CF_AIXTERM16) {
2593 attr->Attr2 |= Attr2Fore;
2594 mask->Attr2 |= Attr2Fore;
2595 attr->Fore = P - 90 + 8;
2596 }
2597 break;
2598
2599 case 100:
2600 if (! (ts.ColorFlag & CF_AIXTERM16)) {
2601 /* Reset text and back color */
2602 attr->Attr2 &= ~ (Attr2Fore | Attr2Back);
2603 mask->Attr2 |= Attr2ColorMask;
2604 attr->Fore = AttrDefaultFG;
2605 attr->Back = AttrDefaultBG;
2606 break;
2607 }
2608 /* fall through to aixterm style back color */
2609
2610 case 101:
2611 case 102:
2612 case 103:
2613 case 104:
2614 case 105:
2615 case 106:
2616 case 107: /* aixterm style back color */
2617 if (ts.ColorFlag & CF_AIXTERM16) {
2618 attr->Attr2 |= Attr2Back;
2619 mask->Attr2 |= Attr2Back;
2620 attr->Back = P - 100 + 8;
2621 }
2622 break;
2623 }
2624 }
2625 }
2626
2627 void CSSetAttr() // SGR
2628 {
2629 UpdateStr();
2630 ParseSGRParams(&CharAttr, NULL, 1);
2631 BuffSetCurCharAttr(CharAttr);
2632 }
2633
2634 void CSSetScrollRegion() // DECSTBM
2635 {
2636 if (isCursorOnStatusLine) {
2637 MoveCursor(0,CursorY);
2638 return;
2639 }
2640
2641 RequiredParams(2);
2642 CheckParamVal(Param[1], NumOfLines-StatusLine);
2643 CheckParamValMax(Param[2], NumOfLines-StatusLine);
2644
2645 if (Param[1] >= Param[2])
2646 return;
2647
2648 CursorTop = Param[1] - 1;
2649 CursorBottom = Param[2] - 1;
2650
2651 if (RelativeOrgMode)
2652 // TODO: ���}�[�W���������������B�v���@�m�F�B
2653 MoveCursor(0, CursorTop);
2654 else
2655 MoveCursor(0, 0);
2656 }
2657
2658 void CSSetLRScrollRegion() // DECSLRM
2659 {
2660 // TODO: �X�e�[�^�X���C�������������m�F�B
2661 // if (isCursorOnStatusLine) {
2662 // MoveCursor(0,CursorY);
2663 // return;
2664 // }
2665
2666 RequiredParams(2);
2667 CheckParamVal(Param[1], NumOfColumns);
2668 CheckParamValMax(Param[2], NumOfColumns);
2669
2670 if (Param[1] >= Param[2])
2671 return;
2672
2673 CursorLeftM = Param[1] - 1;
2674 CursorRightM = Param[2] - 1;
2675
2676 if (RelativeOrgMode)
2677 MoveCursor(CursorLeftM, CursorTop);
2678 else
2679 MoveCursor(0, 0);
2680 }
2681
2682 void CSSunSequence() /* Sun terminal private sequences */
2683 {
2684 int x, y, len;
2685 char Report[TitleBuffSize*2+10];
2686 PTStack t;
2687
2688 switch (Param[1]) {
2689 case 1: // De-iconify window
2690 if (ts.WindowFlag & WF_WINDOWCHANGE)
2691 DispShowWindow(WINDOW_RESTORE);
2692 break;
2693
2694 case 2: // Iconify window
2695 if (ts.WindowFlag & WF_WINDOWCHANGE)
2696 DispShowWindow(WINDOW_MINIMIZE);
2697 break;
2698
2699 case 3: // set window position
2700 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2701 RequiredParams(3);
2702 DispMoveWindow(Param[2], Param[3]);
2703 }
2704 break;
2705
2706 case 4: // set window size
2707 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2708 RequiredParams(3);
2709 DispResizeWin(Param[3], Param[2]);
2710 }
2711 break;
2712
2713 case 5: // Raise window
2714 if (ts.WindowFlag & WF_WINDOWCHANGE)
2715 DispShowWindow(WINDOW_RAISE);
2716 break;
2717
2718 case 6: // Lower window
2719 if (ts.WindowFlag & WF_WINDOWCHANGE)
2720 DispShowWindow(WINDOW_LOWER);
2721 break;
2722
2723 case 7: // Refresh window
2724 if (ts.WindowFlag & WF_WINDOWCHANGE)
2725 DispShowWindow(WINDOW_REFRESH);
2726 break;
2727
2728 case 8: /* set terminal size */
2729 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2730 RequiredParams(3);
2731 if (Param[2] <= 1) Param[2] = 24;
2732 if (Param[3] <= 1) Param[3] = 80;
2733 ChangeTerminalSize(Param[3], Param[2]);
2734 }
2735 break;
2736
2737 case 9: // Maximize/Restore window
2738 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2739 RequiredParams(2);
2740 if (Param[2] == 0) {
2741 DispShowWindow(WINDOW_RESTORE);
2742 }
2743 else if (Param[2] == 1) {
2744 DispShowWindow(WINDOW_MAXIMIZE);
2745 }
2746 }
2747 break;
2748
2749 case 10: // Full-screen
2750 /*
2751 * �{�������� PuTTY ���������t���X�N���[�����[�h�������������������A
2752 * �������������������������������p����
2753 */
2754 if (ts.WindowFlag & WF_WINDOWCHANGE) {
2755 RequiredParams(2);
2756 switch (Param[2]) {
2757 case 0:
2758 DispShowWindow(WINDOW_RESTORE);
2759 break;
2760 case 1:
2761 DispShowWindow(WINDOW_MAXIMIZE);
2762 break;
2763 case 2:
2764 DispShowWindow(WINDOW_TOGGLE_MAXIMIZE);
2765 break;
2766 }
2767 }
2768 break;
2769
2770 case 11: // Report window state
2771 if (ts.WindowFlag & WF_WINDOWREPORT) {
2772 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
2773 SendCSIstr(Report, len);
2774 }
2775 break;
2776
2777 case 13: // Report window position
2778 if (ts.WindowFlag & WF_WINDOWREPORT) {
2779 RequiredParams(2);
2780 switch (Param[2]) {
2781 case 0:
2782 case 1:
2783 DispGetWindowPos(&x, &y, FALSE);
2784 break;
2785 case 2:
2786 DispGetWindowPos(&x, &y, TRUE);
2787 break;
2788 default:
2789 return;
2790 }
2791 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%u;%ut", CLocale, (unsigned int)x, (unsigned int)y);
2792 SendCSIstr(Report, len);
2793 }
2794 break;
2795
2796 case 14: /* get window size */
2797 if (ts.WindowFlag & WF_WINDOWREPORT) {
2798 RequiredParams(2);
2799 switch (Param[2]) {
2800 case 0:
2801 case 1:
2802 DispGetWindowSize(&x, &y, TRUE);
2803 break;
2804 case 2:
2805 DispGetWindowSize(&x, &y, FALSE);
2806 break;
2807 default:
2808 return;
2809 }
2810
2811 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "4;%d;%dt", CLocale, y, x);
2812 SendCSIstr(Report, len);
2813 }
2814 break;
2815
2816 case 15: // Report display size (pixel)
2817 if (ts.WindowFlag & WF_WINDOWREPORT) {
2818 DispGetRootWinSize(&x, &y, TRUE);
2819 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "5;%d;%dt", CLocale, y, x);
2820 SendCSIstr(Report, len);
2821 }
2822 break;
2823
2824 case 16: // Report character cell size (pixel)
2825 if (ts.WindowFlag & WF_WINDOWREPORT) {
2826 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "6;%d;%dt", CLocale, FontHeight, FontWidth);
2827 SendCSIstr(Report, len);
2828 }
2829 break;
2830
2831 case 18: /* get terminal size */
2832 if (ts.WindowFlag & WF_WINDOWREPORT) {
2833 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%ut", CLocale,
2834 NumOfLines-StatusLine, NumOfColumns);
2835 SendCSIstr(Report, len);
2836 }
2837 break;
2838
2839 case 19: // Report display size (character)
2840 if (ts.WindowFlag & WF_WINDOWREPORT) {
2841 DispGetRootWinSize(&x, &y, FALSE);
2842 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
2843 SendCSIstr(Report, len);
2844 }
2845 break;
2846
2847 case 20: // Report icon label
2848 switch (ts.WindowFlag & WF_TITLEREPORT) {
2849 case IdTitleReportIgnore:
2850 // nothing to do
2851 break;
2852
2853 case IdTitleReportAccept:
2854 switch (ts.AcceptTitleChangeRequest) {
2855 case IdTitleChangeRequestOff:
2856 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2857 break;
2858
2859 case IdTitleChangeRequestAhead:
2860 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, cv.TitleRemote, ts.Title);
2861 break;
2862
2863 case IdTitleChangeRequestLast:
2864 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, ts.Title, cv.TitleRemote);
2865 break;
2866
2867 default:
2868 if (cv.TitleRemote[0] == 0) {
2869 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2870 }
2871 else {
2872 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, cv.TitleRemote);
2873 }
2874 }
2875 SendOSCstr(Report, len, ST);
2876 break;
2877
2878 default: // IdTitleReportEmpty:
2879 SendOSCstr("L", 0, ST);
2880 break;
2881 }
2882 break;
2883
2884 case 21: // Report window title
2885 switch (ts.WindowFlag & WF_TITLEREPORT) {
2886 case IdTitleReportIgnore:
2887 // nothing to do
2888 break;
2889
2890 case IdTitleReportAccept:
2891 switch (ts.AcceptTitleChangeRequest) {
2892 case IdTitleChangeRequestOff:
2893 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2894 break;
2895
2896 case IdTitleChangeRequestAhead:
2897 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, cv.TitleRemote, ts.Title);
2898 break;
2899
2900 case IdTitleChangeRequestLast:
2901 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s %s", CLocale, ts.Title, cv.TitleRemote);
2902 break;
2903
2904 default:
2905 if (cv.TitleRemote[0] == 0) {
2906 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, ts.Title);
2907 }
2908 else {
2909 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "l%s", CLocale, cv.TitleRemote);
2910 }
2911 }
2912 SendOSCstr(Report, len, ST);
2913 break;
2914
2915 default: // IdTitleReportEmpty:
2916 SendOSCstr("l", 0, ST);
2917 break;
2918 }
2919 break;
2920
2921 case 22: // Push Title
2922 RequiredParams(2);
2923 switch (Param[2]) {
2924 case 0:
2925 case 1:
2926 case 2:
2927 if (ts.AcceptTitleChangeRequest && (t=malloc(sizeof(TStack))) != NULL) {
2928 if ((t->title = _strdup(cv.TitleRemote)) != NULL) {
2929 t->next = TitleStack;
2930 TitleStack = t;
2931 }
2932 else {
2933 free(t);
2934 }
2935 }
2936 break;
2937 }
2938 break;
2939
2940 case 23: // Pop Title
2941 RequiredParams(2);
2942 switch (Param[2]) {
2943 case 0:
2944 case 1:
2945 case 2:
2946 if (ts.AcceptTitleChangeRequest && TitleStack != NULL) {
2947 t = TitleStack;
2948 TitleStack = t->next;
2949 strncpy_s(cv.TitleRemote, sizeof(cv.TitleRemote), t->title, _TRUNCATE);
2950 ChangeTitle();
2951 free(t->title);
2952 free(t);
2953 }
2954 break;
2955 }
2956 }
2957 }
2958
2959 void CSLT(BYTE b)
2960 {
2961 switch (b) {
2962 case 'r':
2963 if (CanUseIME()) {
2964 SetIMEOpenStatus(HVTWin, SavedIMEstatus);
2965 }
2966 break;
2967
2968 case 's':
2969 if (CanUseIME()) {
2970 SavedIMEstatus = GetIMEOpenStatus(HVTWin);
2971 }
2972 break;
2973
2974 case 't':
2975 if (CanUseIME()) {
2976 SetIMEOpenStatus(HVTWin, Param[1] == 1);
2977 }
2978 break;
2979 }
2980 }
2981
2982 void CSEQ(BYTE b)
2983 {
2984 char Report[16];
2985 int len;
2986
2987 switch (b) {
2988 case 'c': /* Tertiary terminal report (Tertiary DA) */
2989 if (Param[1] == 0) {
2990 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "!|%8s", CLocale, ts.TerminalUID);
2991 SendDCSstr(Report, len);
2992 }
2993 break;
2994 }
2995 }
2996
2997 void CSGT(BYTE b)
2998 {
2999 switch (b) {
3000 case 'c': /* second terminal report (Secondary DA) */
3001 if (Param[1] == 0) {
3002 SendCSIstr(">32;331;0c", 0); /* VT382(>32) + xterm rev 331 */
3003 }
3004 break;
3005
3006 case 'J': // IO-8256 terminal
3007 if (Param[1]==3) {
3008 RequiredParams(5);
3009 CheckParamVal(Param[2], NumOfLines-StatusLine);
3010 CheckParamVal(Param[3], NumOfColumns);
3011 CheckParamValMax(Param[4], NumOfLines-StatusLine);
3012 CheckParamValMax(Param[5], NumOfColumns);
3013
3014 if (Param[2] > Param[4] || Param[3] > Param[5]) {
3015 return;
3016 }
3017
3018 BuffEraseBox(Param[3]-1, Param[2]-1, Param[5]-1, Param[4]-1);
3019 }
3020 break;
3021
3022 case 'K': // IO-8256 terminal
3023 switch (Param[1]) {
3024 case 3:
3025 RequiredParams(3);
3026 CheckParamVal(Param[2], NumOfColumns);
3027 CheckParamVal(Param[3], NumOfColumns);
3028
3029 if (Param[2] > Param[3]) {
3030 return;
3031 }
3032
3033 BuffEraseCharsInLine(Param[2]-1, Param[3]-Param[2]+1);
3034 break;
3035
3036 case 5:
3037 RequiredParams(3);
3038 switch (Param[2]) {
3039 case 3:
3040 case 4:
3041 case 5:
3042 case 6: // Draw Line
3043 BuffDrawLine(CharAttr, Param[2], Param[3]);
3044 break;
3045
3046 case 12: // Text color
3047 if ((Param[3]>=0) && (Param[3]<=7)) {
3048 switch (Param[3]) {
3049 case 3: CharAttr.Fore = IdBlue; break;
3050 case 4: CharAttr.Fore = IdCyan; break;
3051 case 5: CharAttr.Fore = IdYellow; break;
3052 case 6: CharAttr.Fore = IdMagenta; break;
3053 default: CharAttr.Fore = Param[3]; break;
3054 }
3055 CharAttr.Attr2 |= Attr2Fore;
3056 BuffSetCurCharAttr(CharAttr);
3057 }
3058 break;
3059 }
3060 break;
3061 }
3062 break;
3063 }
3064 }
3065
3066 void CSQExchangeColor() // DECSCNM / Visual Bell
3067 {
3068 COLORREF ColorRef;
3069
3070 BuffUpdateScroll();
3071
3072 if (ts.ColorFlag & CF_REVERSECOLOR) {
3073 ColorRef = ts.VTColor[0];
3074 ts.VTColor[0] = ts.VTReverseColor[0];
3075 ts.VTReverseColor[0] = ColorRef;
3076 ColorRef = ts.VTColor[1];
3077 ts.VTColor[1] = ts.VTReverseColor[1];
3078 ts.VTReverseColor[1] = ColorRef;
3079 }
3080 else {
3081 ColorRef = ts.VTColor[0];
3082 ts.VTColor[0] = ts.VTColor[1];
3083 ts.VTColor[1] = ColorRef;
3084 }
3085
3086 ColorRef = ts.VTBoldColor[0];
3087 ts.VTBoldColor[0] = ts.VTBoldColor[1];
3088 ts.VTBoldColor[1] = ColorRef;
3089
3090 ColorRef = ts.VTBlinkColor[0];
3091 ts.VTBlinkColor[0] = ts.VTBlinkColor[1];
3092 ts.VTBlinkColor[1] = ColorRef;
3093
3094 ColorRef = ts.URLColor[0];
3095 ts.URLColor[0] = ts.URLColor[1];
3096 ts.URLColor[1] = ColorRef;
3097
3098 ts.ColorFlag ^= CF_REVERSEVIDEO;
3099
3100 #ifdef ALPHABLEND_TYPE2
3101 BGExchangeColor();
3102 #endif
3103 DispChangeBackground();
3104 UpdateWindow(HVTWin);
3105 }
3106
3107 void CSQChangeColumnMode(int width) // DECCOLM
3108 {
3109 ChangeTerminalSize(width, NumOfLines-StatusLine);
3110 LRMarginMode = FALSE;
3111
3112 // DECCOLM �����������N���A�����������d�l
3113 // ClearOnResize �� off �������������N���A�����B
3114 // ClearOnResize �� on ������ ChangeTerminalSize() ���������N���A�����������A
3115 // �]�v���X�N���[�����������������������N���A�������B
3116 if ((ts.TermFlag & TF_CLEARONRESIZE) == 0) {
3117 MoveCursor(0, 0);
3118 BuffClearScreen();
3119 UpdateWindow(HVTWin);
3120 }
3121 }
3122
3123 void CSQ_h_Mode() // DECSET
3124 {
3125 int i;
3126
3127 for (i = 1 ; i<=NParam ; i++) {
3128 switch (Param[i]) {
3129 case 1: AppliCursorMode = TRUE; break; // DECCKM
3130 case 3: CSQChangeColumnMode(132); break; // DECCOLM
3131 case 5: /* Reverse Video (DECSCNM) */
3132 if (!(ts.ColorFlag & CF_REVERSEVIDEO))
3133 CSQExchangeColor(); /* Exchange text/back color */
3134 break;
3135 case 6: // DECOM
3136 if (isCursorOnStatusLine)
3137 MoveCursor(0,CursorY);
3138 else {
3139 RelativeOrgMode = TRUE;
3140 MoveCursor(0,CursorTop);
3141 }
3142 break;
3143 case 7: AutoWrapMode = TRUE; break; // DECAWM
3144 case 8: AutoRepeatMode = TRUE; break; // DECARM
3145 case 9: /* X10 Mouse Tracking */
3146 if (ts.MouseEventTracking)
3147 MouseReportMode = IdMouseTrackX10;
3148 break;
3149 case 12: /* att610 cursor blinking */
3150 if (ts.WindowFlag & WF_CURSORCHANGE) {
3151 ts.NonblinkingCursor = FALSE;
3152 ChangeCaret();
3153 }
3154 break;
3155 case 19: PrintEX = TRUE; break; // DECPEX
3156 case 25: DispEnableCaret(TRUE); break; // cursor on (DECTCEM)
3157 case 38: // DECTEK
3158 if (ts.AutoWinSwitch>0)
3159 ChangeEmu = IdTEK; /* Enter TEK Mode */
3160 break;
3161 case 47: // Alternate Screen Buffer
3162 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
3163 BuffSaveScreen();
3164 AltScr = TRUE;
3165 }
3166 break;
3167 case 59:
3168 if (ts.Language==IdJapanese) {
3169 /* kanji terminal */
3170 Gn[0] = IdASCII;
3171 Gn[1] = IdKatakana;
3172 Gn[2] = IdKatakana;
3173 Gn[3] = IdKanji;
3174 Glr[0] = 0;
3175 if ((ts.KanjiCode==IdJIS) &&
3176 (ts.JIS7Katakana==0))
3177 Glr[1] = 2; // 8-bit katakana
3178 else
3179 Glr[1] = 3;
3180 }
3181 break;
3182 case 66: AppliKeyMode = TRUE; break; // DECNKM
3183 case 67: ts.BSKey = IdBS; break; // DECBKM
3184 case 69: LRMarginMode = TRUE; break; // DECLRMM (DECVSSM)
3185 case 1000: // Mouse Tracking
3186 if (ts.MouseEventTracking)
3187 MouseReportMode = IdMouseTrackVT200;
3188 break;
3189 case 1001: // Hilite Mouse Tracking
3190 if (ts.MouseEventTracking)
3191 MouseReportMode = IdMouseTrackVT200Hl;
3192 break;
3193 case 1002: // Button-Event Mouse Tracking
3194 if (ts.MouseEventTracking)
3195 MouseReportMode = IdMouseTrackBtnEvent;
3196 break;
3197 case 1003: // Any-Event Mouse Tracking
3198 if (ts.MouseEventTracking)
3199 MouseReportMode = IdMouseTrackAllEvent;
3200 break;
3201 case 1004: // Focus Report
3202 if (ts.MouseEventTracking)
3203 FocusReportMode = TRUE;
3204 break;
3205 case 1005: // Extended Mouse Tracking (UTF-8)
3206 if (ts.MouseEventTracking)
3207 MouseReportExtMode = IdMouseTrackExtUTF8;
3208 break;
3209 case 1006: // Extended Mouse Tracking (SGR)
3210 if (ts.MouseEventTracking)
3211 MouseReportExtMode = IdMouseTrackExtSGR;
3212 break;
3213 case 1015: // Extended Mouse Tracking (rxvt-unicode)
3214 if (ts.MouseEventTracking)
3215 MouseReportExtMode = IdMouseTrackExtURXVT;
3216 break;
3217 case 1047: // Alternate Screen Buffer
3218 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
3219 BuffSaveScreen();
3220 AltScr = TRUE;
3221 }
3222 break;
3223 case 1048: // Save Cursor Position (Alternate Screen Buffer)
3224 if (ts.TermFlag & TF_ALTSCR) {
3225 SaveCursor();
3226 }
3227 break;
3228 case 1049: // Alternate Screen Buffer
3229 if ((ts.TermFlag & TF_ALTSCR) && !AltScr) {
3230 SaveCursor();
3231 BuffSaveScreen();
3232 BuffClearScreen();
3233 AltScr = TRUE;
3234 }
3235 break;
3236 case 2004: // Bracketed Paste Mode
3237 BracketedPaste = TRUE;
3238 break;
3239 case 7727: // mintty Application Escape Mode
3240 AppliEscapeMode = 1;
3241 break;
3242 case 7786: // Wheel to Cursor translation
3243 if (ts.TranslateWheelToCursor) {
3244 AcceptWheelToCursor = TRUE;
3245 }
3246 break;
3247 case 8200: // ClearThenHome
3248 ClearThenHome = TRUE;
3249 break;
3250 case 14001: // NetTerm mouse mode
3251 if (ts.MouseEventTracking)
3252 MouseReportMode = IdMouseTrackNetTerm;
3253 break;
3254 case 14002: // test Application Escape Mode 2
3255 case 14003: // test Application Escape Mode 3
3256 case 14004: // test Application Escape Mode 4
3257 AppliEscapeMode = Param[i] - 14000;
3258 break;
3259 }
3260 }
3261 }
3262
3263 void CSQ_i_Mode() // DECMC
3264 {
3265 switch (Param[1]) {
3266 case 1:
3267 if (ts.TermFlag&TF_PRINTERCTRL) {
3268 OpenPrnFile();
3269 BuffDumpCurrentLine(LF);
3270 if (! AutoPrintMode)
3271 ClosePrnFile();
3272 }
3273 break;
3274 /* auto print mode off */
3275 case 4:
3276 if (AutoPrintMode) {
3277 ClosePrnFile();
3278 AutoPrintMode = FALSE;
3279 }
3280 break;
3281 /* auto print mode on */
3282 case 5:
3283 if (ts.TermFlag&TF_PRINTERCTRL) {
3284 if (! AutoPrintMode) {
3285 OpenPrnFile();
3286 AutoPrintMode = TRUE;
3287 }
3288 }
3289 break;
3290 }
3291 }
3292
3293 void CSQ_l_Mode() // DECRST
3294 {
3295 int i;
3296
3297 for (i = 1 ; i <= NParam ; i++) {
3298 switch (Param[i]) {
3299 case 1: AppliCursorMode = FALSE; break; // DECCKM
3300 case 3: CSQChangeColumnMode(80); break; // DECCOLM
3301 case 5: /* Normal Video (DECSCNM) */
3302 if (ts.ColorFlag & CF_REVERSEVIDEO)
3303 CSQExchangeColor(); /* Exchange text/back color */
3304 break;
3305 case 6: // DECOM
3306 if (isCursorOnStatusLine)
3307 MoveCursor(0,CursorY);
3308 else {
3309 RelativeOrgMode = FALSE;
3310 MoveCursor(0,0);
3311 }
3312 break;
3313 case 7: AutoWrapMode = FALSE; break; // DECAWM
3314 case 8: AutoRepeatMode = FALSE; break; // DECARM
3315 case 9: MouseReportMode = IdMouseTrackNone; break; /* X10 Mouse Tracking */
3316 case 12: /* att610 cursor blinking */
3317 if (ts.WindowFlag & WF_CURSORCHANGE) {
3318 ts.NonblinkingCursor = TRUE;
3319 ChangeCaret();
3320 }
3321 break;
3322 case 19: PrintEX = FALSE; break; // DECPEX
3323 case 25: DispEnableCaret(FALSE); break; // cursor off (DECTCEM)
3324 case 47: // Alternate Screen Buffer
3325 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
3326 BuffRestoreScreen();
3327 AltScr = FALSE;
3328 }
3329 break;
3330 case 59:
3331 if (ts.Language==IdJapanese) {
3332 /* katakana terminal */
3333 Gn[0] = IdASCII;
3334 Gn[1] = IdKatakana;
3335 Gn[2] = IdKatakana;
3336 Gn[3] = IdKanji;
3337 Glr[0] = 0;
3338 if ((ts.KanjiCode==IdJIS) &&
3339 (ts.JIS7Katakana==0))
3340 Glr[1] = 2; // 8-bit katakana
3341 else
3342 Glr[1] = 3;
3343 }
3344 break;
3345 case 66: AppliKeyMode = FALSE; break; // DECNKM
3346 case 67: ts.BSKey = IdDEL; break; // DECBKM
3347 case 69: // DECLRMM (DECVSSM)
3348 LRMarginMode = FALSE;
3349 CursorLeftM = 0;
3350 CursorRightM = NumOfColumns - 1;
3351 break;
3352 case 1000: // Mouse Tracking
3353 case 1001: // Hilite Mouse Tracking
3354 case 1002: // Button-Event Mouse Tracking
3355 case 1003: // Any-Event Mouse Tracking
3356 MouseReportMode = IdMouseTrackNone;
3357 break;
3358 case 1004: // Focus Report
3359 FocusReportMode = FALSE;
3360 break;
3361 case 1005: // Extended Mouse Tracking (UTF-8)
3362 case 1006: // Extended Mouse Tracking (SGR)
3363 case 1015: // Extended Mouse Tracking (rxvt-unicode)
3364 MouseReportExtMode = IdMouseTrackExtNone;
3365 break;
3366 case 1047: // Alternate Screen Buffer
3367 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
3368 BuffClearScreen();
3369 BuffRestoreScreen();
3370 AltScr = FALSE;
3371 }
3372 break;
3373 case 1048: // Save Cursor Position (Alternate Screen Buffer)
3374 if (ts.TermFlag & TF_ALTSCR) {
3375 RestoreCursor();
3376 }
3377 break;
3378 case 1049: // Alternate Screen Buffer
3379 if ((ts.TermFlag & TF_ALTSCR) && AltScr) {
3380 BuffClearScreen();
3381 BuffRestoreScreen();
3382 AltScr = FALSE;
3383 RestoreCursor();
3384 }
3385 break;
3386 case 2004: // Bracketed Paste Mode
3387 BracketedPaste = FALSE;
3388 break;
3389 case 7727: // mintty Application Escape Mode
3390 AppliEscapeMode = 0;
3391 break;
3392 case 7786: // Wheel to Cursor translation
3393 AcceptWheelToCursor = FALSE;
3394 break;
3395 case 8200: // ClearThenHome
3396 ClearThenHome = FALSE;
3397 break;
3398 case 14001: // NetTerm mouse mode
3399 MouseReportMode = IdMouseTrackNone;
3400 break;
3401 case 14002: // test Application Escape Mode 2
3402 case 14003: // test Application Escape Mode 3
3403 case 14004: // test Application Escape Mode 4
3404 AppliEscapeMode = 0;
3405 break;
3406 }
3407 }
3408 }
3409
3410 void CSQ_n_Mode() // DECDSR
3411 {
3412 switch (Param[1]) {
3413 case 53:
3414 case 55:
3415 /* Locator Device Status Report -> Ready */
3416 SendCSIstr("?50n", 0);
3417 break;
3418 }
3419 }
3420
3421 void CSQuest(BYTE b