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 9115 - (show annotations) (download) (as text)
Mon Dec 28 14:29:48 2020 UTC (3 years, 3 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 153874 byte(s)
エスケープシーケンスからの印字を修正

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