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 3742 - (show annotations) (download) (as text)
Wed Jan 27 13:38:58 2010 UTC (14 years, 2 months ago) by doda
File MIME type: text/x-csrc
File size: 83750 byte(s)
コメント追加(mnemonic)

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