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 3485 - (show annotations) (download) (as text)
Mon Jun 15 02:39:48 2009 UTC (14 years, 9 months ago) by doda
File MIME type: text/x-csrc
File size: 80635 byte(s)
ウィンドウ制御/報告シーケンスおよびカーソル形状制御シーケンスを受け入れるか設定できるようにした。

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 if (ts.WindowFlag & WF_CURSORCHANGE) {
1510 ts.NonblinkingCursor = TRUE;
1511 ChangeCaret();
1512 }
1513 break;
1514 case 34: // WYULCURM
1515 if (ts.WindowFlag & WF_CURSORCHANGE) {
1516 ts.CursorShape = IdHCur;
1517 ChangeCaret();
1518 }
1519 break;
1520 }
1521 }
1522
1523 void CS_i_Mode()
1524 {
1525 if (Param[1]==-1) Param[1] = 0;
1526 switch (Param[1]) {
1527 /* print screen */
1528 // PrintEX -- TRUE: print screen
1529 // FALSE: scroll region
1530 case 0: BuffPrint(! PrintEX); break;
1531 /* printer controller mode off */
1532 case 4: break; /* See PrnParseCS() */
1533 /* printer controller mode on */
1534 case 5:
1535 if (! AutoPrintMode)
1536 OpenPrnFile();
1537 DirectPrn = (ts.PrnDev[0]!=0);
1538 PrinterMode = TRUE;
1539 break;
1540 }
1541 }
1542
1543 void CS_l_Mode()
1544 {
1545 switch (Param[1]) {
1546 case 2: // KAM
1547 KeybEnabled = TRUE; break;
1548 case 4: // IRM
1549 InsertMode = FALSE; break;
1550 case 12: // SRM
1551 ts.LocalEcho = 1;
1552 if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1553 TelChangeEcho();
1554 break;
1555 case 20: // LF/NL
1556 LFMode = FALSE;
1557 ts.CRSend = IdCR;
1558 cv.CRSend = IdCR;
1559 break;
1560 case 33: // WYSTCURM
1561 if (ts.WindowFlag & WF_CURSORCHANGE) {
1562 ts.NonblinkingCursor = FALSE;
1563 ChangeCaret();
1564 }
1565 break;
1566 case 34: // WYULCURM
1567 if (ts.WindowFlag & WF_CURSORCHANGE) {
1568 ts.CursorShape = IdBlkCur;
1569 ChangeCaret();
1570 }
1571 break;
1572 }
1573 }
1574
1575 void CS_n_Mode()
1576 {
1577 char Report[16];
1578 int Y, len;
1579
1580 switch (Param[1]) {
1581 case 5:
1582 /* Device Status Report -> Ready */
1583 SendCSIstr("0n", 2);
1584 break;
1585 case 6:
1586 /* Cursor Position Report */
1587 Y = CursorY+1;
1588 if ((StatusLine>0) &&
1589 (Y==NumOfLines))
1590 Y = 1;
1591 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, CursorX+1);
1592 SendCSIstr(Report, len);
1593 break;
1594 }
1595 }
1596
1597 void CSSetAttr()
1598 {
1599 int i, P;
1600
1601 UpdateStr();
1602 for (i=1 ; i<=NParam ; i++)
1603 {
1604 P = Param[i];
1605 if (P<0) P = 0;
1606 switch (P) {
1607 case 0: /* Clear all */
1608 CharAttr = DefCharAttr;
1609 BuffSetCurCharAttr(CharAttr);
1610 break;
1611
1612 case 1: /* Bold */
1613 CharAttr.Attr |= AttrBold;
1614 BuffSetCurCharAttr(CharAttr);
1615 break;
1616
1617 case 4: /* Under line */
1618 CharAttr.Attr |= AttrUnder;
1619 BuffSetCurCharAttr(CharAttr);
1620 break;
1621
1622 case 5: /* Blink */
1623 CharAttr.Attr |= AttrBlink;
1624 BuffSetCurCharAttr(CharAttr);
1625 break;
1626
1627 case 7: /* Reverse */
1628 CharAttr.Attr |= AttrReverse;
1629 BuffSetCurCharAttr(CharAttr);
1630 break;
1631
1632 case 22: /* Bold off */
1633 CharAttr.Attr &= ~ AttrBold;
1634 BuffSetCurCharAttr(CharAttr);
1635 break;
1636
1637 case 24: /* Under line off */
1638 CharAttr.Attr &= ~ AttrUnder;
1639 BuffSetCurCharAttr(CharAttr);
1640 break;
1641
1642 case 25: /* Blink off */
1643 CharAttr.Attr &= ~ AttrBlink;
1644 BuffSetCurCharAttr(CharAttr);
1645 break;
1646
1647 case 27: /* Reverse off */
1648 CharAttr.Attr &= ~ AttrReverse;
1649 BuffSetCurCharAttr(CharAttr);
1650 break;
1651
1652 case 30:
1653 case 31:
1654 case 32:
1655 case 33:
1656 case 34:
1657 case 35:
1658 case 36:
1659 case 37: /* text color */
1660 CharAttr.Attr2 |= Attr2Fore;
1661 CharAttr.Fore = P - 30;
1662 BuffSetCurCharAttr(CharAttr);
1663 break;
1664
1665 case 38: /* text color (256color mode) */
1666 if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1667 i++;
1668 if (i < NParam) {
1669 P = Param[++i];
1670 if (P<0) {
1671 P = 0;
1672 }
1673 CharAttr.Attr2 |= Attr2Fore;
1674 CharAttr.Fore = P;
1675 BuffSetCurCharAttr(CharAttr);
1676 }
1677 }
1678 break;
1679
1680 case 39: /* Reset text color */
1681 CharAttr.Attr2 &= ~ Attr2Fore;
1682 CharAttr.Fore = AttrDefaultFG;
1683 BuffSetCurCharAttr(CharAttr);
1684 break;
1685
1686 case 40:
1687 case 41:
1688 case 42:
1689 case 43:
1690 case 44:
1691 case 45:
1692 case 46:
1693 case 47: /* Back color */
1694 CharAttr.Attr2 |= Attr2Back;
1695 CharAttr.Back = P - 40;
1696 BuffSetCurCharAttr(CharAttr);
1697 break;
1698
1699 case 48: /* Back color (256color mode) */
1700 if ((ts.ColorFlag & CF_XTERM256) && i < NParam && Param[i+1] == 5) {
1701 i++;
1702 if (i < NParam) {
1703 P = Param[++i];
1704 if (P<0) {
1705 P = 0;
1706 }
1707 CharAttr.Attr2 |= Attr2Back;
1708 CharAttr.Back = P;
1709 BuffSetCurCharAttr(CharAttr);
1710 }
1711 }
1712 break;
1713
1714 case 49: /* Reset back color */
1715 CharAttr.Attr2 &= ~ Attr2Back;
1716 CharAttr.Back = AttrDefaultBG;
1717 BuffSetCurCharAttr(CharAttr);
1718 break;
1719
1720 case 90:
1721 case 91:
1722 case 92:
1723 case 93:
1724 case 94:
1725 case 95:
1726 case 96:
1727 case 97: /* aixterm style text color */
1728 if (ts.ColorFlag & CF_AIXTERM16) {
1729 CharAttr.Attr2 |= Attr2Fore;
1730 CharAttr.Fore = P - 90 + 8;
1731 BuffSetCurCharAttr(CharAttr);
1732 }
1733 break;
1734
1735 case 100:
1736 if (! (ts.ColorFlag & CF_AIXTERM16)) {
1737 /* Reset text and back color */
1738 CharAttr.Attr2 &= ~ (Attr2Fore | Attr2Back);
1739 CharAttr.Fore = AttrDefaultFG;
1740 CharAttr.Back = AttrDefaultBG;
1741 BuffSetCurCharAttr(CharAttr);
1742 break;
1743 }
1744 /* fall through to aixterm style back color */
1745
1746 case 101:
1747 case 102:
1748 case 103:
1749 case 104:
1750 case 105:
1751 case 106:
1752 case 107: /* aixterm style back color */
1753 if (ts.ColorFlag & CF_AIXTERM16) {
1754 CharAttr.Attr2 |= Attr2Back;
1755 CharAttr.Back = P - 100 + 8;
1756 BuffSetCurCharAttr(CharAttr);
1757 }
1758 break;
1759 }
1760 }
1761 }
1762
1763 void CSSetScrollRegion()
1764 {
1765 if ((StatusLine>0) &&
1766 (CursorY==NumOfLines-1))
1767 {
1768 MoveCursor(0,CursorY);
1769 return;
1770 }
1771 if (Param[1]<1) Param[1] =1;
1772 if ((NParam < 2) | (Param[2]<1))
1773 Param[2] = NumOfLines-StatusLine;
1774 Param[1]--;
1775 Param[2]--;
1776 if (Param[1] > NumOfLines-1-StatusLine)
1777 Param[1] = NumOfLines-1-StatusLine;
1778 if (Param[2] > NumOfLines-1-StatusLine)
1779 Param[2] = NumOfLines-1-StatusLine;
1780 if (Param[1] >= Param[2]) return;
1781 CursorTop = Param[1];
1782 CursorBottom = Param[2];
1783 if (RelativeOrgMode) MoveCursor(0,CursorTop);
1784 else MoveCursor(0,0);
1785 }
1786
1787 void CSSunSequence() /* Sun terminal private sequences */
1788 {
1789 int x, y, len;
1790 char Report[16];
1791
1792 switch (Param[1]) {
1793 case 1: // De-iconify window
1794 if (ts.WindowFlag & WF_WINDOWCHANGE)
1795 DispShowWindow(WINDOW_RESTORE);
1796 break;
1797 case 2: // Iconify window
1798 if (ts.WindowFlag & WF_WINDOWCHANGE)
1799 DispShowWindow(WINDOW_MINIMIZE);
1800 break;
1801 case 3: // set window position
1802 if (ts.WindowFlag & WF_WINDOWCHANGE) {
1803 if (NParam < 2) Param[2] = 0;
1804 if (NParam < 3) Param[3] = 0;
1805 DispMoveWindow(Param[2], Param[3]);
1806 }
1807 break;
1808 case 4: // set window size
1809 if (ts.WindowFlag & WF_WINDOWCHANGE) {
1810 if (NParam < 2) Param[2] = 0;
1811 if (NParam < 3) Param[3] = 0;
1812 DispResizeWin(Param[3], Param[2]);
1813 }
1814 break;
1815 case 5: // Raise window
1816 if (ts.WindowFlag & WF_WINDOWCHANGE)
1817 DispShowWindow(WINDOW_RAISE);
1818 break;
1819 case 6: // Lower window
1820 if (ts.WindowFlag & WF_WINDOWCHANGE)
1821 DispShowWindow(WINDOW_LOWER);
1822 break;
1823 case 7: // Refresh window
1824 if (ts.WindowFlag & WF_WINDOWCHANGE)
1825 DispShowWindow(WINDOW_REFRESH);
1826 break;
1827 case 8: /* set terminal size */
1828 if (ts.WindowFlag & WF_WINDOWCHANGE) {
1829 if ((Param[2]<=1) || (NParam<2)) Param[2] = 24;
1830 if ((Param[3]<=1) || (NParam<3)) Param[3] = 80;
1831 ChangeTerminalSize(Param[3],Param[2]);
1832 }
1833 break;
1834 case 9: // Maximize/Restore window
1835 if (ts.WindowFlag & WF_WINDOWCHANGE) {
1836 if (NParam < 2 || Param[2] == 0) {
1837 DispShowWindow(WINDOW_RESTORE);
1838 }
1839 else {
1840 DispShowWindow(WINDOW_MAXIMIZE);
1841 }
1842 }
1843 break;
1844 case 11: // Report window state
1845 if (ts.WindowFlag & WF_WINDOWREPORT) {
1846 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
1847 SendCSIstr(Report, len);
1848 }
1849 break;
1850 case 13: // Report window position
1851 if (ts.WindowFlag & WF_WINDOWREPORT) {
1852 DispGetWindowPos(&x, &y);
1853 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%d;%dt", CLocale, x, y);
1854 SendCSIstr(Report, len);
1855 }
1856 break;
1857 case 14: /* get window size??? */
1858 if (ts.WindowFlag & WF_WINDOWREPORT) {
1859 /* this is not actual window size */
1860 SendCSIstr("4;640;480t", 10);
1861 }
1862 break;
1863 case 18: /* get terminal size */
1864 if (ts.WindowFlag & WF_WINDOWREPORT) {
1865 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%u;t", CLocale,
1866 NumOfLines-StatusLine, NumOfColumns);
1867 SendCSIstr(Report, len);
1868 }
1869 break;
1870 case 19: // Report display size (character)
1871 if (ts.WindowFlag & WF_WINDOWREPORT) {
1872 DispGetRootWinSize(&x, &y);
1873 len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
1874 SendCSIstr(Report, len);
1875 }
1876 break;
1877 }
1878 }
1879
1880 void CSGT(BYTE b)
1881 {
1882 switch (b) {
1883 case 'c': /* second terminal report (Secondary DA) */
1884 if (Param[1] < 1) {
1885 SendCSIstr(">32;10;2c", 9); /* VT382 */
1886 }
1887 break;
1888 case 'J':
1889 if (Param[1]==3) // IO-8256 terminal
1890 {
1891 if (Param[2]<1) Param[2]=1;
1892 if (Param[3]<1) Param[3]=1;
1893 if (Param[4]<1) Param[4]=1;
1894 if (Param[5]<1) Param[5]=1;
1895 BuffEraseBox(Param[3]-1,Param[2]-1,
1896 Param[5]-1,Param[4]-1);
1897 }
1898 break;
1899 case 'K':
1900 if ((NParam>=2) && (Param[1]==5))
1901 { // IO-8256 terminal
1902 switch (Param[2]) {
1903 case 3:
1904 case 4:
1905 case 5:
1906 case 6:
1907 BuffDrawLine(CharAttr, Param[2], Param[3]);
1908 break;
1909 case 12:
1910 /* Text color */
1911 if ((Param[3]>=0) && (Param[3]<=7))
1912 {
1913 switch (Param[3]) {
1914 case 3: CharAttr.Fore = IdBlue; break;
1915 case 4: CharAttr.Fore = IdCyan; break;
1916 case 5: CharAttr.Fore = IdYellow; break;
1917 case 6: CharAttr.Fore = IdMagenta; break;
1918 default: CharAttr.Fore = Param[3]; break;
1919 }
1920 CharAttr.Attr2 |= Attr2Fore;
1921 BuffSetCurCharAttr(CharAttr);
1922 }
1923 break;
1924 }
1925 }
1926 else if (Param[1]==3)
1927 {// IO-8256 terminal
1928 if (Param[2]<1) Param[2] = 1;
1929 if (Param[3]<1) Param[2] = 1;
1930 BuffEraseCharsInLine(Param[2]-1,Param[3]-Param[2]+1);
1931 }
1932 break;
1933 }
1934 }
1935
1936 void CSQExchangeColor()
1937 {
1938 COLORREF ColorRef;
1939
1940 BuffUpdateScroll();
1941
1942 if (ts.ColorFlag & CF_REVERSECOLOR) {
1943 ColorRef = ts.VTColor[0];
1944 ts.VTColor[0] = ts.VTReverseColor[0];
1945 ts.VTReverseColor[0] = ColorRef;
1946 ColorRef = ts.VTColor[1];
1947 ts.VTColor[1] = ts.VTReverseColor[1];
1948 ts.VTReverseColor[1] = ColorRef;
1949 }
1950 else {
1951 ColorRef = ts.VTColor[0];
1952 ts.VTColor[0] = ts.VTColor[1];
1953 ts.VTColor[1] = ColorRef;
1954 }
1955
1956 ColorRef = ts.VTBoldColor[0];
1957 ts.VTBoldColor[0] = ts.VTBoldColor[1];
1958 ts.VTBoldColor[1] = ColorRef;
1959
1960 ColorRef = ts.VTBlinkColor[0];
1961 ts.VTBlinkColor[0] = ts.VTBlinkColor[1];
1962 ts.VTBlinkColor[1] = ColorRef;
1963
1964 ColorRef = ts.URLColor[0];
1965 ts.URLColor[0] = ts.URLColor[1];
1966 ts.URLColor[1] = ColorRef;
1967
1968 ts.ColorFlag ^= CF_REVERSEVIDEO;
1969
1970 #ifdef ALPHABLEND_TYPE2
1971 BGInitialize();
1972 #endif
1973 DispChangeBackground();
1974 UpdateWindow(HVTWin);
1975 }
1976
1977 void CSQ_h_Mode()
1978 {
1979 int i;
1980
1981 for (i = 1 ; i<=NParam ; i++)
1982 switch (Param[i]) {
1983 case 1: AppliCursorMode = TRUE; break;
1984 case 3:
1985 ChangeTerminalSize(132,NumOfLines-StatusLine);
1986 break;
1987 case 5: /* Reverse Video */
1988 if (!(ts.ColorFlag & CF_REVERSEVIDEO))
1989 CSQExchangeColor(); /* Exchange text/back color */
1990 break;
1991 case 6:
1992 if ((StatusLine>0) && (CursorY==NumOfLines-1))
1993 MoveCursor(0,CursorY);
1994 else {
1995 RelativeOrgMode = TRUE;
1996 MoveCursor(0,CursorTop);
1997 }
1998 break;
1999 case 7: AutoWrapMode = TRUE; break;
2000 case 8: AutoRepeatMode = TRUE; break;
2001 case 9:
2002 if (ts.MouseEventTracking)
2003 MouseReportMode = IdMouseTrackX10;
2004 break;
2005 case 12:
2006 if (ts.WindowFlag & WF_CURSORCHANGE) {
2007 ts.NonblinkingCursor = FALSE;
2008 ChangeCaret();
2009 }
2010 break;
2011 case 19: PrintEX = TRUE; break;
2012 case 25: DispEnableCaret(TRUE); break; // cursor on
2013 case 38:
2014 if (ts.AutoWinSwitch>0)
2015 ChangeEmu = IdTEK; /* Enter TEK Mode */
2016 break;
2017 case 59:
2018 if (ts.Language==IdJapanese)
2019 { /* kanji terminal */
2020 Gn[0] = IdASCII;
2021 Gn[1] = IdKatakana;
2022 Gn[2] = IdKatakana;
2023 Gn[3] = IdKanji;
2024 Glr[0] = 0;
2025 if ((ts.KanjiCode==IdJIS) &&
2026 (ts.JIS7Katakana==0))
2027 Glr[1] = 2; // 8-bit katakana
2028 else
2029 Glr[1] = 3;
2030 }
2031 break;
2032 case 66: AppliKeyMode = TRUE; break;
2033 case 67: ts.BSKey = IdBS; break;
2034 case 1000:
2035 if (ts.MouseEventTracking)
2036 MouseReportMode = IdMouseTrackVT200;
2037 break;
2038 case 1001:
2039 if (ts.MouseEventTracking)
2040 MouseReportMode = IdMouseTrackVT200Hl;
2041 break;
2042 case 1002:
2043 if (ts.MouseEventTracking)
2044 MouseReportMode = IdMouseTrackBtnEvent;
2045 break;
2046 case 1003:
2047 if (ts.MouseEventTracking)
2048 MouseReportMode = IdMouseTrackAllEvent;
2049 break;
2050 case 1004:
2051 if (ts.MouseEventTracking)
2052 FocusReportMode = TRUE;
2053 break;
2054 }
2055 }
2056
2057 void CSQ_i_Mode()
2058 {
2059 if (Param[1]==-1) Param[1] = 0;
2060 switch (Param[1]) {
2061 case 1:
2062 OpenPrnFile();
2063 BuffDumpCurrentLine(LF);
2064 if (! AutoPrintMode)
2065 ClosePrnFile();
2066 break;
2067 /* auto print mode off */
2068 case 4:
2069 if (AutoPrintMode)
2070 {
2071 ClosePrnFile();
2072 AutoPrintMode = FALSE;
2073 }
2074 break;
2075 /* auto print mode on */
2076 case 5:
2077 if (! AutoPrintMode)
2078 {
2079 OpenPrnFile();
2080 AutoPrintMode = TRUE;
2081 }
2082 break;
2083 }
2084 }
2085
2086 void CSQ_l_Mode()
2087 {
2088 int i;
2089
2090 for (i = 1 ; i <= NParam ; i++)
2091 switch (Param[i]) {
2092 case 1: AppliCursorMode = FALSE; break;
2093 case 3:
2094 ChangeTerminalSize(80,NumOfLines-StatusLine);
2095 break;
2096 case 5: /* Normal Video */
2097 if (ts.ColorFlag & CF_REVERSEVIDEO)
2098 CSQExchangeColor(); /* Exchange text/back color */
2099 break;
2100 case 6:
2101 if ((StatusLine>0) && (CursorY==NumOfLines-1))
2102 MoveCursor(0,CursorY);
2103 else {
2104 RelativeOrgMode = FALSE;
2105 MoveCursor(0,0);
2106 }
2107 break;
2108 case 7: AutoWrapMode = FALSE; break;
2109 case 8: AutoRepeatMode = FALSE; break;
2110 case 9: MouseReportMode = IdMouseTrackNone; break;
2111 case 12:
2112 if (ts.WindowFlag & WF_CURSORCHANGE) {
2113 ts.NonblinkingCursor = TRUE;
2114 ChangeCaret();
2115 }
2116 break;
2117 case 19: PrintEX = FALSE; break;
2118 case 25: DispEnableCaret(FALSE); break; // cursor off
2119 case 59:
2120 if (ts.Language==IdJapanese)
2121 { /* katakana terminal */
2122 Gn[0] = IdASCII;
2123 Gn[1] = IdKatakana;
2124 Gn[2] = IdKatakana;
2125 Gn[3] = IdKanji;
2126 Glr[0] = 0;
2127 if ((ts.KanjiCode==IdJIS) &&
2128 (ts.JIS7Katakana==0))
2129 Glr[1] = 2; // 8-bit katakana
2130 else
2131 Glr[1] = 3;
2132 }
2133 break;
2134 case 66: AppliKeyMode = FALSE; break;
2135 case 67: ts.BSKey = IdDEL; break;
2136 case 1000:
2137 case 1001:
2138 case 1002:
2139 case 1003: MouseReportMode = IdMouseTrackNone; break;
2140 case 1004: FocusReportMode = FALSE; break;
2141 }
2142 }
2143
2144 void CSQ_n_Mode()
2145 {
2146 }
2147
2148 void CSQuest(BYTE b)
2149 {
2150 switch (b) {
2151 case 'K': CSLineErase(); break;
2152 case 'h': CSQ_h_Mode(); break;
2153 case 'i': CSQ_i_Mode(); break;
2154 case 'l': CSQ_l_Mode(); break;
2155 case 'n': CSQ_n_Mode(); break;
2156 }
2157 }
2158
2159 void SoftReset()
2160 // called by software-reset escape sequence handler
2161 {
2162 UpdateStr();
2163 AutoRepeatMode = TRUE;
2164 DispEnableCaret(TRUE); // cursor on
2165 InsertMode = FALSE;
2166 RelativeOrgMode = FALSE;
2167 AppliKeyMode = FALSE;
2168 AppliCursorMode = FALSE;
2169 if ((StatusLine>0) &&
2170 (CursorY == NumOfLines-1))
2171 MoveToMainScreen();
2172 CursorTop = 0;
2173 CursorBottom = NumOfLines-1-StatusLine;
2174 ResetCharSet();
2175
2176 Send8BitMode = ts.Send8BitCtrl;
2177
2178 /* Attribute */
2179 CharAttr = DefCharAttr;
2180 Special = FALSE;
2181 BuffSetCurCharAttr(CharAttr);
2182
2183 // status buffers
2184 ResetSBuffers();
2185 }
2186
2187 void CSExc(BYTE b)
2188 {
2189 switch (b) {
2190 case 'p':
2191 /* Software reset */
2192 SoftReset();
2193 break;
2194 }
2195 }
2196
2197 void CSDouble(BYTE b)
2198 {
2199 switch (b) {
2200 case 'p':
2201 /* Select terminal mode (software reset) */
2202 SoftReset();
2203 if (NParam > 0) {
2204 switch (Param[1]) {
2205 case 61: // VT100 Mode
2206 Send8BitMode = FALSE; break;
2207 case 62: // VT200 Mode
2208 case 63: // VT300 Mode
2209 case 64: // VT400 Mode
2210 if (NParam > 1 && Param[2] == 1)
2211 Send8BitMode = FALSE;
2212 else
2213 Send8BitMode = TRUE;
2214 break;
2215 }
2216 }
2217 break;
2218 }
2219 }
2220
2221 void CSDol(BYTE b)
2222 {
2223 switch (b) {
2224 case '}':
2225 if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2226 if (StatusLine==0) return;
2227 if ((Param[1]<1) && (CursorY==NumOfLines-1))
2228 MoveToMainScreen();
2229 else if ((Param[1]==1) && (CursorY<NumOfLines-1))
2230 MoveToStatusLine();
2231 break;
2232 case '~':
2233 if ((ts.TermFlag & TF_ENABLESLINE)==0) return;
2234 if (Param[1]<=1)
2235 HideStatusLine();
2236 else if ((StatusLine==0) && (Param[1]==2))
2237 ShowStatusLine(1); // show
2238 break;
2239 }
2240 }
2241
2242 void CSSpace(BYTE b) {
2243 switch (b) {
2244 case 'q':
2245 if (ts.WindowFlag & WF_CURSORCHANGE) {
2246 if (NParam > 0) {
2247 if (Param[1] < 0) Param[1] = 0;
2248 switch (Param[1]) {
2249 case 0:
2250 case 1:
2251 ts.CursorShape = IdBlkCur;
2252 ts.NonblinkingCursor = FALSE;
2253 break;
2254 case 2:
2255 ts.CursorShape = IdBlkCur;
2256 ts.NonblinkingCursor = TRUE;
2257 break;
2258 case 3:
2259 ts.CursorShape = IdHCur;
2260 ts.NonblinkingCursor = FALSE;
2261 break;
2262 case 4:
2263 ts.CursorShape = IdHCur;
2264 ts.NonblinkingCursor = TRUE;
2265 break;
2266 case 5:
2267 ts.CursorShape = IdVCur;
2268 ts.NonblinkingCursor = FALSE;
2269 break;
2270 case 6:
2271 ts.CursorShape = IdVCur;
2272 ts.NonblinkingCursor = TRUE;
2273 break;
2274 default:
2275 return;
2276 }
2277 ChangeCaret();
2278 }
2279 }
2280 break;
2281 }
2282 }
2283
2284 void PrnParseCS(BYTE b) // printer mode
2285 {
2286 ParseMode = ModeFirst;
2287 switch (ICount) {
2288 /* no intermediate char */
2289 case 0:
2290 switch (Prv) {
2291 /* no private parameter */
2292 case 0:
2293 switch (b) {
2294 case 'i':
2295 if (Param[1]==4)
2296 {
2297 PrinterMode = FALSE;
2298 // clear prn buff
2299 WriteToPrnFile(0,FALSE);
2300 if (! AutoPrintMode)
2301 ClosePrnFile();
2302 return;
2303 }
2304 break;
2305 } /* of case Prv=0 */
2306 break;
2307 }
2308 break;
2309 /* one intermediate char */
2310 case 1: break;
2311 } /* of case Icount */
2312
2313 WriteToPrnFile(b,TRUE);
2314 }
2315
2316 void ParseCS(BYTE b) /* b is the final char */
2317 {
2318 if (PrinterMode) { // printer mode
2319 PrnParseCS(b);
2320 return;
2321 }
2322
2323 switch (ICount) {
2324 /* no intermediate char */
2325 case 0:
2326 switch (Prv) {
2327 /* no private parameter */
2328 case 0:
2329 switch (b) {
2330 // ISO/IEC 6429 / ECMA-48 Sequence
2331 case '@': CSInsertCharacter(); break; // ICH
2332 case 'A': CSCursorUp(); break; // CUU
2333 case 'B': CSCursorDown(); break; // CUD
2334 case 'C': CSCursorRight(); break; // CUF
2335 case 'D': CSCursorLeft(); break; // CUB
2336 case 'E': CSCursorDown1(); break; // CNL
2337 case 'F': CSCursorUp1(); break; // CPL
2338 case 'G': CSMoveToColumnN(); break; // CHA
2339 case 'H': CSMoveToXY(); break; // CUP
2340 case 'I': CSForwardTab(); break; // CHT
2341 case 'J': CSScreenErase(); break; // ED
2342 case 'K': CSLineErase(); break; // EL
2343 case 'L': CSInsertLine(); break; // IL
2344 case 'M': CSDeleteNLines(); break; // DL
2345 // case 'N': break; // EF -- Not support
2346 // case 'O': break; // EA -- Not support
2347 case 'P': CSDeleteCharacter(); break; // DCH
2348 // case 'Q': break; // SEE -- Not support
2349 // case 'R': break; // CPR -- Not support
2350 case 'S': CSScrollUP(); break; // SU
2351 case 'T': CSScrollDown(); break; // SD
2352 // case 'U': break; // NP -- Not support
2353 // case 'V': break; // PP -- Not support
2354 // case 'W': break; // CTC -- Not support
2355 case 'X': CSEraseCharacter(); break; // ECH
2356 // case 'Y': break; // CVT -- Not support
2357 case 'Z': CSBackwardTab(); break; // CBT
2358 // caes '[': break; // SRS -- Not support
2359 // caes '\\': break; // PTX -- Not support
2360 // caes ']': break; // SDS -- Not support
2361 // caes '^': break; // SIMD -- Not support
2362 case '`': CSMoveToColumnN(); break; // HPA
2363 case 'a': CSCursorRight(); break; // HPR
2364 // caes 'b': break; // REP -- Not support
2365 case 'c': AnswerTerminalType(); break; // DA
2366 case 'd': CSMoveToLineN(); break; // VPA
2367 case 'e': CSCursorUp(); break; // VPR
2368 case 'f': CSMoveToXY(); break; // HVP
2369 case 'g': CSDeleteTabStop(); break; // TBC
2370 case 'h': CS_h_Mode(); break; // SM
2371 case 'i': CS_i_Mode(); break; // MC
2372 // caes 'b': break; // HPB -- Not support
2373 // caes 'b': break; // VPB -- Not support
2374 case 'l': CS_l_Mode(); break; // RM
2375 case 'm': CSSetAttr(); break; // SGR
2376 case 'n': CS_n_Mode(); break; // DSR
2377 // caes 'o': break; // DAQ -- Not support
2378
2379 // Private Sequence
2380 case 'r': CSSetScrollRegion(); break; // DECSTBM
2381 case 's': SaveCursor(); break; // SCP (Save cursor (ANSI.SYS/SCO?))
2382 case 't': CSSunSequence(); break; // DECSLPP / Window manipulation(dtterm?)
2383 case 'u': RestoreCursor(); break; // RCP (Restore cursor (ANSI.SYS/SCO))
2384 } /* of case Prv=0 */
2385 break;
2386 /* private parameter = '>' */
2387 case '>': CSGT(b); break;
2388 /* private parameter = '?' */
2389 case '?': CSQuest(b); break;
2390 } /* end of siwtch (Prv) */
2391 break;
2392 /* one intermediate char */
2393 case 1:
2394 switch (IntChar[1]) {
2395 /* intermediate char = ' ' */
2396 case ' ': CSSpace(b); break;
2397 /* intermediate char = '!' */
2398 case '!': CSExc(b); break;
2399 /* intermediate char = '"' */
2400 case '"': CSDouble(b); break;
2401 /* intermediate char = '$' */
2402 case '$': CSDol(b); break;
2403 }
2404 break;
2405 } /* of case Icount */
2406
2407 ParseMode = ModeFirst;
2408 }
2409
2410 void ControlSequence(BYTE b)
2411 {
2412 if ((b<=US) || (b>=0x80) && (b<=0x9F))
2413 ParseControl(b); /* ctrl char */
2414 else if ((b>=0x40) && (b<=0x7E))
2415 ParseCS(b); /* terminate char */
2416 else {
2417 if (PrinterMode)
2418 WriteToPrnFile(b,FALSE);
2419
2420 if ((b>=0x20) && (b<=0x2F))
2421 { /* intermediate char */
2422 if (ICount<IntCharMax) ICount++;
2423 IntChar[ICount] = b;
2424 }
2425 else if ((b>=0x30) && (b<=0x39))
2426 {
2427 if (Param[NParam] < 0)
2428 Param[NParam] = 0;
2429 if (Param[NParam]<1000)
2430 Param[NParam] = Param[NParam]*10 + b - 0x30;
2431 }
2432 else if (b==0x3B)
2433 {
2434 if (NParam < NParamMax)
2435 {
2436 NParam++;
2437 Param[NParam] = -1;
2438 }
2439 }
2440 else if ((b>=0x3C) && (b<=0x3F))
2441 { /* private char */
2442 if (FirstPrm) Prv = b;
2443 }
2444 }
2445 FirstPrm = FALSE;
2446 }
2447
2448 void DeviceControl(BYTE b)
2449 {
2450 if (ESCFlag && (b=='\\') || (b==ST && ts.KanjiCode!=IdSJIS))
2451 {
2452 ESCFlag = FALSE;
2453 ParseMode = SavedMode;
2454 return;
2455 }
2456
2457 if (b==ESC)
2458 {
2459 ESCFlag = TRUE;
2460 return;
2461 }
2462 else ESCFlag = FALSE;
2463
2464 if (b<=US)
2465 ParseControl(b);
2466 else if ((b>=0x30) && (b<=0x39))
2467 {
2468 if (Param[NParam] < 0) Param[NParam] = 0;
2469 if (Param[NParam]<1000)
2470 Param[NParam] = Param[NParam]*10 + b - 0x30;
2471 }
2472 else if (b==0x3B)
2473 {
2474 if (NParam < NParamMax)
2475 {
2476 NParam++;
2477 Param[NParam] = -1;
2478 }
2479 }
2480 else if ((b>=0x40) && (b<=0x7E))
2481 {
2482 if (b=='|')
2483 {
2484 ParseMode = ModeDCUserKey;
2485 if (Param[1] < 1) ClearUserKey();
2486 WaitKeyId = TRUE;
2487 NewKeyId = 0;
2488 }
2489 else ParseMode = ModeSOS;
2490 }
2491 }
2492
2493 void DCUserKey(BYTE b)
2494 {
2495 if (ESCFlag && (b=='\\') || (b==ST && ts.KanjiCode!=IdSJIS))
2496 {
2497 if (! WaitKeyId) DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
2498 ESCFlag = FALSE;
2499 ParseMode = SavedMode;
2500 return;
2501 }
2502
2503 if (b==ESC)
2504 {
2505 ESCFlag = TRUE;
2506 return;
2507 }
2508 else ESCFlag = FALSE;
2509
2510 if (WaitKeyId)
2511 {
2512 if ((b>=0x30) && (b<=0x39))
2513 {
2514 if (NewKeyId<1000)
2515 NewKeyId = NewKeyId*10 + b - 0x30;
2516 }
2517 else if (b==0x2F)
2518 {
2519 WaitKeyId = FALSE;
2520 WaitHi = TRUE;
2521 NewKeyLen = 0;
2522 }
2523 }
2524 else {
2525 if (b==0x3B)
2526 {
2527 DefineUserKey(NewKeyId,NewKeyStr,NewKeyLen);
2528 WaitKeyId = TRUE;
2529 NewKeyId = 0;
2530 }
2531 else {
2532 if (NewKeyLen < FuncKeyStrMax)
2533 {
2534 if (WaitHi)
2535 {
2536 NewKeyStr[NewKeyLen] = ConvHexChar(b) << 4;
2537 WaitHi = FALSE;
2538 }
2539 else {
2540 NewKeyStr[NewKeyLen] = NewKeyStr[NewKeyLen] +
2541 ConvHexChar(b);
2542 WaitHi = TRUE;
2543 NewKeyLen++;
2544 }
2545 }
2546 }
2547 }
2548 }
2549
2550 void IgnoreString(BYTE b)
2551 {
2552 if ((ESCFlag && (b=='\\')) ||
2553 (b<=US && b!=ESC && b!=HT) ||
2554 (b==ST && ts.KanjiCode!=IdSJIS))
2555 ParseMode = SavedMode;
2556
2557 if (b==ESC) ESCFlag = TRUE;
2558 else ESCFlag = FALSE;
2559 }
2560
2561 BOOL XsParseColor(char *colspec, COLORREF *color)
2562 {
2563 unsigned int r, g, b;
2564 // double dr, dg, db;
2565
2566 r = g = b = 255;
2567
2568 if (colspec == NULL || color == NULL) {
2569 return FALSE;
2570 }
2571
2572 if (_strnicmp(colspec, "rgb:", 4) == 0) {
2573 switch (strlen(colspec)) {
2574 case 9: // rgb:R/G/B
2575 if (sscanf(colspec, "rgb:%1x/%1x/%1x", &r, &g, &b) != 3) {
2576 return FALSE;
2577 }
2578 r *= 17; g *= 17; b *= 17;
2579 break;
2580 case 12: // rgb:RR/GG/BB
2581 if (sscanf(colspec, "rgb:%2x/%2x/%2x", &r, &g, &b) != 3) {
2582 return FALSE;
2583 }
2584 break;
2585 case 15: // rgb:RRR/GGG/BBB
2586 if (sscanf(colspec, "rgb:%3x/%3x/%3x", &r, &g, &b) != 3) {
2587 return FALSE;
2588 }
2589 r >>= 4; g >>= 4; b >>= 4;
2590 break;
2591 case 18: // rgb:RRRR/GGGG/BBBB
2592 if (sscanf(colspec, "rgb:%4x/%4x/%4x", &r, &g, &b) != 3) {
2593 return FALSE;
2594 }
2595 r >>= 8; g >>= 8; b >>= 8;
2596 break;
2597 default:
2598 return FALSE;
2599 }
2600 }
2601 // else if (_strnicmp(colspec, "rgbi:", 5) == 0) {
2602 // ; /* nothing to do */
2603 // }
2604 else if (colspec[0] == '#') {
2605 switch (strlen(colspec)) {
2606 case 4: // #RGB
2607 if (sscanf(colspec, "#%1x%1x%1x", &r, &g, &b) != 3) {
2608 return FALSE;
2609 }
2610 r <<= 4; g <<= 4; b <<= 4;
2611 break;
2612 case 7: // #RRGGBB
2613 if (sscanf(colspec, "#%2x%2x%2x", &r, &g, &b) != 3) {
2614 return FALSE;
2615 }
2616 break;
2617 case 10: // #RRRGGGBBB
2618 if (sscanf(colspec, "#%3x%3x%3x", &r, &g, &b) != 3) {
2619 return FALSE;
2620 }
2621 r >>= 4; g >>= 4; b >>= 4;
2622 break;
2623 case 13: // #RRRRGGGGBBBB
2624 if (sscanf(colspec, "#%4x%4x%4x", &r, &g, &b) != 3) {
2625 return FALSE;
2626 }
2627 r >>= 8; g >>= 8; b >>= 8;
2628 break;
2629 default:
2630 return FALSE;
2631 }
2632 }
2633 else {
2634 return FALSE;
2635 }
2636
2637 if (r > 255 || g > 255 || b > 255) {
2638 return FALSE;
2639 }
2640
2641 *color = RGB(r, g, b);
2642 return TRUE;
2643 }
2644
2645 #define ModeXsFirst 1
2646 #define ModeXsString 2
2647 #define ModeXsColorNum 3
2648 #define ModeXsColorSpec 4
2649 #define ModeXsEsc 5
2650 void XSequence(BYTE b)
2651 {
2652 static BYTE XsParseMode = ModeXsFirst, PrevMode;
2653 static char StrBuff[sizeof(ts.Title)];
2654 static unsigned int ColorNumber, StrLen;
2655 int len;
2656 COLORREF color;
2657
2658 switch (XsParseMode) {
2659 case ModeXsFirst:
2660 if (isdigit(b)) {
2661 if (Param[1] < 1000) {
2662 Param[1] = Param[1]*10 + b - '0';
2663 }
2664 }
2665 else if (b == ';') {
2666 StrBuff[0] = '\0';
2667 StrLen = 0;
2668 if (Param[1] == 4) {
2669 ColorNumber = 0;
2670 XsParseMode = ModeXsColorNum;
2671 }
2672 else {
2673 XsParseMode = ModeXsString;
2674 }
2675 }
2676 else {
2677 ParseMode = ModeFirst;
2678 }
2679 break;
2680 case ModeXsString:
2681 if ((b==ST && ts.KanjiCode!=IdSJIS) || b==BEL) { /* String Terminator */
2682 StrBuff[StrLen] = '\0';
2683 switch (Param[1]) {
2684 case 0: /* Change window title and icon name */
2685 case 1: /* Change icon name */
2686 case 2: /* Change window title */
2687 if (ts.AcceptTitleChangeRequest) {
2688 strncpy_s(cv.TitleRemote, sizeof(cv.TitleRemote), StrBuff, _TRUNCATE);
2689 // (2006.6.15 maya) �^�C�g�����n����������SJIS������
2690 ConvertToCP932(cv.TitleRemote, sizeof(cv.TitleRemote));
2691 ChangeTitle();
2692 }
2693 break;
2694 default:
2695 /* nothing to do */;
2696 }
2697 ParseMode = ModeFirst;
2698 XsParseMode = ModeXsFirst;
2699 }
2700 else if (b == ESC) { /* Escape */
2701 PrevMode = ModeXsString;
2702 XsParseMode = ModeXsEsc;
2703 }
2704 else if (b <= US) { /* Other control character -- invalid sequence */
2705 ParseMode = ModeFirst;
2706 XsParseMode = ModeXsFirst;
2707 }
2708 else if (StrLen < sizeof(StrBuff) - 1) {
2709 StrBuff[StrLen++] = b;
2710 }
2711 break;
2712 case ModeXsColorNum:
2713 if (isdigit(b)) {
2714 ColorNumber = ColorNumber*10 + b - '0';
2715 }
2716 else if (b == ';') {
2717 XsParseMode = ModeXsColorSpec;
2718 StrBuff[0] = '\0';
2719 StrLen = 0;
2720 }
2721 else {
2722 ParseMode = ModeFirst;
2723 XsParseMode = ModeXsFirst;
2724 }
2725 break;
2726 case ModeXsColorSpec:
2727 if ((b==ST && ts.KanjiCode!=IdSJIS) || b==BEL) { /* String Terminator */
2728 StrBuff[StrLen] = '\0';
2729 if ((ts.ColorFlag & CF_XTERM256) && ColorNumber <= 255) {
2730 if (strcmp(StrBuff, "?") == 0) {
2731 color = DispGetANSIColor(ColorNumber);
2732 len =_snprintf_s_l(StrBuff, sizeof(StrBuff), _TRUNCATE,
2733 "4;%d;rgb:%02x/%02x/%02x\234", CLocale, ColorNumber,
2734 GetRValue(color), GetGValue(color), GetBValue(color));
2735 ParseMode = ModeFirst;
2736 XsParseMode = ModeXsFirst;
2737 SendOSCstr(StrBuff, len);
2738 break;
2739 }
2740 else if (XsParseColor(StrBuff, &color)) {
2741 DispSetANSIColor(ColorNumber, color);
2742 }
2743 }
2744 ParseMode = ModeFirst;
2745 XsParseMode = ModeXsFirst;
2746 }
2747 else if (b == ESC) {
2748 PrevMode = ModeXsColorSpec;
2749 XsParseMode = ModeXsEsc;
2750 }
2751 else if (b <= US) { /* Other control character -- invalid sequence */
2752 ParseMode = ModeFirst;
2753 XsParseMode = ModeXsFirst;
2754 }
2755 else if (b == ';') {
2756 if ((ts.ColorFlag & CF_XTERM256) && ColorNumber <= 255) {
2757 if (strcmp(StrBuff, "?") == 0) {
2758 color = DispGetANSIColor(ColorNumber);
2759 len =_snprintf_s_l(StrBuff, sizeof(StrBuff), _TRUNCATE,
2760 "4;%d;rgb:%02x/%02x/%02x\234", CLocale, ColorNumber,
2761 GetRValue(color), GetGValue(color), GetBValue(color));
2762 XsParseMode = ModeXsColorNum;
2763 SendOSCstr(StrBuff, len);
2764 }
2765 else if (XsParseColor(StrBuff, &color)) {
2766 DispSetANSIColor(ColorNumber, color);
2767 }
2768 }
2769 ColorNumber = 0;
2770 StrBuff[0] = '\0';
2771 StrLen = 0;
2772 XsParseMode = ModeXsColorNum;
2773 }
2774 else if (StrLen < sizeof(StrBuff) - 1) {
2775 StrBuff[StrLen++] = b;
2776 }
2777 break;
2778 case ModeXsEsc:
2779 if (b == '\\') { /* String Terminator */
2780 XsParseMode = PrevMode;
2781 // XSequence(ST);
2782 XSequence(BEL);
2783 }
2784 else { /* Other character -- invalid sequence */
2785 ParseMode = ModeFirst;
2786 XsParseMode = ModeXsFirst;
2787 }
2788 break;
2789 // default:
2790 // ParseMode = ModeFirst;
2791 // XsParseMode = ModeXsFirst;
2792 }
2793 }
2794
2795 void DLESeen(BYTE b)
2796 {
2797 ParseMode = ModeFirst;
2798 if (((ts.FTFlag & FT_BPAUTO)!=0) && (b=='B'))
2799 BPStart(IdBPAuto); /* Auto B-Plus activation */
2800 ChangeEmu = -1;
2801 }
2802
2803 void CANSeen(BYTE b)
2804 {
2805 ParseMode = ModeFirst;
2806 if (((ts.FTFlag & FT_ZAUTO)!=0) && (b=='B'))
2807 ZMODEMStart(IdZAuto); /* Auto ZMODEM activation */
2808 ChangeEmu = -1;
2809 }
2810
2811 BOOL CheckKanji(BYTE b)
2812 {
2813 BOOL Check;
2814
2815 if (ts.Language!=IdJapanese) return FALSE;
2816
2817 ConvJIS = FALSE;
2818
2819 if (ts.KanjiCode==IdSJIS)
2820 {
2821 if ((0x80<b) && (b<0xa0) || (0xdf<b) && (b<0xfd))
2822 return TRUE; // SJIS kanji
2823 if ((0xa1<=b) && (b<=0xdf))
2824 return FALSE; // SJIS katakana
2825 }
2826
2827 if ((b>=0x21) && (b<=0x7e))
2828 {
2829 Check = (Gn[Glr[0]]==IdKanji);
2830 ConvJIS = Check;
2831 }
2832 else if ((b>=0xA1) && (b<=0xFE))
2833 {
2834 Check = (Gn[Glr[1]]==IdKanji);
2835 if (ts.KanjiCode==IdEUC)
2836 Check = TRUE;
2837 else if (ts.KanjiCode==IdJIS)
2838 {
2839 if (((ts.TermFlag & TF_FIXEDJIS)!=0) &&
2840 (ts.JIS7Katakana==0))
2841 Check = FALSE; // 8-bit katakana
2842 }
2843 ConvJIS = Check;
2844 }
2845 else
2846 Check = FALSE;
2847
2848 return Check;
2849 }
2850
2851 BOOL CheckKorean(BYTE b)
2852 {
2853 BOOL Check;
2854 if (ts.Language!=IdKorean)
2855 return FALSE;
2856
2857 if (ts.KanjiCode == IdSJIS) {
2858 if ((0xA1<=b) && (b<=0xFE)) {
2859 Check = TRUE;
2860 }
2861 else {
2862 Check = FALSE;
2863 }
2864 }
2865
2866 return Check;
2867 }
2868
2869 BOOL ParseFirstJP(BYTE b)
2870 // returns TRUE if b is processed
2871 // (actually allways returns TRUE)
2872 {
2873 if (KanjiIn) {
2874 if ((! ConvJIS) && (0x3F<b) && (b<0xFD) ||
2875 ConvJIS && ( (0x20<b) && (b<0x7f) ||
2876 (0xa0<b) && (b<0xff) ))
2877 {
2878 PutKanji(b);
2879 KanjiIn = FALSE;
2880 return TRUE;
2881 }
2882 else if ((ts.TermFlag & TF_CTRLINKANJI)==0) {
2883 KanjiIn = FALSE;
2884 }
2885 else if ((b==CR) && Wrap) {
2886 CarriageReturn(FALSE);
2887 LineFeed(LF,FALSE);
2888 Wrap = FALSE;
2889 }
2890 }
2891
2892 if (SSflag) {
2893 if (Gn[GLtmp] == IdKanji) {
2894 Kanji = b << 8;
2895 KanjiIn = TRUE;
2896 SSflag = FALSE;
2897 return TRUE;
2898 }
2899 else if (Gn[GLtmp] == IdKatakana) {
2900 b = b | 0x80;
2901 }
2902
2903 PutChar(b);
2904 SSflag = FALSE;
2905 return TRUE;
2906 }
2907
2908 if ((!EUCsupIn) && (!EUCkanaIn) && (!KanjiIn) && CheckKanji(b)) {
2909 Kanji = b << 8;
2910 KanjiIn = TRUE;
2911 return TRUE;
2912 }
2913
2914 if (b<=US) {
2915 ParseControl(b);
2916 }
2917 else if (b==0x20) {
2918 PutChar(b);
2919 }
2920 else if ((b>=0x21) && (b<=0x7E)) {
2921 if (EUCsupIn) {
2922 EUCcount--;
2923 EUCsupIn = (EUCcount==0);
2924 return TRUE;
2925 }
2926
2927 if ((Gn[Glr[0]] == IdKatakana) || EUCkanaIn) {
2928 b = b | 0x80;
2929 EUCkanaIn = FALSE;
2930 }
2931 PutChar(b);
2932 }
2933 else if (b==0x7f) {
2934 return TRUE;
2935 }
2936 else if ((b>=0x80) && (b<=0x8D)) {
2937 ParseControl(b);
2938 }
2939 else if (b==0x8E) { // SS2
2940 if (ts.KanjiCode==IdEUC) {
2941 EUCkanaIn = TRUE;
2942 }
2943 else {
2944 ParseControl(b);
2945 }
2946 }
2947 else if (b==0x8F) { // SS3
2948 if (ts.KanjiCode==IdEUC) {
2949 EUCcount = 2;
2950 EUCsupIn = TRUE;
2951 }
2952 else {
2953 ParseControl(b);
2954 }
2955 }
2956 else if ((b>=0x90) && (b<=0x9F)) {
2957 ParseControl(b);
2958 }
2959 else if (b==0xA0) {
2960 PutChar(0x20);
2961 }
2962 else if ((b>=0xA1) && (b<=0xFE)) {
2963 if (EUCsupIn) {
2964 EUCcount--;
2965 EUCsupIn = (EUCcount==0);
2966 return TRUE;
2967 }
2968
2969 if ((Gn[Glr[1]] != IdASCII) ||
2970 (ts.KanjiCode==IdEUC) && EUCkanaIn ||
2971 (ts.KanjiCode==IdSJIS) ||
2972 (ts.KanjiCode==IdJIS) &&
2973 (ts.JIS7Katakana==0) &&
2974 ((ts.TermFlag & TF_FIXEDJIS)!=0))
2975 PutChar(b); // katakana
2976 else {
2977 if (Gn[Glr[1]] == IdASCII) {
2978 b = b & 0x7f;
2979 }
2980 PutChar(b);
2981 }
2982 EUCkanaIn = FALSE;
2983 }
2984 else {
2985 PutChar(b);
2986 }
2987
2988 return TRUE;
2989 }
2990
2991 BOOL ParseFirstKR(BYTE b)
2992 // returns TRUE if b is processed
2993 // (actually allways returns TRUE)
2994 {
2995 if (KanjiIn) {
2996 if ((0x41<=b) && (b<=0x5A) ||
2997 (0x61<=b) && (b<=0x7A) ||
2998 (0x81<=b) && (b<=0xFE))
2999 {
3000 PutKanji(b);
3001 KanjiIn = FALSE;
3002 return TRUE;
3003 }
3004 else if ((ts.TermFlag & TF_CTRLINKANJI)==0) {
3005 KanjiIn = FALSE;
3006 }
3007 else if ((b==CR) && Wrap) {
3008 CarriageReturn(FALSE);
3009 LineFeed(LF,FALSE);
3010 Wrap = FALSE;
3011 }
3012 }
3013
3014 if ((!KanjiIn) && CheckKorean(b)) {
3015 Kanji = b << 8;
3016 KanjiIn = TRUE;
3017 return TRUE;
3018 }
3019
3020 if (b<=US) {
3021 ParseControl(b);
3022 }
3023 else if (b==0x20) {
3024 PutChar(b);
3025 }
3026 else if ((b>=0x21) && (b<=0x7E)) {
3027 // if (Gn[Glr[0]] == IdKatakana) {
3028 // b = b | 0x80;
3029 // }
3030 PutChar(b);
3031 }
3032 else if (b==0x7f) {
3033 return TRUE;
3034 }
3035 else if ((0x80<=b) && (b<=0x9F)) {
3036 ParseControl(b);
3037 }
3038 else if (b==0xA0) {
3039 PutChar(0x20);
3040 }
3041 else if ((b>=0xA1) && (b<=0xFE)) {
3042 if (Gn[Glr[1]] == IdASCII) {
3043 b = b & 0x7f;
3044 }
3045 PutChar(b);
3046 }
3047 else {
3048 PutChar(b);
3049 }
3050
3051 return TRUE;
3052 }
3053
3054 static void ParseASCII(BYTE b)
3055 {
3056 if (SSflag) {
3057 PutChar(b);
3058 SSflag = FALSE;
3059 return;
3060 }
3061
3062 if (b<=US) {
3063 ParseControl(b);
3064 } else if ((b>=0x20) && (b<=0x7E)) {
3065 //Kanji = 0;
3066 //PutKanji(b);
3067 PutChar(b);
3068 } else if ((b>=0x80) && (b<=0x9F)) {
3069 ParseControl(b);
3070 } else if (b>=0xA0) {
3071 //Kanji = 0;
3072 //PutKanji(b);
3073 PutChar(b);
3074 }
3075 }
3076
3077 //
3078 // UTF-8
3079 //
3080 #include "uni2sjis.map"
3081 #include "unisym2decsp.map"
3082 extern unsigned short ConvertUnicode(unsigned short code, codemap_t *table, int tmax);
3083
3084
3085 //
3086 // UTF-8 for Mac OS X(HFS plus)
3087 //
3088 #include "hfs_plus.map"
3089
3090 unsigned short GetIllegalUnicode(int start_index, unsigned short first_code, unsigned short code,
3091 hfsplus_codemap_t *table, int tmax)
3092 {
3093 unsigned short result = 0;
3094 int i;
3095
3096 for (i = start_index ; i < tmax ; i++) {
3097 if (table[i].first_code != first_code) { // 1�������������������A���~���������������������B
3098 break;
3099 }
3100
3101 if (table[i].second_code == code) {
3102 result = table[i].illegal_code;
3103 break;
3104 }
3105 }
3106
3107 return (result);
3108 }
3109
3110 int GetIndexOfHFSPlusFirstCode(unsigned short code, hfsplus_codemap_t *table, int tmax)
3111 {
3112 int low, mid, high;
3113 int index = -1;
3114
3115 low = 0;
3116 high = tmax - 1;
3117
3118 // binary search
3119 while (low < high) {
3120 mid = (low + high) / 2;
3121 if (table[mid].first_code < code) {
3122 low = mid + 1;
3123 } else {
3124 high = mid;
3125 }
3126 }
3127
3128 if (table[low].first_code == code) {
3129 while (low >= 0 && table[low].first_code == code) {
3130 index = low;
3131 low--;
3132 }
3133 }
3134
3135 return (index);
3136 }
3137
3138
3139 static void UnicodeToCP932(unsigned int code)
3140 {
3141 int ret;
3142 char mbchar[32];
3143 unsigned char wchar[32];
3144 unsigned short cset = 0;
3145
3146 #if 0
3147 Kanji = code & 0xff00;
3148 PutKanji(code & 0x00ff);
3149 return;
3150 #else
3151
3152 wchar[0] = code & 0xff;
3153 wchar[1] = (code >> 8) & 0xff;
3154
3155 if (ts.UnicodeDecSpMapping) {
3156 cset = ConvertUnicode(code, mapUnicodeSymbolToDecSp, MAPSIZE(mapUnicodeSymbolToDecSp));
3157 }
3158 if (((cset >> 8) & ts.UnicodeDecSpMapping) != 0) {
3159 PutDecSp(cset & 0xff);
3160 }
3161 else {
3162 // Unicode -> CP932
3163 ret = wctomb(mbchar, ((wchar_t *)wchar)[0]);
3164 switch (ret) {
3165 case -1:
3166 if (_stricmp(ts.Locale, DEFAULT_LOCALE) == 0) {
3167 // U+301C�������������������BUnicode -> Shift_JIS���������������B
3168 cset = ConvertUnicode(code, mapUnicodeToSJIS, MAPSIZE(mapUnicodeToSJIS));
3169 if (cset != 0) {
3170 Kanji = cset & 0xff00;
3171 PutKanji(cset & 0x00ff);
3172 }
3173 }
3174
3175 if (cset == 0) {
3176 PutChar('?');
3177 if (ts.UnknownUnicodeCharaAsWide) {
3178 PutChar('?');
3179 }
3180 }
3181 break;
3182 case 1:
3183 PutChar(mbchar[0]);
3184 break;
3185 default:
3186 Kanji = mbchar[0] << 8;
3187 PutKanji(mbchar[1]);
3188 break;
3189 }
3190 }
3191 #endif
3192 }
3193
3194 // UTF-8�����M�f�[�^����������
3195 BOOL ParseFirstUTF8(BYTE b, int hfsplus_mode)
3196 // returns TRUE if b is processed
3197 // (actually allways returns TRUE)
3198 {
3199 static BYTE buf[3];
3200 static int count = 0;
3201 static int maybe_hfsplus = 0;
3202 static unsigned int first_code;
3203 static int first_code_index;
3204
3205 unsigned int code;
3206 char mbchar[32];
3207 unsigned short cset;
3208 char *locptr;
3209
3210 locptr = setlocale(LC_ALL, ts.Locale);
3211
3212 if ((b & 0x80) != 0x80 || ((b & 0xe0) == 0x80 && count == 0)) {
3213 // 1�o�C�g��������2�o�C�g����ASCII���������A������ASCII�o���������B
3214 // 1�o�C�g����C1��������(0x80-0x9f)�����������l�B
3215 if (count == 0 || count == 1) {
3216 if (hfsplus_mode == 1 && maybe_hfsplus == 1) {
3217 UnicodeToCP932(first_code);
3218 maybe_hfsplus = 0;
3219 }
3220
3221 if (count == 1) {
3222 ParseASCII(buf[0]);
3223 }
3224 ParseASCII(b);
3225
3226 count = 0; // reset counter
3227 return TRUE;
3228 }
3229 }
3230
3231 buf[count++] = b;
3232 if (count < 2) {
3233 return TRUE;
3234 }
3235
3236 memset(mbchar, 0, sizeof(mbchar));
3237
3238 // 2�o�C�g�R�[�h������
3239 if ((buf[0] & 0xe0) == 0xc0) {
3240 if ((buf[1] & 0xc0) == 0x80) {
3241
3242 if (hfsplus_mode == 1 && maybe_hfsplus == 1) {
3243 UnicodeToCP932(first_code);
3244 maybe_hfsplus = 0;
3245 }
3246
3247 code = ((buf[0] & 0x1f) << 6);
3248 code |= ((buf[1] & 0x3f));
3249
3250 UnicodeToCP932(code);
3251 }
3252 else {
3253 ParseASCII(buf[0]);
3254 ParseASCII(buf[1]);
3255 }
3256 count = 0;
3257 return TRUE;
3258 }
3259
3260 if (count < 3) {
3261 return TRUE;
3262 }
3263
3264 if ((buf[0] & 0xe0) == 0xe0 &&
3265 (buf[1] & 0xc0) == 0x80 &&
3266 (buf[2] & 0xc0) == 0x80) { // 3�o�C�g�R�[�h������
3267
3268 // UTF-8 BOM(Byte Order Mark)
3269 if (buf[0] == 0xef && buf[1] == 0xbb && buf[2] == 0xbf) {
3270 goto skip;
3271 }
3272
3273 code = ((buf[0] & 0xf) << 12);
3274 code |= ((buf[1] & 0x3f) << 6);
3275 code |= ((buf[2] & 0x3f));
3276
3277 if (hfsplus_mode == 1) {
3278 if (maybe_hfsplus == 0) {
3279 if ((first_code_index = GetIndexOfHFSPlusFirstCode(
3280 code, mapHFSPlusUnicode, MAPSIZE(mapHFSPlusUnicode)
3281 )) != -1) {
3282 maybe_hfsplus = 1;
3283 first_code = code;
3284 count = 0;
3285 return (TRUE);
3286 }
3287 } else {
3288 maybe_hfsplus = 0;
3289 cset = GetIllegalUnicode(first_code_index, first_code, code, mapHFSPlusUnicode, MAPSIZE(mapHFSPlusUnicode));
3290 if (cset != 0) { // success
3291 code = cset;
3292
3293 } else { // error
3294 // 2�����������������_��1�����������������������A���x�������������B(2005.10.15 yutaka)
3295 if ((first_code_index = GetIndexOfHFSPlusFirstCode(
3296 code, mapHFSPlusUnicode, MAPSIZE(mapHFSPlusUnicode)
3297 )) != -1) {
3298
3299 // 1���������������������o������
3300 UnicodeToCP932(first_code);
3301
3302 maybe_hfsplus = 1;
3303 first_code = code;
3304 count = 0;
3305 return (TRUE);
3306 }
3307
3308 UnicodeToCP932(first_code);
3309 UnicodeToCP932(code);
3310 count = 0;
3311 return (TRUE);
3312 }
3313 }
3314 }
3315
3316 UnicodeToCP932(code);
3317
3318 skip:
3319 count = 0;
3320
3321 } else {
3322 ParseASCII(buf[0]);
3323 ParseASCII(buf[1]);
3324 ParseASCII(buf[2]);
3325 count = 0;
3326
3327 }
3328
3329 return TRUE;
3330 }
3331
3332
3333 BOOL ParseFirstRus(BYTE b)
3334 // returns if b is processed
3335 {
3336 if (b>=128)
3337 {
3338 b = RussConv(ts.RussHost,ts.RussClient,b);
3339 PutChar(b);
3340 return TRUE;
3341 }
3342 return FALSE;
3343 }
3344
3345 void ParseFirst(BYTE b)
3346 {
3347 switch (ts.Language) {
3348 case IdUtf8:
3349 ParseFirstUTF8(b, ts.KanjiCode == IdUTF8m);
3350 return;
3351
3352 case IdJapanese:
3353 switch (ts.KanjiCode) {
3354 case IdUTF8:
3355 if (ParseFirstUTF8(b, 0)) {
3356 return;
3357