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 3470 - (show annotations) (download) (as text)
Fri Jun 12 10:36:49 2009 UTC (14 years, 10 months ago) by doda
File MIME type: text/x-csrc
File size: 80164 byte(s)
8ビット応答設定(S8C1T)時、Secondary DAの応答の後ろにゴミがついていたのを修正。

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