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 8391 - (show annotations) (download) (as text)
Thu Nov 21 15:00:01 2019 UTC (4 years, 4 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 141228 byte(s)
_CRTDBG_MAP_ALLOC を使ってデバッグバージョンのヒープ割り当て関数へ切り替え

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