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 7978 - (show annotations) (download) (as text)
Sat Aug 17 04:54:13 2019 UTC (4 years, 7 months ago) by yutakapon
File MIME type: text/x-csrc
File size: 139651 byte(s)
英語版WindowsでTera Termの起動時にアプリケーションフォルトとなることがある問題を修正した。
英語版Windows95/NT4.0でsetlocaleがNULLを返すことで、NULLポインタアクセスで落ちる。
ただし、英語版Windows95でもstrrchrにNULLを渡しているにも関わらず、落ちない場合もある。

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