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 9313 - (show annotations) (download) (as text)
Sun Jun 20 01:07:40 2021 UTC (2 years, 9 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 153630 byte(s)
locale設定を削除

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