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 3471 - (show annotations) (download) (as text)
Fri Jun 12 12:02:06 2009 UTC (14 years, 10 months ago) by doda
File MIME type: text/x-csrc
File size: 78923 byte(s)
以下の理由でCSI/OSCの送信を別関数に分けた。
・Send8BitModeの判定を関数側に移して、記述を簡単にできるようにするため
・送信文字列の長さの指定を間違えにくくするため

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