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 8822 - (show annotations) (download) (as text)
Thu Jul 2 15:41:37 2020 UTC (3 years, 9 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 152774 byte(s)
ログが取れなくなっていたので修正

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