Develop and Download Open Source Software

Browse Subversion Repository

Contents of /branches/ttcomtester/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


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