Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7088 - (hide annotations) (download) (as text)
Mon Apr 2 09:07:41 2018 UTC (6 years ago) by doda
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 136266 byte(s)
DECSACE の状態を DECRQSS で取れるようにした。
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3     * (C) 2004-2017 TeraTerm Project
4     * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3227
30     /* TERATERM.EXE, VT terminal emulation */
31     #include "teraterm.h"
32     #include "tttypes.h"
33     #include <stdio.h>
34     #include <string.h>
35     #include <stdlib.h>
36     #include <mbstring.h>
37     #include <locale.h>
38 doda 4225 #include <ctype.h>
39 maya 3227
40     #include "buffer.h"
41     #include "ttwinman.h"
42     #include "ttcommon.h"
43     #include "commlib.h"
44     #include "vtdisp.h"
45     #include "keyboard.h"
46     #include "ttlib.h"
47     #include "ttftypes.h"
48     #include "filesys.h"
49     #include "teraprn.h"
50     #include "telnet.h"
51 doda 4278 #include "ttime.h"
52 doda 4769 #include "clipboar.h"
53 maya 3227
54     #include "vtterm.h"
55    
56 doda 4256 void ParseFirst(BYTE b);
57    
58 doda 3443 #define MAPSIZE(x) (sizeof(x)/sizeof((x)[0]))
59 doda 4246 #define Accept8BitCtrl ((VTlevel >= 2) && (ts.TermFlag & TF_ACCEPT8BITCTRL))
60 doda 3443
61 maya 3227 /* Parsing modes */
62     #define ModeFirst 0
63     #define ModeESC 1
64     #define ModeDCS 2
65     #define ModeDCUserKey 3
66     #define ModeSOS 4
67     #define ModeCSI 5
68     #define ModeXS 6
69     #define ModeDLE 7
70     #define ModeCAN 8
71 doda 5911 #define ModeIgnore 9
72 maya 3227
73 doda 5073 #define NParamMax 16
74     #define NSParamMax 16
75     #define IntCharMax 5
76 maya 3227
77 doda 3997 /* DEC Locator Flag */
78     #define DecLocatorOneShot 1
79     #define DecLocatorPixel 2
80     #define DecLocatorButtonDown 4
81     #define DecLocatorButtonUp 8
82     #define DecLocatorFiltered 16
83    
84 doda 5316 void RingBell(int type);
85 maya 3227 void VisualBell();
86 doda 3999 BOOL DecLocatorReport(int Event, int Button);
87 maya 3227
88     /* character attribute */
89     static TCharAttr CharAttr;
90    
91     /* various modes of VT emulation */
92     static BOOL RelativeOrgMode;
93     static BOOL InsertMode;
94     static BOOL LFMode;
95 doda 5564 static BOOL ClearThenHome;
96 maya 3227 static BOOL AutoWrapMode;
97     static BOOL FocusReportMode;
98 doda 3743 static BOOL AltScr;
99 doda 5324 static BOOL LRMarginMode;
100 doda 7086 static BOOL RectangleMode;
101 doda 3872 BOOL BracketedPaste;
102 maya 3227
103 doda 4246 static int VTlevel;
104    
105 doda 4293 BOOL AcceptWheelToCursor;
106    
107 maya 3227 // save/restore cursor
108     typedef struct {
109 doda 6802 int CursorX, CursorY;
110     TCharAttr Attr;
111     int Glr[2], Gn[4]; // G0-G3, GL & GR
112     BOOL AutoWrapMode;
113     BOOL RelativeOrgMode;
114 maya 3227 } TStatusBuff;
115     typedef TStatusBuff *PStatusBuff;
116    
117 maya 4893 // currently only used for AUTO CR/LF receive mode
118     BYTE PrevCharacter;
119     BOOL PrevCRorLFGeneratedCRLF; // indicates that previous CR or LF really generated a CR+LF
120    
121 maya 3227 // status buffer for main screen & status line
122 doda 3797 static TStatusBuff SBuff1, SBuff2, SBuff3;
123 maya 3227
124     static BOOL ESCFlag, JustAfterESC;
125     static BOOL KanjiIn;
126     static BOOL EUCkanaIn, EUCsupIn;
127     static int EUCcount;
128     static BOOL Special;
129    
130     static int Param[NParamMax+1];
131 doda 5073 static int SubParam[NParamMax+1][NSParamMax+1];
132     static int NParam, NSParam[NParamMax+1];
133 maya 3227 static BOOL FirstPrm;
134     static BYTE IntChar[IntCharMax+1];
135     static int ICount;
136     static BYTE Prv;
137 doda 4291 static int ParseMode;
138 maya 3227 static int ChangeEmu;
139    
140 doda 5096 typedef struct tstack {
141 doda 6802 char *title;
142     struct tstack *next;
143 doda 5096 } TStack;
144     typedef TStack *PTStack;
145     PTStack TitleStack = NULL;
146    
147 maya 3227 /* user defined keys */
148     static BOOL WaitKeyId, WaitHi;
149    
150     /* GL, GR code group */
151     static int Glr[2];
152     /* G0, G1, G2, G3 code group */
153     static int Gn[4];
154     /* GL for single shift 2/3 */
155     static int GLtmp;
156     /* single shift 2/3 flag */
157     static BOOL SSflag;
158     /* JIS -> SJIS conversion flag */
159     static BOOL ConvJIS;
160     static WORD Kanji;
161 doda 6602 static BOOL Fallbacked;
162 maya 3227
163     // variables for status line mode
164     static int StatusX=0;
165     static BOOL StatusWrap=FALSE;
166     static BOOL StatusCursor=TRUE;
167     static int MainX, MainY; //cursor registers
168     static int MainTop, MainBottom; // scroll region registers
169     static BOOL MainWrap;
170     static BOOL MainCursor=TRUE;
171    
172     /* status for printer escape sequences */
173 doda 6802 static BOOL PrintEX = TRUE; // printing extent
174 maya 3227 // (TRUE: screen, FALSE: scroll region)
175     static BOOL AutoPrintMode = FALSE;
176     static BOOL PrinterMode = FALSE;
177     static BOOL DirectPrn = FALSE;
178    
179     /* User key */
180     static BYTE NewKeyStr[FuncKeyStrMax];
181     static int NewKeyId, NewKeyLen;
182    
183 doda 3997 /* Mouse Report */
184     int MouseReportMode;
185 doda 4813 int MouseReportExtMode;
186 doda 3997 unsigned int DecLocatorFlag;
187     int LastX, LastY;
188     int ButtonStat;
189 doda 3999 int FilterTop, FilterBottom, FilterLeft, FilterRight;
190 doda 3997
191 doda 4278 /* IME Status */
192     BOOL IMEstat;
193    
194 doda 5316 /* Beep over-used */
195     static DWORD BeepStartTime = 0;
196     static DWORD BeepSuppressTime = 0;
197     static DWORD BeepOverUsedCount = 0;
198    
199 doda 3450 static _locale_t CLocale = NULL;
200 maya 3227
201 doda 5073 void ClearParams()
202     {
203 doda 6802 ICount = 0;
204     NParam = 1;
205     NSParam[1] = 0;
206     Param[1] = 0;
207     Prv = 0;
208 doda 5073 }
209    
210 doda 3916 void ResetSBuffer(PStatusBuff sbuff)
211 maya 3227 {
212 doda 6802 sbuff->CursorX = 0;
213     sbuff->CursorY = 0;
214     sbuff->Attr = DefCharAttr;
215     if (ts.Language==IdJapanese) {
216     sbuff->Gn[0] = IdASCII;
217     sbuff->Gn[1] = IdKatakana;
218     sbuff->Gn[2] = IdKatakana;
219     sbuff->Gn[3] = IdKanji;
220     sbuff->Glr[0] = 0;
221     if ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0))
222     sbuff->Glr[1] = 2; // 8-bit katakana
223     else
224     sbuff->Glr[1] = 3;
225     }
226     else {
227     sbuff->Gn[0] = IdASCII;
228     sbuff->Gn[1] = IdSpecial;
229     sbuff->Gn[2] = IdASCII;
230     sbuff->Gn[3] = IdASCII;
231     sbuff->Glr[0] = 0;
232     sbuff->Glr[1] = 0;
233     }
234     sbuff->AutoWrapMode = TRUE;
235     sbuff->RelativeOrgMode = FALSE;
236 doda 3916 }
237    
238     void ResetAllSBuffers()
239     {
240 doda 6802 ResetSBuffer(&SBuff1);
241     // copy SBuff1 to SBuff2
242     SBuff2 = SBuff1;
243     SBuff3 = SBuff1;
244 maya 3227 }
245    
246 doda 3916 void ResetCurSBuffer()
247     {
248 doda 6802 PStatusBuff Buff;
249 doda 3916
250 doda 6802 if (AltScr) {
251     Buff = &SBuff3; // Alternate screen buffer
252     }
253     else {
254     Buff = &SBuff1; // Normal screen buffer
255     }
256     ResetSBuffer(Buff);
257     SBuff2 = *Buff;
258 doda 3916 }
259    
260 maya 3227 void ResetTerminal() /*reset variables but don't update screen */
261     {
262 doda 6802 DispReset();
263     BuffReset();
264 maya 3227
265 doda 6802 /* Attribute */
266     CharAttr = DefCharAttr;
267     Special = FALSE;
268     BuffSetCurCharAttr(CharAttr);
269 maya 3227
270 doda 6802 /* Various modes */
271     InsertMode = FALSE;
272     LFMode = (ts.CRSend == IdCRLF);
273     AutoWrapMode = TRUE;
274     AppliKeyMode = FALSE;
275     AppliCursorMode = FALSE;
276     AppliEscapeMode = FALSE;
277     AcceptWheelToCursor = ts.TranslateWheelToCursor;
278     RelativeOrgMode = FALSE;
279     ts.ColorFlag &= ~CF_REVERSEVIDEO;
280     AutoRepeatMode = TRUE;
281     FocusReportMode = FALSE;
282     MouseReportMode = IdMouseTrackNone;
283     MouseReportExtMode = IdMouseTrackExtNone;
284     DecLocatorFlag = 0;
285     ClearThenHome = FALSE;
286 doda 7086 RectangleMode = FALSE;
287 maya 3227
288 doda 6802 ChangeTerminalID();
289 doda 4246
290 doda 6802 LastX = 0;
291     LastY = 0;
292     ButtonStat = 0;
293 doda 3997
294 doda 6802 if (CLocale == NULL) {
295     CLocale = _create_locale(LC_ALL, "C");
296     }
297 maya 3227
298 doda 6802 /* Character sets */
299     ResetCharSet();
300 maya 3227
301 doda 6802 /* ESC flag for device control sequence */
302     ESCFlag = FALSE;
303     /* for TEK sequence */
304     JustAfterESC = FALSE;
305 maya 3227
306 doda 6802 /* Parse mode */
307     ParseMode = ModeFirst;
308 maya 3227
309 doda 6802 /* Clear printer mode */
310     PrinterMode = FALSE;
311 maya 3227
312 doda 6802 // status buffers
313     ResetAllSBuffers();
314 doda 3745
315 doda 6802 // Alternate Screen Buffer
316     AltScr = FALSE;
317 doda 3872
318 doda 6802 // Left/Right Margin Mode
319     LRMarginMode = FALSE;
320 doda 5324
321 doda 6802 // Bracketed Paste Mode
322     BracketedPaste = FALSE;
323 doda 4278
324 doda 6802 // Saved IME Status
325     IMEstat = FALSE;
326 maya 4893
327 doda 6802 // previous received character
328     PrevCharacter = -1; // none
329     PrevCRorLFGeneratedCRLF = FALSE;
330 doda 5316
331 doda 6802 // Beep over-used
332     BeepStartTime = GetTickCount();
333     BeepSuppressTime = BeepStartTime - ts.BeepSuppressTime * 1000;
334     BeepStartTime -= (ts.BeepOverUsedTime * 1000);
335     BeepOverUsedCount = ts.BeepOverUsedCount;
336 maya 3227 }
337    
338     void ResetCharSet()
339     {
340 doda 6802 if (ts.Language==IdJapanese) {
341     Gn[0] = IdASCII;
342     Gn[1] = IdKatakana;
343     Gn[2] = IdKatakana;
344     Gn[3] = IdKanji;
345     Glr[0] = 0;
346     if ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0))
347     Glr[1] = 2; // 8-bit katakana
348     else
349     Glr[1] = 3;
350     }
351     else {
352     Gn[0] = IdASCII;
353     Gn[1] = IdSpecial;
354     Gn[2] = IdASCII;
355     Gn[3] = IdASCII;
356     Glr[0] = 0;
357     Glr[1] = 0;
358     cv.SendCode = IdASCII;
359     cv.SendKanjiFlag = FALSE;
360     cv.EchoCode = IdASCII;
361     cv.EchoKanjiFlag = FALSE;
362     }
363     /* Kanji flag */
364     KanjiIn = FALSE;
365     EUCkanaIn = FALSE;
366     EUCsupIn = FALSE;
367     SSflag = FALSE;
368     ConvJIS = FALSE;
369     Fallbacked = FALSE;
370 maya 3227
371 doda 6802 cv.Language = ts.Language;
372     cv.CRSend = ts.CRSend;
373     cv.KanjiCodeEcho = ts.KanjiCode;
374     cv.JIS7KatakanaEcho = ts.JIS7Katakana;
375     cv.KanjiCodeSend = ts.KanjiCodeSend;
376     cv.JIS7KatakanaSend = ts.JIS7KatakanaSend;
377     cv.KanjiIn = ts.KanjiIn;
378     cv.KanjiOut = ts.KanjiOut;
379 maya 3227 }
380    
381     void ResetKeypadMode(BOOL DisabledModeOnly)
382     {
383 doda 6802 if (!DisabledModeOnly || ts.DisableAppKeypad)
384     AppliKeyMode = FALSE;
385     if (!DisabledModeOnly || ts.DisableAppCursor)
386     AppliCursorMode = FALSE;
387 maya 3227 }
388    
389     void MoveToMainScreen()
390     {
391 doda 6802 StatusX = CursorX;
392     StatusWrap = Wrap;
393     StatusCursor = IsCaretEnabled();
394 maya 3227
395 doda 6802 CursorTop = MainTop;
396     CursorBottom = MainBottom;
397     Wrap = MainWrap;
398     DispEnableCaret(MainCursor);
399     MoveCursor(MainX, MainY); // move to main screen
400 maya 3227 }
401    
402     void MoveToStatusLine()
403     {
404 doda 6802 MainX = CursorX;
405     MainY = CursorY;
406     MainTop = CursorTop;
407     MainBottom = CursorBottom;
408     MainWrap = Wrap;
409     MainCursor = IsCaretEnabled();
410 maya 3227
411 doda 6802 DispEnableCaret(StatusCursor);
412     MoveCursor(StatusX, NumOfLines-1); // move to status line
413     CursorTop = NumOfLines-1;
414     CursorBottom = CursorTop;
415     Wrap = StatusWrap;
416 maya 3227 }
417    
418     void HideStatusLine()
419     {
420 doda 6802 if (isCursorOnStatusLine)
421     MoveToMainScreen();
422     StatusX = 0;
423     StatusWrap = FALSE;
424     StatusCursor = TRUE;
425     ShowStatusLine(0); //hide
426 maya 3227 }
427    
428     void ChangeTerminalSize(int Nx, int Ny)
429     {
430 doda 6802 BuffChangeTerminalSize(Nx, Ny);
431     StatusX = 0;
432     MainX = 0;
433     MainY = 0;
434     MainTop = 0;
435 doda 7045 MainBottom = NumOfLines-StatusLine-1;
436 doda 6802 LRMarginMode = FALSE;
437 maya 3227 }
438    
439 doda 3471 void SendCSIstr(char *str, int len) {
440 doda 4024 int l;
441    
442     if (str == NULL || len < 0)
443 doda 3471 return;
444    
445 doda 4024 if (len == 0) {
446     l = strlen(str);
447     }
448     else {
449     l = len;
450     }
451    
452 doda 3471 if (Send8BitMode)
453     CommBinaryOut(&cv,"\233", 1);
454     else
455     CommBinaryOut(&cv,"\033[", 2);
456    
457 doda 4024 CommBinaryOut(&cv, str, l);
458 doda 3471 }
459    
460 doda 5911 void SendOSCstr(char *str, int len, char TermChar) {
461 doda 4024 int l;
462    
463 doda 4104 if (str == NULL || len < 0)
464 doda 3471 return;
465    
466 doda 4024 if (len == 0) {
467     l = strlen(str);
468     }
469     else {
470     l = len;
471     }
472    
473 doda 5911 if (TermChar == BEL) {
474     CommBinaryOut(&cv,"\033]", 2);
475     CommBinaryOut(&cv, str, l);
476     CommBinaryOut(&cv,"\007", 1);
477     }
478     else if (Send8BitMode) {
479 doda 3471 CommBinaryOut(&cv,"\235", 1);
480 doda 4024 CommBinaryOut(&cv, str, l);
481 doda 3486 CommBinaryOut(&cv,"\234", 1);
482     }
483     else {
484 doda 3471 CommBinaryOut(&cv,"\033]", 2);
485 doda 4024 CommBinaryOut(&cv, str, l);
486 doda 3486 CommBinaryOut(&cv,"\033\\", 2);
487     }
488 doda 3471
489     }
490    
491 doda 4162 void SendDCSstr(char *str, int len) {
492     int l;
493    
494     if (str == NULL || len < 0)
495     return;
496    
497     if (len == 0) {
498     l = strlen(str);
499     }
500     else {
501     l = len;
502     }
503    
504     if (Send8BitMode) {
505     CommBinaryOut(&cv,"\220", 1);
506     CommBinaryOut(&cv, str, l);
507     CommBinaryOut(&cv,"\234", 1);
508     }
509     else {
510     CommBinaryOut(&cv,"\033P", 2);
511     CommBinaryOut(&cv, str, l);
512     CommBinaryOut(&cv,"\033\\", 2);
513     }
514    
515     }
516    
517 maya 3227 void BackSpace()
518     {
519 doda 5324 if (CursorX == CursorLeftM || CursorX == 0) {
520     if (CursorY > 0 && (ts.TermFlag & TF_BACKWRAP)) {
521     MoveCursor(CursorRightM, CursorY-1);
522     if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
523     }
524     }
525     else if (CursorX > 0) {
526     MoveCursor(CursorX-1, CursorY);
527     if (cv.HLogBuf!=0 && !ts.LogTypePlainText) Log1Byte(BS);
528     }
529 maya 3227 }
530    
531     void CarriageReturn(BOOL logFlag)
532     {
533     if (!ts.EnableContinuedLineCopy || logFlag)
534 doda 6803 if (cv.HLogBuf!=0) Log1Byte(CR);
535 maya 3227
536 doda 5324 if (RelativeOrgMode || CursorX > CursorLeftM)
537     MoveCursor(CursorLeftM, CursorY);
538     else if (CursorX < CursorLeftM)
539     MoveCursor(0, CursorY);
540 doda 6602
541     Fallbacked = FALSE;
542 maya 3227 }
543    
544     void LineFeed(BYTE b, BOOL logFlag)
545     {
546     /* for auto print mode */
547     if ((AutoPrintMode) &&
548     (b>=LF) && (b<=FF))
549     BuffDumpCurrentLine(b);
550    
551     if (!ts.EnableContinuedLineCopy || logFlag)
552 doda 6803 if (cv.HLogBuf!=0) Log1Byte(LF);
553 maya 3227
554     if (CursorY < CursorBottom)
555     MoveCursor(CursorX,CursorY+1);
556     else if (CursorY == CursorBottom) BuffScrollNLines(1);
557     else if (CursorY < NumOfLines-StatusLine-1)
558     MoveCursor(CursorX,CursorY+1);
559    
560 doda 3312 ClearLineContinued();
561    
562 maya 3227 if (LFMode) CarriageReturn(logFlag);
563 doda 6602
564     Fallbacked = FALSE;
565 maya 3227 }
566    
567     void Tab()
568     {
569 doda 6802 if (Wrap && !ts.VTCompatTab) {
570     CarriageReturn(FALSE);
571     LineFeed(LF,FALSE);
572     if (ts.EnableContinuedLineCopy) {
573     SetLineContinued();
574     }
575     Wrap = FALSE;
576     }
577     CursorForwardTab(1, AutoWrapMode);
578     if (cv.HLogBuf!=0) Log1Byte(HT);
579 maya 3227 }
580    
581     void PutChar(BYTE b)
582     {
583 doda 6802 BOOL SpecialNew;
584     TCharAttr CharAttrTmp;
585 maya 3227
586 doda 6802 CharAttrTmp = CharAttr;
587 maya 3227
588 doda 6802 if (PrinterMode) { // printer mode
589     WriteToPrnFile(b,TRUE);
590     return;
591     }
592 maya 3227
593 doda 6802 if (Wrap) {
594     CarriageReturn(FALSE);
595     LineFeed(LF,FALSE);
596     CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
597     }
598 maya 3227
599 doda 6802 // if (cv.HLogBuf!=0) Log1Byte(b);
600 maya 3227 // (2005.2.20 yutaka)
601 doda 6802 if (ts.LogTypePlainText) {
602     if (__isascii(b) && !isprint(b)) {
603     // ASCII�������A���\�������������O�����������B
604     } else {
605     if (cv.HLogBuf!=0) Log1Byte(b);
606     }
607     } else {
608 maya 3227 if (cv.HLogBuf!=0) Log1Byte(b);
609 doda 6802 }
610 maya 3227
611 doda 6802 Wrap = FALSE;
612 maya 3227
613 doda 6802 SpecialNew = FALSE;
614     if ((b>0x5F) && (b<0x80)) {
615     if (SSflag)
616     SpecialNew = (Gn[GLtmp]==IdSpecial);
617     else
618     SpecialNew = (Gn[Glr[0]]==IdSpecial);
619     }
620     else if (b>0xDF) {
621     if (SSflag)
622     SpecialNew = (Gn[GLtmp]==IdSpecial);
623     else
624     SpecialNew = (Gn[Glr[1]]==IdSpecial);
625     }
626 maya 3227
627 doda 6802 if (SpecialNew != Special) {
628     UpdateStr();
629     Special = SpecialNew;
630     }
631 maya 3227
632 doda 6802 if (Special) {
633     b = b & 0x7F;
634     CharAttrTmp.Attr |= AttrSpecial;
635     }
636     else
637     CharAttrTmp.Attr |= CharAttr.Attr;
638 maya 3227
639 doda 6802 BuffPutChar(b, CharAttrTmp, InsertMode);
640 maya 3227
641 doda 6802 if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) {
642     UpdateStr();
643     Wrap = AutoWrapMode;
644     }
645     else {
646     MoveRight();
647     }
648 maya 3227 }
649    
650     void PutDecSp(BYTE b)
651     {
652 doda 6802 TCharAttr CharAttrTmp;
653 maya 3227
654 doda 6802 CharAttrTmp = CharAttr;
655 maya 3227
656 doda 6802 if (PrinterMode) { // printer mode
657     WriteToPrnFile(b, TRUE);
658     return;
659     }
660 maya 3227
661 doda 6802 if (Wrap) {
662     CarriageReturn(FALSE);
663     LineFeed(LF, FALSE);
664     CharAttrTmp.Attr |= ts.EnableContinuedLineCopy ? AttrLineContinued : 0;
665     }
666 maya 3227
667 doda 6802 if (cv.HLogBuf!=0) Log1Byte(b);
668 maya 3227 /*
669 doda 6802 if (ts.LogTypePlainText && __isascii(b) && !isprint(b)) {
670     // ASCII�������A���\�������������O�����������B
671     } else {
672     if (cv.HLogBuf!=0) Log1Byte(b);
673     }
674 maya 3227 */
675    
676 doda 6802 Wrap = FALSE;
677 maya 3227
678 doda 6802 if (!Special) {
679     UpdateStr();
680     Special = TRUE;
681     }
682 maya 3227
683 doda 6802 CharAttrTmp.Attr |= AttrSpecial;
684     BuffPutChar(b, CharAttrTmp, InsertMode);
685 maya 3227
686 doda 6802 if (CursorX == CursorRightM || CursorX >= NumOfColumns-1) {
687     UpdateStr();
688     Wrap = AutoWrapMode;
689     }
690     else {
691     MoveRight();
692     }
693 maya 3227 }
694    
695     void PutKanji(BYTE b)
696     {
697 doda 6802 int LineEnd;
698     TCharAttr CharAttrTmp;
699 doda 6803 CharAttrTmp = CharAttr;
700 maya 3227
701 doda 6802 Kanji = Kanji + b;
702 maya 3227
703 doda 6802 if (PrinterMode && DirectPrn) {
704     WriteToPrnFile(HIBYTE(Kanji),FALSE);
705     WriteToPrnFile(LOBYTE(Kanji),TRUE);
706     return;
707     }
708 maya 3227
709 doda 6802 if (ConvJIS)
710     Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f));
711 maya 3227
712 doda 6802 if (PrinterMode) { // printer mode
713     WriteToPrnFile(HIBYTE(Kanji),FALSE);
714     WriteToPrnFile(LOBYTE(Kanji),TRUE);
715     return;
716     }
717 maya 3227
718 doda 6802 if (CursorX > CursorRightM)
719     LineEnd = NumOfColumns - 1;
720     else
721     LineEnd = CursorRightM;
722 doda 5324
723 doda 6802 if (Wrap) {
724     CarriageReturn(FALSE);
725     LineFeed(LF,FALSE);
726     if (ts.EnableContinuedLineCopy)
727     CharAttrTmp.Attr |= AttrLineContinued;
728     }
729     else if (CursorX > LineEnd - 1) {
730     if (AutoWrapMode) {
731     if (ts.EnableContinuedLineCopy) {
732     CharAttrTmp.Attr |= AttrLineContinued;
733     if (CursorX == LineEnd)
734     BuffPutChar(0x20, CharAttr, FALSE);
735     }
736     CarriageReturn(FALSE);
737     LineFeed(LF,FALSE);
738     }
739     else {
740     return;
741     }
742     }
743 maya 3227
744 doda 6802 Wrap = FALSE;
745 maya 3227
746 doda 6802 if (cv.HLogBuf!=0) {
747     Log1Byte(HIBYTE(Kanji));
748     Log1Byte(LOBYTE(Kanji));
749     }
750 maya 3227
751 doda 6802 if (Special) {
752     UpdateStr();
753     Special = FALSE;
754     }
755 maya 3227
756 doda 6802 BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
757 maya 3227
758 doda 6802 if (CursorX < LineEnd - 1) {
759     MoveRight();
760     MoveRight();
761     }
762     else {
763     UpdateStr();
764     Wrap = AutoWrapMode;
765     }
766 maya 3227 }
767    
768     void PutDebugChar(BYTE b)
769     {
770 yutakapon 3637 static BYTE buff[3];
771 doda 5589 int i;
772     BOOL svInsertMode, svAutoWrapMode;
773     BYTE svCharAttr;
774 yutakapon 3637
775 doda 5589 if (DebugFlag!=DEBUG_FLAG_NOUT) {
776     svInsertMode = InsertMode;
777     svAutoWrapMode = AutoWrapMode;
778 doda 5588 InsertMode = FALSE;
779     AutoWrapMode = TRUE;
780 maya 3227
781 doda 5589 svCharAttr = CharAttr.Attr;
782     if (CharAttr.Attr != AttrDefault) {
783     UpdateStr();
784     CharAttr.Attr = AttrDefault;
785     }
786    
787 doda 5588 if (DebugFlag==DEBUG_FLAG_HEXD) {
788     _snprintf(buff, 3, "%02X", (unsigned int) b);
789 yutakapon 3637
790 doda 5589 for (i=0; i<2; i++)
791 doda 5588 PutChar(buff[i]);
792     PutChar(' ');
793     }
794     else if (DebugFlag==DEBUG_FLAG_NORM) {
795 yutakapon 3637
796 doda 5588 if ((b & 0x80) == 0x80) {
797     UpdateStr();
798     CharAttr.Attr = AttrReverse;
799     b = b & 0x7f;
800     }
801 maya 3227
802 doda 5588 if (b<=US) {
803     PutChar('^');
804     PutChar((char)(b+0x40));
805     }
806     else if (b==DEL) {
807     PutChar('<');
808     PutChar('D');
809     PutChar('E');
810     PutChar('L');
811     PutChar('>');
812     }
813     else
814     PutChar(b);
815     }
816 maya 3227
817 doda 5589 if (CharAttr.Attr != svCharAttr) {
818 doda 5588 UpdateStr();
819 doda 5589 CharAttr.Attr = svCharAttr;
820 doda 5588 }
821 doda 5589 InsertMode = svInsertMode;
822     AutoWrapMode = svAutoWrapMode;
823 yutakapon 3637 }
824 maya 3227 }
825    
826     void PrnParseControl(BYTE b) // printer mode
827     {
828 doda 6802 switch (b) {
829     case NUL:
830     return;
831     case SO:
832 doda 6913 if ((ts.ISO2022Flag & ISO2022_SO) && ! DirectPrn) {
833 doda 6802 if ((ts.Language==IdJapanese) &&
834     (ts.KanjiCode==IdJIS) &&
835     (ts.JIS7Katakana==1) &&
836     ((ts.TermFlag & TF_FIXEDJIS)!=0))
837     {
838     Gn[1] = IdKatakana;
839     }
840     Glr[0] = 1; /* LS1 */
841     return;
842     }
843     break;
844     case SI:
845 doda 6913 if ((ts.ISO2022Flag & ISO2022_SI) && ! DirectPrn) {
846 doda 6802 Glr[0] = 0; /* LS0 */
847     return;
848     }
849     break;
850     case DC1:
851     case DC3:
852     return;
853     case ESC:
854     ICount = 0;
855     JustAfterESC = TRUE;
856     ParseMode = ModeESC;
857     WriteToPrnFile(0, TRUE); // flush prn buff
858     return;
859     case CSI:
860     if (! Accept8BitCtrl) {
861     PutChar(b); /* Disp C1 char in VT100 mode */
862     return;
863     }
864     ClearParams();
865     FirstPrm = TRUE;
866     ParseMode = ModeCSI;
867     WriteToPrnFile(0, TRUE); // flush prn buff
868     WriteToPrnFile(b, FALSE);
869     return;
870     }
871     /* send the uninterpreted character to printer */
872     WriteToPrnFile(b, TRUE);
873 maya 3227 }
874    
875     void ParseControl(BYTE b)
876     {
877 doda 6802 if (PrinterMode) { // printer mode
878     PrnParseControl(b);
879     return;
880     }
881 maya 3227
882 doda 6802 if (b>=0x80) { /* C1 char */
883     if (ts.Language==IdEnglish) { /* English mode */
884     if (!Accept8BitCtrl) {
885     PutChar(b); /* Disp C1 char in VT100 mode */
886     return;
887     }
888     }
889     else { /* Japanese mode */
890     if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0) {
891     return; /* ignore C1 char */
892     }
893     /* C1 chars are interpreted as C0 chars in VT100 mode */
894     if (VTlevel < 2) {
895     b = b & 0x7F;
896     }
897     }
898     }
899     switch (b) {
900     /* C0 group */
901     case ENQ:
902     CommBinaryOut(&cv, &(ts.Answerback[0]), ts.AnswerbackLen);
903     break;
904     case BEL:
905     if (ts.Beep != IdBeepOff)
906     RingBell(ts.Beep);
907     break;
908     case BS:
909     BackSpace();
910     break;
911     case HT:
912     Tab();
913     break;
914     case LF:
915 maya 3227 if (ts.CRReceive == IdLF) {
916 maya 4893 // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
917     // CR+LF���������������������B
918     // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
919     // (2007.1.21 yutaka)
920 maya 3227 CarriageReturn(TRUE);
921     LineFeed(b, TRUE);
922     break;
923     }
924 maya 4893 else if (ts.CRReceive == IdAUTO) {
925     // 9th Apr 2012: AUTO CR/LF mode (tentner)
926     // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
927     if(PrevCharacter != CR || !PrevCRorLFGeneratedCRLF) {
928     CarriageReturn(TRUE);
929     LineFeed(b, TRUE);
930     PrevCRorLFGeneratedCRLF = TRUE;
931     }
932     else {
933     PrevCRorLFGeneratedCRLF = FALSE;
934     }
935     break;
936     }
937 maya 3227
938 doda 6802 case VT:
939     LineFeed(b, TRUE);
940     break;
941 maya 3227
942 doda 6802 case FF:
943     if ((ts.AutoWinSwitch>0) && JustAfterESC) {
944     CommInsert1Byte(&cv, b);
945     CommInsert1Byte(&cv, ESC);
946     ChangeEmu = IdTEK; /* Enter TEK Mode */
947     }
948     else
949     LineFeed(b, TRUE);
950     break;
951     case CR:
952     if (ts.CRReceive == IdAUTO) {
953     // 9th Apr 2012: AUTO CR/LF mode (tentner)
954     // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
955     if(PrevCharacter != LF || !PrevCRorLFGeneratedCRLF) {
956     CarriageReturn(TRUE);
957     LineFeed(b, TRUE);
958     PrevCRorLFGeneratedCRLF = TRUE;
959     }
960     else {
961     PrevCRorLFGeneratedCRLF = FALSE;
962     }
963     }
964     else {
965     CarriageReturn(TRUE);
966     if (ts.CRReceive==IdCRLF) {
967     CommInsert1Byte(&cv, LF);
968     }
969     }
970     break;
971     case SO: /* LS1 */
972 doda 6913 if (ts.ISO2022Flag & ISO2022_SO) {
973 doda 6804 if ((ts.Language==IdJapanese) &&
974     (ts.KanjiCode==IdJIS) &&
975     (ts.JIS7Katakana==1) &&
976     ((ts.TermFlag & TF_FIXEDJIS)!=0))
977     {
978     Gn[1] = IdKatakana;
979     }
980 maya 3227
981 doda 6804 Glr[0] = 1;
982     }
983 doda 6802 break;
984     case SI: /* LS0 */
985 doda 6913 if (ts.ISO2022Flag & ISO2022_SI) {
986 doda 6804 Glr[0] = 0;
987     }
988 doda 6802 break;
989     case DLE:
990     if ((ts.FTFlag & FT_BPAUTO)!=0)
991     ParseMode = ModeDLE; /* Auto B-Plus activation */
992     break;
993     case CAN:
994     if ((ts.FTFlag & FT_ZAUTO)!=0)
995     ParseMode = ModeCAN; /* Auto ZMODEM activation */
996     // else if (ts.AutoWinSwitch>0)
997     // ChangeEmu = IdTEK; /* Enter TEK Mode */
998     else
999     ParseMode = ModeFirst;
1000     break;
1001     case SUB:
1002     ParseMode = ModeFirst;
1003     break;
1004     case ESC:
1005     ICount = 0;
1006     JustAfterESC = TRUE;
1007     ParseMode = ModeESC;
1008     break;
1009     case FS:
1010     case GS:
1011     case RS:
1012     case US:
1013     if (ts.AutoWinSwitch>0) {
1014     CommInsert1Byte(&cv, b);
1015     ChangeEmu = IdTEK; /* Enter TEK Mode */
1016     }
1017     break;
1018 maya 3227
1019 doda 6802 /* C1 char */
1020     case IND:
1021     LineFeed(0, TRUE);
1022     break;
1023     case NEL:
1024     LineFeed(0, TRUE);
1025     CarriageReturn(TRUE);
1026     break;
1027     case HTS:
1028     if (ts.TabStopFlag & TABF_HTS8)
1029     SetTabStop();
1030     break;
1031     case RI:
1032     CursorUpWithScroll();
1033     break;
1034     case SS2:
1035 doda 6913 if (ts.ISO2022Flag & ISO2022_SS2) {
1036     GLtmp = 2;
1037     SSflag = TRUE;
1038     }
1039 doda 6802 break;
1040     case SS3:
1041 doda 6913 if (ts.ISO2022Flag & ISO2022_SS3) {
1042     GLtmp = 3;
1043     SSflag = TRUE;
1044     }
1045 doda 6802 break;
1046     case DCS:
1047     ClearParams();
1048     ESCFlag = FALSE;
1049     ParseMode = ModeDCS;
1050     break;
1051     case SOS:
1052     ESCFlag = FALSE;
1053     ParseMode = ModeIgnore;
1054     break;
1055     case CSI:
1056     ClearParams();
1057     FirstPrm = TRUE;
1058     ParseMode = ModeCSI;
1059     break;
1060     case OSC:
1061     ClearParams();
1062     ParseMode = ModeXS;
1063     break;
1064     case PM:
1065     case APC:
1066     ESCFlag = FALSE;
1067     ParseMode = ModeIgnore;
1068     break;
1069     }
1070 maya 3227 }
1071    
1072     void SaveCursor()
1073     {
1074 doda 6802 int i;
1075     PStatusBuff Buff;
1076 maya 3227
1077 doda 6802 if (isCursorOnStatusLine)
1078     Buff = &SBuff2; // for status line
1079     else if (AltScr)
1080     Buff = &SBuff3; // for alternate screen
1081     else
1082     Buff = &SBuff1; // for main screen
1083 maya 3227
1084 doda 6802 Buff->CursorX = CursorX;
1085     Buff->CursorY = CursorY;
1086     Buff->Attr = CharAttr;
1087    
1088     Buff->Glr[0] = Glr[0];
1089     Buff->Glr[1] = Glr[1];
1090     for (i=0 ; i<=3; i++)
1091     Buff->Gn[i] = Gn[i];
1092    
1093     Buff->AutoWrapMode = AutoWrapMode;
1094     Buff->RelativeOrgMode = RelativeOrgMode;
1095 maya 3227 }
1096    
1097 doda 6802 void RestoreCursor()
1098 maya 3227 {
1099 doda 6802 int i;
1100     PStatusBuff Buff;
1101 maya 3227
1102 doda 6802 UpdateStr();
1103 maya 3227
1104 doda 6802 if (isCursorOnStatusLine)
1105     Buff = &SBuff2; // for status line
1106     else if (AltScr)
1107     Buff = &SBuff3; // for alternate screen
1108     else
1109     Buff = &SBuff1; // for main screen
1110    
1111     if (Buff->CursorX > NumOfColumns-1)
1112     Buff->CursorX = NumOfColumns-1;
1113     if (Buff->CursorY > NumOfLines-1-StatusLine)
1114     Buff->CursorY = NumOfLines-1-StatusLine;
1115     MoveCursor(Buff->CursorX, Buff->CursorY);
1116    
1117     CharAttr = Buff->Attr;
1118     BuffSetCurCharAttr(CharAttr);
1119    
1120     Glr[0] = Buff->Glr[0];
1121     Glr[1] = Buff->Glr[1];
1122     for (i=0 ; i<=3; i++)
1123     Gn[i] = Buff->Gn[i];
1124    
1125     AutoWrapMode = Buff->AutoWrapMode;
1126     RelativeOrgMode = Buff->RelativeOrgMode;
1127 maya 3227 }
1128    
1129     void AnswerTerminalType()
1130     {
1131 doda 6802 char Tmp[50];
1132 maya 3227
1133 doda 6802 if (ts.TerminalID<IdVT320 || !Send8BitMode)
1134     strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1135     else
1136     strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1137 maya 3227
1138 doda 6802 switch (ts.TerminalID) {
1139     case IdVT100:
1140     strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1141     break;
1142     case IdVT100J:
1143     strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1144     break;
1145     case IdVT101:
1146     strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1147     break;
1148     case IdVT102:
1149     strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1150     break;
1151     case IdVT102J:
1152     strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1153     break;
1154     case IdVT220J:
1155     strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1156     break;
1157     case IdVT282:
1158     strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1159     break;
1160     case IdVT320:
1161     strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1162     break;
1163     case IdVT382:
1164     strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1165     break;
1166     case IdVT420:
1167     strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1168     break;
1169     case IdVT520:
1170     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1171     break;
1172     case IdVT525:
1173     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1174     break;
1175     }
1176     strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1177 maya 3227
1178 doda 6802 CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1179 maya 3227 }
1180    
1181     void ESCSpace(BYTE b)
1182     {
1183 doda 6802 switch (b) {
1184     case 'F': // S7C1T
1185     Send8BitMode = FALSE;
1186     break;
1187     case 'G': // S8C1T
1188     if (VTlevel >= 2) {
1189     Send8BitMode = TRUE;
1190     }
1191     break;
1192     }
1193 maya 3227 }
1194    
1195     void ESCSharp(BYTE b)
1196     {
1197 doda 6802 switch (b) {
1198     case '8': /* Fill screen with "E" (DECALN) */
1199     BuffUpdateScroll();
1200     BuffFillWithE();
1201     CursorTop = 0;
1202     CursorBottom = NumOfLines-1-StatusLine;
1203     CursorLeftM = 0;
1204     CursorRightM = NumOfColumns - 1;
1205     MoveCursor(0, 0);
1206     ParseMode = ModeFirst;
1207     break;
1208     }
1209 maya 3227 }
1210    
1211     /* select double byte code set */
1212     void ESCDBCSSelect(BYTE b)
1213     {
1214 doda 6802 int Dist;
1215 maya 3227
1216 doda 6802 if (ts.Language!=IdJapanese) return;
1217 maya 3227
1218 doda 6802 switch (ICount) {
1219     case 1:
1220     if ((b=='@') || (b=='B'))
1221     {
1222     Gn[0] = IdKanji; /* Kanji -> G0 */
1223     if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1224     Glr[0] = 0; /* G0->GL */
1225     }
1226     break;
1227     case 2:
1228     /* Second intermediate char must be
1229     '(' or ')' or '*' or '+'. */
1230     Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1231     if ((b=='1') || (b=='3') ||
1232     (b=='@') || (b=='B'))
1233     {
1234     Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1235     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1236     (Dist==0))
1237     Glr[0] = 0; /* G0->GL */
1238     }
1239     break;
1240     }
1241 maya 3227 }
1242    
1243     void ESCSelectCode(BYTE b)
1244     {
1245 doda 6802 switch (b) {
1246     case '0':
1247     if (ts.AutoWinSwitch>0)
1248     ChangeEmu = IdTEK; /* enter TEK mode */
1249     break;
1250     }
1251 maya 3227 }
1252    
1253 doda 6802 /* select single byte code set */
1254 maya 3227 void ESCSBCSSelect(BYTE b)
1255     {
1256 doda 6802 int Dist;
1257 maya 3227
1258 doda 6802 /* Intermediate char must be '(' or ')' or '*' or '+'. */
1259     Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1260 maya 3227
1261 doda 6802 switch (b) {
1262     case '0': Gn[Dist] = IdSpecial; break;
1263     case '<': Gn[Dist] = IdASCII; break;
1264     case '>': Gn[Dist] = IdASCII; break;
1265     case 'A': Gn[Dist] = IdASCII; break;
1266     case 'B': Gn[Dist] = IdASCII; break;
1267     case 'H': Gn[Dist] = IdASCII; break;
1268     case 'I':
1269     if (ts.Language==IdJapanese)
1270     Gn[Dist] = IdKatakana;
1271     break;
1272     case 'J': Gn[Dist] = IdASCII; break;
1273     }
1274 maya 3227
1275 doda 6802 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) && (Dist==0))
1276     Glr[0] = 0; /* G0->GL */
1277 maya 3227 }
1278    
1279     void PrnParseEscape(BYTE b) // printer mode
1280     {
1281 doda 6802 int i;
1282 maya 3227
1283 doda 6802 ParseMode = ModeFirst;
1284     switch (ICount) {
1285     /* no intermediate char */
1286     case 0:
1287     switch (b) {
1288     case '[': /* CSI */
1289     ClearParams();
1290     FirstPrm = TRUE;
1291     WriteToPrnFile(ESC,FALSE);
1292     WriteToPrnFile('[',FALSE);
1293     ParseMode = ModeCSI;
1294     return;
1295     } /* end of case Icount=0 */
1296     break;
1297     /* one intermediate char */
1298     case 1:
1299     switch (IntChar[1]) {
1300     case '$':
1301     if (! DirectPrn) {
1302     ESCDBCSSelect(b);
1303     return;
1304     }
1305     break;
1306     case '(':
1307     case ')':
1308     case '*':
1309     case '+':
1310     if (! DirectPrn) {
1311     ESCSBCSSelect(b);
1312     return;
1313     }
1314     break;
1315     }
1316     break;
1317     /* two intermediate char */
1318     case 2:
1319     if ((! DirectPrn) &&
1320     (IntChar[1]=='$') &&
1321     ('('<=IntChar[2]) &&
1322     (IntChar[2]<='+'))
1323     {
1324     ESCDBCSSelect(b);
1325     return;
1326     }
1327     break;
1328     }
1329     // send the uninterpreted sequence to printer
1330     WriteToPrnFile(ESC,FALSE);
1331     for (i=1; i<=ICount; i++)
1332     WriteToPrnFile(IntChar[i],FALSE);
1333     WriteToPrnFile(b,TRUE);
1334 maya 3227 }
1335    
1336     void ParseEscape(BYTE b) /* b is the final char */
1337     {
1338 doda 6802 if (PrinterMode) { // printer mode
1339     PrnParseEscape(b);
1340     return;
1341     }
1342 maya 3227
1343 doda 6802 switch (ICount) {
1344     case 0: /* no intermediate char */
1345     switch (b) {
1346     case '6': // DECBI
1347     if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1348     CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1349     if (CursorX == CursorLeftM)
1350     BuffScrollRight(1);
1351     else
1352     MoveCursor(CursorX-1, CursorY);
1353     }
1354     break;
1355     case '7': SaveCursor(); break;
1356     case '8': RestoreCursor(); break;
1357     case '9': // DECFI
1358     if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1359     CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1360     if (CursorX == CursorRightM)
1361     BuffScrollLeft(1);
1362     else
1363     MoveCursor(CursorX+1, CursorY);
1364     }
1365     break;
1366     case '=': AppliKeyMode = TRUE; break;
1367     case '>': AppliKeyMode = FALSE; break;
1368     case 'D': /* IND */
1369     LineFeed(0,TRUE);
1370     break;
1371     case 'E': /* NEL */
1372     MoveCursor(0,CursorY);
1373     LineFeed(0,TRUE);
1374     break;
1375     case 'H': /* HTS */
1376     if (ts.TabStopFlag & TABF_HTS7)
1377     SetTabStop();
1378     break;
1379     case 'M': /* RI */
1380     CursorUpWithScroll();
1381     break;
1382     case 'N': /* SS2 */
1383 doda 6913 if (ts.ISO2022Flag & ISO2022_SS2) {
1384     GLtmp = 2;
1385     SSflag = TRUE;
1386     }
1387 doda 6802 break;
1388     case 'O': /* SS3 */
1389 doda 6913 if (ts.ISO2022Flag & ISO2022_SS3) {
1390     GLtmp = 3;
1391     SSflag = TRUE;
1392     }
1393 doda 6802 break;
1394     case 'P': /* DCS */
1395     ClearParams();
1396     ESCFlag = FALSE;
1397     ParseMode = ModeDCS;
1398     return;
1399     case 'X': /* SOS */
1400     case '^': /* APC */
1401     case '_': /* PM */
1402     ESCFlag = FALSE;
1403     ParseMode = ModeIgnore;
1404     return;
1405     case 'Z': /* DECID */
1406     AnswerTerminalType();
1407     break;
1408     case '[': /* CSI */
1409     ClearParams();
1410     FirstPrm = TRUE;
1411     ParseMode = ModeCSI;
1412     return;
1413     case '\\': break; /* ST */
1414     case ']': /* XTERM sequence (OSC) */
1415     ClearParams();
1416     ParseMode = ModeXS;
1417     return;
1418     case 'c': /* Hardware reset */
1419     HideStatusLine();
1420     ResetTerminal();
1421     ClearUserKey();
1422     ClearBuffer();
1423     if (ts.PortType==IdSerial) // reset serial port
1424     CommResetSerial(&ts, &cv, TRUE);
1425     break;
1426     case 'g': /* Visual Bell (screen original?) */
1427     RingBell(IdBeepVisual);
1428     break;
1429 doda 6913 case 'n': /* LS2 */
1430     if (ts.ISO2022Flag & ISO2022_LS2) {
1431     Glr[0] = 2;
1432     }
1433     break;
1434     case 'o': /* LS3 */
1435     if (ts.ISO2022Flag & ISO2022_LS3) {
1436     Glr[0] = 3;
1437     }
1438     break;
1439     case '|': /* LS3R */
1440     if (ts.ISO2022Flag & ISO2022_LS3R) {
1441     Glr[1] = 3;
1442     }
1443     break;
1444     case '}': /* LS2R */
1445     if (ts.ISO2022Flag & ISO2022_LS2R) {
1446     Glr[1] = 2;
1447     }
1448     break;
1449     case '~': /* LS1R */
1450     if (ts.ISO2022Flag & ISO2022_LS1R) {
1451     Glr[1] = 1;
1452     }
1453     break;
1454 doda 6802 }
1455     break;
1456     /* end of case Icount=0 */
1457    
1458     case 1: /* one intermediate char */
1459     switch (IntChar[1]) {
1460     case ' ': ESCSpace(b); break;
1461     case '#': ESCSharp(b); break;
1462     case '$': ESCDBCSSelect(b); break;
1463     case '%': break;
1464     case '(':
1465     case ')':
1466     case '*':
1467     case '+':
1468     ESCSBCSSelect(b);
1469     break;
1470     }
1471     break;
1472    
1473     case 2: /* two intermediate char */
1474     if ((IntChar[1]=='$') && ('('<=IntChar[2]) && (IntChar[2]<='+'))
1475     ESCDBCSSelect(b);
1476     else if ((IntChar[1]=='%') && (IntChar[2]=='!'))
1477     ESCSelectCode(b);
1478     break;
1479     }
1480     ParseMode = ModeFirst;
1481 maya 3227 }
1482    
1483     void EscapeSequence(BYTE b)
1484     {
1485 doda 6173 if (b<=US)
1486     ParseControl(b);
1487     else if ((b>=0x20) && (b<=0x2F)) {
1488 doda 6174 // TODO: ICount �� IntCharMax ���B�������A������ IntChar ���u����������������?
1489 doda 6173 if (ICount<IntCharMax)
1490     ICount++;
1491     IntChar[ICount] = b;
1492     }
1493     else if ((b>=0x30) && (b<=0x7E))
1494     ParseEscape(b);
1495     else if ((b>=0x80) && (b<=0x9F))
1496     ParseControl(b);
1497     else if (b>=0xA0) {
1498     ParseMode=ModeFirst;
1499     ParseFirst(b);
1500     }
1501 maya 3227
1502 doda 6173 JustAfterESC = FALSE;
1503 maya 3227 }
1504    
1505 doda 6174 #define CheckParamVal(p,m) \
1506     if ((p) == 0) { \
1507     (p) = 1; \
1508     } \
1509     else if ((p) > (m) || p < 0) { \
1510     (p) = (m); \
1511     }
1512    
1513     #define CheckParamValMax(p,m) \
1514     if ((p) > (m) || p <= 0) { \
1515     (p) = (m); \
1516     }
1517    
1518     #define RequiredParams(n) \
1519     if ((n) > 1) { \
1520     while (NParam < n) { \
1521     NParam++; \
1522     Param[NParam] = 0; \
1523     NSParam[NParam] = 0; \
1524     } \
1525     }
1526    
1527 doda 6173 void CSInsertCharacter() // ICH
1528     {
1529     // Insert space characters at cursor
1530 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1531 maya 3227
1532 doda 6173 BuffUpdateScroll();
1533 doda 6174 BuffInsertSpace(Param[1]);
1534 doda 6173 }
1535 maya 3227
1536 doda 5429 void CSCursorUp(BOOL AffectMargin) // CUU / VPB
1537     {
1538     int topMargin, NewY;
1539 maya 3227
1540 doda 6174 CheckParamVal(Param[1], CursorY);
1541 maya 3227
1542 doda 5429 if (AffectMargin && CursorY >= CursorTop)
1543     topMargin = CursorTop;
1544     else
1545     topMargin = 0;
1546 maya 3227
1547 doda 5429 NewY = CursorY - Param[1];
1548     if (NewY < topMargin)
1549     NewY = topMargin;
1550 maya 3227
1551 doda 5429 MoveCursor(CursorX, NewY);
1552     }
1553 maya 3227
1554 doda 5429 void CSCursorUp1() // CPL
1555     {
1556     MoveCursor(CursorLeftM, CursorY);
1557     CSCursorUp(TRUE);
1558     }
1559 maya 3227
1560 doda 5429 void CSCursorDown(BOOL AffectMargin) // CUD / VPR
1561     {
1562     int bottomMargin, NewY;
1563    
1564     if (AffectMargin && CursorY <= CursorBottom)
1565     bottomMargin = CursorBottom;
1566     else
1567     bottomMargin = NumOfLines-StatusLine-1;
1568    
1569 doda 6174 CheckParamVal(Param[1], bottomMargin);
1570    
1571 doda 5429 NewY = CursorY + Param[1];
1572     if (NewY > bottomMargin)
1573     NewY = bottomMargin;
1574    
1575     MoveCursor(CursorX, NewY);
1576     }
1577    
1578     void CSCursorDown1() // CNL
1579     {
1580     MoveCursor(CursorLeftM, CursorY);
1581     CSCursorDown(TRUE);
1582     }
1583    
1584 maya 3227 void CSScreenErase()
1585     {
1586     BuffUpdateScroll();
1587     switch (Param[1]) {
1588 doda 6173 case 0:
1589 maya 3227 // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1590     // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1591     // �����������������B(2005.5.29 yutaka)
1592     // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1593 doda 6435 if (ts.ScrollWindowClearScreen &&
1594 maya 3227 (CursorX == 0 && CursorY == 0)) {
1595 doda 6173 // Erase screen (scroll out)
1596 maya 3227 BuffClearScreen();
1597     UpdateWindow(HVTWin);
1598    
1599     } else {
1600 doda 6173 // Erase characters from cursor to the end of screen
1601 maya 3227 BuffEraseCurToEnd();
1602     }
1603     break;
1604    
1605 doda 6173 case 1:
1606     // Erase characters from home to cursor
1607 maya 3227 BuffEraseHomeToCur();
1608     break;
1609    
1610 doda 6173 case 2:
1611     // Erase screen (scroll out)
1612 maya 3227 BuffClearScreen();
1613     UpdateWindow(HVTWin);
1614 doda 5564 if (ClearThenHome && !isCursorOnStatusLine) {
1615     if (RelativeOrgMode) {
1616     MoveCursor(0, 0);
1617     }
1618     else {
1619     MoveCursor(CursorLeftM, CursorTop);
1620     }
1621     }
1622 maya 3227 break;
1623     }
1624     }
1625    
1626 doda 4070 void CSQSelScreenErase()
1627     {
1628     BuffUpdateScroll();
1629     switch (Param[1]) {
1630 doda 6173 case 0:
1631     // Erase characters from cursor to end
1632 doda 4070 BuffSelectedEraseCurToEnd();
1633     break;
1634    
1635 doda 6173 case 1:
1636     // Erase characters from home to cursor
1637 doda 4070 BuffSelectedEraseHomeToCur();
1638     break;
1639    
1640 doda 6173 case 2:
1641     // Erase entire screen
1642 doda 4070 BuffSelectedEraseScreen();
1643     break;
1644     }
1645     }
1646    
1647 doda 6173 void CSInsertLine()
1648     {
1649     // Insert lines at current position
1650     int Count, YEnd;
1651 maya 3227
1652 doda 6174 if (CursorY < CursorTop || CursorY > CursorBottom) {
1653 doda 6173 return;
1654 doda 6174 }
1655 maya 3227
1656 doda 6174 CheckParamVal(Param[1], NumOfLines);
1657    
1658 doda 6173 Count = Param[1];
1659 maya 3227
1660 doda 6173 YEnd = CursorBottom;
1661     if (CursorY > YEnd)
1662     YEnd = NumOfLines-1-StatusLine;
1663 doda 6174
1664 doda 6173 if (Count > YEnd+1 - CursorY)
1665     Count = YEnd+1 - CursorY;
1666 maya 3227
1667 doda 6173 BuffInsertLines(Count,YEnd);
1668     }
1669 maya 3227
1670 doda 6173 void CSLineErase()
1671     {
1672     BuffUpdateScroll();
1673     switch (Param[1]) {
1674     case 0: /* erase char from cursor to end of line */
1675     BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1676     break;
1677 doda 4070
1678 doda 6173 case 1: /* erase char from start of line to cursor */
1679     BuffEraseCharsInLine(0,CursorX+1);
1680     break;
1681 maya 3227
1682 doda 6173 case 2: /* erase entire line */
1683     BuffEraseCharsInLine(0,NumOfColumns);
1684     break;
1685     }
1686     }
1687 maya 3227
1688 doda 6173 void CSQSelLineErase()
1689     {
1690     BuffUpdateScroll();
1691     switch (Param[1]) {
1692     case 0: /* erase char from cursor to end of line */
1693     BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1694     break;
1695 maya 3227
1696 doda 6173 case 1: /* erase char from start of line to cursor */
1697     BuffSelectedEraseCharsInLine(0,CursorX+1);
1698     break;
1699 maya 3227
1700 doda 6173 case 2: /* erase entire line */
1701     BuffSelectedEraseCharsInLine(0,NumOfColumns);
1702     break;
1703     }
1704     }
1705 maya 3227
1706 doda 6173 void CSDeleteNLines()
1707     // Delete lines from current line
1708     {
1709     int Count, YEnd;
1710 maya 3227
1711 doda 6174 if (CursorY < CursorTop || CursorY > CursorBottom) {
1712 doda 6173 return;
1713 doda 6174 }
1714    
1715     CheckParamVal(Param[1], NumOfLines);
1716 doda 6173 Count = Param[1];
1717 maya 3227
1718 doda 6173 YEnd = CursorBottom;
1719     if (CursorY > YEnd)
1720     YEnd = NumOfLines-1-StatusLine;
1721 doda 6174
1722 doda 6173 if (Count > YEnd+1-CursorY)
1723     Count = YEnd+1-CursorY;
1724 doda 6174
1725 doda 6173 BuffDeleteLines(Count,YEnd);
1726     }
1727 maya 3227
1728 doda 6173 void CSDeleteCharacter() // DCH
1729     {
1730     // Delete characters in current line from cursor
1731 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1732 maya 3227
1733 doda 6173 BuffUpdateScroll();
1734     BuffDeleteChars(Param[1]);
1735     }
1736 maya 3227
1737 doda 6173 void CSEraseCharacter() // ECH
1738     {
1739 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1740    
1741 doda 6173 BuffUpdateScroll();
1742     BuffEraseChars(Param[1]);
1743     }
1744    
1745     void CSScrollUp()
1746     {
1747 doda 6174 // TODO: �X�N���[���������l���[���s�����������������v����
1748     CheckParamVal(Param[1], INT_MAX);
1749    
1750 doda 6173 BuffUpdateScroll();
1751     BuffRegionScrollUpNLines(Param[1]);
1752     }
1753    
1754     void CSScrollDown()
1755     {
1756 doda 6174 CheckParamVal(Param[1], NumOfLines);
1757    
1758 doda 6173 BuffUpdateScroll();
1759     BuffRegionScrollDownNLines(Param[1]);
1760     }
1761    
1762     void CSForwardTab()
1763     {
1764 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1765 doda 6173 CursorForwardTab(Param[1], AutoWrapMode);
1766     }
1767    
1768     void CSBackwardTab()
1769     {
1770 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1771 doda 6173 CursorBackwardTab(Param[1]);
1772     }
1773    
1774 doda 5324 void CSMoveToColumnN() // CHA / HPA
1775     {
1776 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1777 maya 3227
1778 doda 5324 Param[1]--;
1779 maya 3227
1780 doda 5324 if (RelativeOrgMode) {
1781     if (CursorLeftM + Param[1] > CursorRightM )
1782     MoveCursor(CursorRightM, CursorY);
1783     else
1784     MoveCursor(CursorLeftM + Param[1], CursorY);
1785     }
1786     else {
1787     MoveCursor(Param[1], CursorY);
1788     }
1789     }
1790 maya 3227
1791 doda 5429 void CSCursorRight(BOOL AffectMargin) // CUF / HPR
1792 doda 5324 {
1793 doda 5429 int NewX, rightMargin;
1794 doda 5324
1795 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1796 doda 5324
1797 doda 6174 if (AffectMargin && CursorX <= CursorRightM) {
1798 doda 5429 rightMargin = CursorRightM;
1799 doda 6174 }
1800     else {
1801 doda 5429 rightMargin = NumOfColumns-1;
1802 doda 6174 }
1803 doda 5429
1804 doda 5324 NewX = CursorX + Param[1];
1805 doda 5429 if (NewX > rightMargin)
1806     NewX = rightMargin;
1807 doda 5324
1808     MoveCursor(NewX, CursorY);
1809     }
1810    
1811 doda 5429 void CSCursorLeft(BOOL AffectMargin) // CUB / HPB
1812 doda 5324 {
1813 doda 5429 int NewX, leftMargin;
1814 doda 5324
1815 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1816 doda 5324
1817 doda 6174 if (AffectMargin && CursorX >= CursorLeftM) {
1818 doda 5429 leftMargin = CursorLeftM;
1819 doda 6174 }
1820     else {
1821 doda 5429 leftMargin = 0;
1822 doda 6174 }
1823 doda 5324
1824 doda 5429 NewX = CursorX - Param[1];
1825 doda 6174 if (NewX < leftMargin) {
1826 doda 5429 NewX = leftMargin;
1827 doda 6174 }
1828 doda 5324
1829     MoveCursor(NewX, CursorY);
1830     }
1831    
1832 doda 6174 void CSMoveToLineN() // VPA
1833 doda 6173 {
1834 doda 6174 CheckParamVal(Param[1], NumOfLines-StatusLine);
1835    
1836 doda 6173 if (RelativeOrgMode) {
1837     if (CursorTop+Param[1]-1 > CursorBottom)
1838     MoveCursor(CursorX,CursorBottom);
1839     else
1840     MoveCursor(CursorX,CursorTop+Param[1]-1);
1841     }
1842     else {
1843     if (Param[1] > NumOfLines-StatusLine)
1844     MoveCursor(CursorX,NumOfLines-1-StatusLine);
1845     else
1846     MoveCursor(CursorX,Param[1]-1);
1847     }
1848 doda 6602 Fallbacked = FALSE;
1849 doda 6173 }
1850 maya 3227
1851 doda 5324 void CSMoveToXY() // CUP / HVP
1852     {
1853     int NewX, NewY;
1854 maya 3227
1855 doda 6174 RequiredParams(2);
1856     CheckParamVal(Param[1], NumOfLines-StatusLine);
1857     CheckParamVal(Param[2], NumOfColumns);
1858 maya 3227
1859 doda 5324 NewY = Param[1] - 1;
1860     NewX = Param[2] - 1;
1861    
1862     if (isCursorOnStatusLine)
1863     NewY = CursorY;
1864     else if (RelativeOrgMode) {
1865     NewX += CursorLeftM;
1866     if (NewX > CursorRightM)
1867     NewX = CursorRightM;
1868    
1869     NewY += CursorTop;
1870     if (NewY > CursorBottom)
1871     NewY = CursorBottom;
1872     }
1873     else {
1874     if (NewY > NumOfLines-1-StatusLine)
1875     NewY = NumOfLines-1-StatusLine;
1876     }
1877    
1878     MoveCursor(NewX, NewY);
1879 doda 6602 Fallbacked = FALSE;
1880 doda 5324 }
1881    
1882 doda 6173 void CSDeleteTabStop()
1883     {
1884     ClearTabStop(Param[1]);
1885     }
1886 maya 3227
1887 doda 6173 void CS_h_Mode() // SM
1888     {
1889     switch (Param[1]) {
1890     case 2: // KAM
1891     KeybEnabled = FALSE; break;
1892     case 4: // IRM
1893     InsertMode = TRUE; break;
1894     case 12: // SRM
1895     ts.LocalEcho = 0;
1896     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1897     TelChangeEcho();
1898     break;
1899     case 20: // LF/NL
1900     LFMode = TRUE;
1901     ts.CRSend = IdCRLF;
1902     cv.CRSend = IdCRLF;
1903     break;
1904     case 33: // WYSTCURM
1905     if (ts.WindowFlag & WF_CURSORCHANGE) {
1906     ts.NonblinkingCursor = TRUE;
1907     ChangeCaret();
1908     }
1909     break;
1910     case 34: // WYULCURM
1911     if (ts.WindowFlag & WF_CURSORCHANGE) {
1912     ts.CursorShape = IdHCur;
1913     ChangeCaret();
1914     }
1915     break;
1916     }
1917     }
1918 maya 3227
1919 doda 6173 void CS_i_Mode() // MC
1920     {
1921     switch (Param[1]) {
1922     /* print screen */
1923     // PrintEX -- TRUE: print screen
1924     // FALSE: scroll region
1925     case 0:
1926     if (ts.TermFlag&TF_PRINTERCTRL) {
1927     BuffPrint(! PrintEX);
1928     }
1929     break;
1930     /* printer controller mode off */
1931     case 4: break; /* See PrnParseCS() */
1932     /* printer controller mode on */
1933     case 5:
1934     if (ts.TermFlag&TF_PRINTERCTRL) {
1935     if (! AutoPrintMode)
1936     OpenPrnFile();
1937     DirectPrn = (ts.PrnDev[0]!=0);
1938     PrinterMode = TRUE;
1939     }
1940     break;
1941 doda 4397 }
1942 doda 6173 }
1943    
1944     void CS_l_Mode() // RM
1945     {
1946     switch (Param[1]) {
1947     case 2: // KAM
1948     KeybEnabled = TRUE; break;
1949     case 4: // IRM
1950     InsertMode = FALSE; break;
1951     case 12: // SRM
1952     ts.LocalEcho = 1;
1953     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
1954     TelChangeEcho();
1955     break;
1956     case 20: // LF/NL
1957     LFMode = FALSE;
1958     ts.CRSend = IdCR;
1959     cv.CRSend = IdCR;
1960     break;
1961     case 33: // WYSTCURM
1962     if (ts.WindowFlag & WF_CURSORCHANGE) {
1963     ts.NonblinkingCursor = FALSE;
1964     ChangeCaret();
1965     }
1966     break;
1967     case 34: // WYULCURM
1968     if (ts.WindowFlag & WF_CURSORCHANGE) {
1969     ts.CursorShape = IdBlkCur;
1970     ChangeCaret();
1971     }
1972     break;
1973 doda 4397 }
1974 doda 6173 }
1975 maya 3227
1976 doda 6173 void CS_n_Mode() // DSR
1977     {
1978     char Report[16];
1979     int X, Y, len;
1980 maya 3227
1981 doda 6173 switch (Param[1]) {
1982     case 5:
1983     /* Device Status Report -> Ready */
1984     SendCSIstr("0n", 0);
1985     break;
1986     case 6:
1987     /* Cursor Position Report */
1988     if (isCursorOnStatusLine) {
1989     X = CursorX + 1;
1990     Y = 1;
1991     }
1992     else if (RelativeOrgMode) {
1993     X = CursorX - CursorLeftM + 1;
1994     Y = CursorY - CursorTop + 1;
1995     }
1996     else {
1997     X = CursorX + 1;
1998     Y = CursorY+1;
1999     }
2000     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, X);
2001     SendCSIstr(Report, len);
2002     break;
2003 doda 5336 }
2004 doda 6173 }
2005 maya 3227
2006 doda 5095 void ParseSGRParams(PCharAttr attr, PCharAttr mask, int start)
2007 maya 3227 {
2008 doda 5073 int i, j, P, r, g, b, color;
2009 doda 5095 TCharAttr dummy;
2010 maya 3227
2011 doda 5095 if (mask == NULL) {
2012     mask = &dummy;
2013     }
2014    
2015 doda 6173 for (i=start ; i<=NParam ; i++) {
2016 maya 3227 P = Param[i];
2017     switch (P) {
2018 doda 6173 case 0: /* Clear all */
2019 doda 5095 attr->Attr = DefCharAttr.Attr;
2020     attr->Attr2 = DefCharAttr.Attr2 | (attr->Attr2&Attr2Protect);
2021     attr->Fore = DefCharAttr.Fore;
2022     attr->Back = DefCharAttr.Back;
2023     mask->Attr = AttrSgrMask;
2024     mask->Attr2 = Attr2ColorMask;
2025 maya 3227 break;
2026    
2027 doda 6173 case 1: /* Bold */
2028 doda 5095 attr->Attr |= AttrBold;
2029     mask->Attr |= AttrBold;
2030 maya 3227 break;
2031    
2032 doda 6173 case 4: /* Under line */
2033 doda 5095 attr->Attr |= AttrUnder;
2034     mask->Attr |= AttrUnder;
2035 maya 3227 break;
2036    
2037 doda 6173 case 5: /* Blink */
2038 doda 5095 attr->Attr |= AttrBlink;
2039     mask->Attr |= AttrBlink;
2040 maya 3227 break;
2041    
2042 doda 6173 case 7: /* Reverse */
2043 doda 5095 attr->Attr |= AttrReverse;
2044     mask->Attr |= AttrReverse;
2045 maya 3227 break;
2046    
2047 doda 6173 case 22: /* Bold off */
2048 doda 5095 attr->Attr &= ~ AttrBold;
2049     mask->Attr |= AttrBold;
2050 maya 3227 break;
2051    
2052 doda 6173 case 24: /* Under line off */
2053 doda 5095 attr->Attr &= ~ AttrUnder;
2054     mask->Attr |= AttrUnder;
2055 maya 3227 break;
2056    
2057 doda 6173 case 25: /* Blink off */
2058 doda 5095 attr->Attr &= ~ AttrBlink;
2059     mask->Attr |= AttrBlink;
2060 maya 3227 break;
2061    
2062 doda 6173 case 27: /* Reverse off */
2063 doda 5095 attr->Attr &= ~ AttrReverse;
2064     mask->Attr |= AttrReverse;
2065 maya 3227 break;
2066    
2067 doda 6173 case 30:
2068     case 31:
2069     case 32:
2070     case 33:
2071     case 34:
2072     case 35:
2073     case 36:
2074     case 37: /* text color */
2075 doda 5095 attr->Attr2 |= Attr2Fore;
2076     mask->Attr2 |= Attr2Fore;
2077     attr->Fore = P - 30;
2078 maya 3227 break;
2079    
2080 doda 6173 case 38: /* text color (256color mode) */
2081 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
2082     /*
2083     * Change foreground color. accept following formats.
2084     *
2085     * 38 ; 2 ; r ; g ; b
2086     * 38 ; 2 : r : g : b
2087     * 38 : 2 : r : g : b
2088     * 38 ; 5 ; idx
2089     * 38 ; 5 : idx
2090     * 38 : 5 : idx
2091     *
2092     */
2093     color = -1;
2094     j = 0;
2095     if (NSParam[i] > 0) {
2096     P = SubParam[i][1];
2097     j++;
2098     }
2099     else if (i < NParam) {
2100     P = Param[i+1];
2101     if (P == 2 || P == 5) {
2102     i++;
2103     }
2104     }
2105     switch (P) {
2106 doda 6173 case 2:
2107 doda 5073 r = g = b = 0;
2108     if (NSParam[i] > 0) {
2109     if (j < NSParam[i]) {
2110     r = SubParam[i][++j];
2111     if (j < NSParam[i]) {
2112     g = SubParam[i][++j];
2113     }
2114     if (j < NSParam[i]) {
2115     b = SubParam[i][++j];
2116     }
2117     color = DispFindClosestColor(r, g, b);
2118     }
2119     }
2120     else if (i < NParam && NSParam[i+1] > 0) {
2121     r = Param[++i];
2122     g = SubParam[i][1];
2123     if (NSParam[i] > 1) {
2124     b = SubParam[i][2];
2125     }
2126     color = DispFindClosestColor(r, g, b);
2127     }
2128     else if (i+2 < NParam) {
2129     r = Param[++i];
2130     g = Param[++i];
2131     b = Param[++i];
2132     color = DispFindClosestColor(r, g, b);
2133     }
2134     break;
2135 doda 6173 case 5:
2136 doda 5073 if (NSParam[i] > 0) {
2137     if (j < NSParam[i]) {
2138     color = SubParam[i][++j];
2139     }
2140     }
2141     else if (i < NParam) {
2142     color = Param[++i];
2143     }
2144     break;
2145     }
2146 doda 5077 if (color >= 0 && color < 256) {
2147 doda 5095 attr->Attr2 |= Attr2Fore;
2148     mask->Attr2 |= Attr2Fore;
2149     attr->Fore = color;
2150 maya 3227 }
2151     }
2152     break;
2153    
2154 doda 6173 case 39: /* Reset text color */
2155 doda 5095 attr->Attr2 &= ~ Attr2Fore;
2156     mask->Attr2 |= Attr2Fore;
2157     attr->Fore = AttrDefaultFG;
2158 maya 3227 break;
2159    
2160 doda 6173 case 40:
2161     case 41:
2162     case 42:
2163     case 43:
2164     case 44:
2165     case 45:
2166     case 46:
2167     case 47: /* Back color */
2168 doda 5095 attr->Attr2 |= Attr2Back;
2169     mask->Attr2 |= Attr2Back;
2170     attr->Back = P - 40;
2171 maya 3227 break;
2172    
2173 doda 6173 case 48: /* Back color (256color mode) */
2174 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
2175     color = -1;
2176     j = 0;
2177     if (NSParam[i] > 0) {
2178     P = SubParam[i][1];
2179     j++;
2180     }
2181     else if (i < NParam) {
2182     P = Param[i+1];
2183     if (P == 2 || P == 5) {
2184     i++;
2185     }
2186     }
2187     switch (P) {
2188 doda 6173 case 2:
2189 doda 5073 r = g = b = 0;
2190     if (NSParam[i] > 0) {
2191     if (j < NSParam[i]) {
2192     r = SubParam[i][++j];
2193     if (j < NSParam[i]) {
2194     g = SubParam[i][++j];
2195     }
2196     if (j < NSParam[i]) {
2197     b = SubParam[i][++j];
2198     }
2199     color = DispFindClosestColor(r, g, b);
2200     }
2201     }
2202     else if (i < NParam && NSParam[i+1] > 0) {
2203     r = Param[++i];
2204     g = SubParam[i][1];
2205     if (NSParam[i] > 1) {
2206     b = SubParam[i][2];
2207     }
2208     color = DispFindClosestColor(r, g, b);
2209     }
2210     else if (i+2 < NParam) {
2211     r = Param[++i];
2212     g = Param[++i];
2213     b = Param[++i];
2214     color = DispFindClosestColor(r, g, b);
2215     }
2216     break;
2217 doda 6173 case 5:
2218 doda 5073 if (NSParam[i] > 0) {
2219     if (j < NSParam[i]) {
2220     color = SubParam[i][++j];
2221     }
2222     }
2223     else if (i < NParam) {
2224     color = Param[++i];
2225     }
2226     break;
2227     }
2228 doda 5077 if (color >= 0 && color < 256) {
2229 doda 5095 attr->Attr2 |= Attr2Back;
2230     mask->Attr2 |= Attr2Back;
2231     attr->Back = color;
2232 maya 3227 }
2233     }
2234     break;
2235    
2236 doda 6173 case 49: /* Reset back color */
2237 doda 5095 attr->Attr2 &= ~ Attr2Back;
2238     mask->Attr2 |= Attr2Back;
2239     attr->Back = AttrDefaultBG;
2240 maya 3227 break;
2241    
2242 doda 6173 case 90:
2243     case 91:
2244     case 92:
2245     case 93:
2246     case 94:
2247     case 95:
2248     case 96:
2249     case 97: /* aixterm style text color */
2250 maya 3227 if (ts.ColorFlag & CF_AIXTERM16) {
2251 doda 5095 attr->Attr2 |= Attr2Fore;
2252     mask->Attr2 |= Attr2Fore;
2253     attr->Fore = P - 90 + 8;
2254 maya 3227 }
2255     break;
2256    
2257 doda 6173 case 100:
2258 maya 3227 if (! (ts.ColorFlag & CF_AIXTERM16)) {
2259     /* Reset text and back color */
2260 doda 5095 attr->Attr2 &= ~ (Attr2Fore | Attr2Back);
2261     mask->Attr2 |= Attr2ColorMask;
2262     attr->Fore = AttrDefaultFG;
2263     attr->Back = AttrDefaultBG;
2264 maya 3227 break;
2265     }
2266     /* fall through to aixterm style back color */
2267    
2268 doda 6173 case 101:
2269     case 102:
2270     case 103:
2271     case 104:
2272     case 105:
2273     case 106:
2274     case 107: /* aixterm style back color */
2275 maya 3227 if (ts.ColorFlag & CF_AIXTERM16) {
2276 doda 5095 attr->Attr2 |= Attr2Back;
2277     mask->Attr2 |= Attr2Back;
2278     attr->Back = P - 100 + 8;
2279 maya 3227 }
2280     break;
2281     }
2282     }
2283     }
2284    
2285 doda 5095 void CSSetAttr() // SGR
2286     {
2287     UpdateStr();
2288     ParseSGRParams(&CharAttr, NULL, 1);
2289     BuffSetCurCharAttr(CharAttr);
2290     }
2291    
2292 doda 6173 void CSSetScrollRegion() // DECSTBM
2293     {
2294     if (isCursorOnStatusLine) {
2295     MoveCursor(0,CursorY);
2296     return;
2297     }
2298 doda 6174
2299     RequiredParams(2);
2300     CheckParamVal(Param[1], NumOfLines-StatusLine);
2301     CheckParamValMax(Param[2], NumOfLines-StatusLine);
2302    
2303     if (Param[1] >= Param[2])
2304     return;
2305    
2306     CursorTop = Param[1] - 1;
2307     CursorBottom = Param[2] - 1;
2308    
2309     if (RelativeOrgMode)
2310     // TODO: ���}�[�W���������������B�v���@�m�F�B
2311     MoveCursor(0, CursorTop);
2312     else
2313     MoveCursor(0, 0);
2314 doda 6173 }
2315 maya 3227
2316 doda 5502 void CSSetLRScrollRegion() // DECSLRM
2317 doda 5324 {
2318 doda 6174 // TODO: �X�e�[�^�X���C�������������m�F�B
2319 doda 5324 // if (isCursorOnStatusLine) {
2320     // MoveCursor(0,CursorY);
2321     // return;
2322     // }
2323    
2324 doda 6174 RequiredParams(2);
2325     CheckParamVal(Param[1], NumOfColumns);
2326     CheckParamValMax(Param[2], NumOfColumns);
2327 doda 5324
2328     if (Param[1] >= Param[2])
2329     return;
2330    
2331 doda 6174 CursorLeftM = Param[1] - 1;
2332     CursorRightM = Param[2] - 1;
2333 doda 5324
2334     if (RelativeOrgMode)
2335     MoveCursor(CursorLeftM, CursorTop);
2336     else
2337     MoveCursor(0, 0);
2338     }
2339    
2340 doda 6173 void CSSunSequence() /* Sun terminal private sequences */
2341     {
2342     int x, y, len;
2343     char Report[TitleBuffSize*2+10];
2344     PTStack t;
2345 maya 3227
2346 doda 6173 switch (Param[1]) {
2347     case 1: // De-iconify window
2348     if (ts.WindowFlag & WF_WINDOWCHANGE)
2349     DispShowWindow(WINDOW_RESTORE);
2350     break;
2351 doda 6174
2352 doda 6173 case 2: // Iconify window
2353     if (ts.WindowFlag & WF_WINDOWCHANGE)
2354     DispShowWindow(WINDOW_MINIMIZE);
2355     break;
2356 doda 6174
2357 doda 6173 case 3: // set window position
2358     if (ts.WindowFlag & WF_WINDOWCHANGE) {
2359 doda 6174 RequiredParams(3);
2360 doda 6173 DispMoveWindow(Param[2], Param[3]);
2361     }
2362     break;
2363 doda 6174
2364 doda 6173 case 4: // set window size
2365     if (ts.WindowFlag & WF_WINDOWCHANGE) {
2366 doda 6174 RequiredParams(3);
2367 doda 6173 DispResizeWin(Param[3], Param[2]);
2368     }
2369     break;
2370 doda 6174
2371 doda 6173 case 5: // Raise window
2372     if (ts.WindowFlag & WF_WINDOWCHANGE)
2373     DispShowWindow(WINDOW_RAISE);
2374     break;
2375 doda 6174
2376 doda 6173 case 6: // Lower window
2377     if (ts.WindowFlag & WF_WINDOWCHANGE)
2378     DispShowWindow(WINDOW_LOWER);
2379     break;
2380 doda 6174
2381 doda 6173 case 7: // Refresh window
2382     if (ts.WindowFlag & WF_WINDOWCHANGE)
2383     DispShowWindow(WINDOW_REFRESH);
2384     break;
2385 doda 6174
2386 doda 6173 case 8: /* set terminal size */
2387     if (ts.WindowFlag & WF_WINDOWCHANGE) {
2388 doda 6174 RequiredParams(3);
2389     if (Param[2] <= 1) Param[2] = 24;
2390     if (Param[3] <= 1) Param[3] = 80;
2391     ChangeTerminalSize(Param[3], Param[2]);
2392 doda 6173 }
2393     break;
2394 doda 6174
2395 doda 6173 case 9: // Maximize/Restore window
2396     if (ts.WindowFlag & WF_WINDOWCHANGE) {
2397 doda 6174 RequiredParams(2);
2398     if (Param[2] == 0) {
2399 doda 6173 DispShowWindow(WINDOW_RESTORE);
2400     }
2401     else if (Param[2] == 1) {
2402     DispShowWindow(WINDOW_MAXIMIZE);
2403     }
2404     }
2405     break;
2406 doda 6174
2407 doda 6173 case 11: // Report window state
2408     if (ts.WindowFlag & WF_WINDOWREPORT) {
2409     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%dt", CLocale, DispWindowIconified()?2:1);
2410     SendCSIstr(Report, len);
2411     }
2412     break;
2413 doda 6174
2414 doda 6173 case 13: // Report window position
2415     if (ts.WindowFlag & WF_WINDOWREPORT) {
2416     DispGetWindowPos(&x, &y);
2417     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "3;%u;%ut", CLocale, (unsigned int)x, (unsigned int)y);
2418     SendCSIstr(Report, len);
2419     }
2420     break;
2421 doda 6174
2422 doda 6173 case 14: /* get window size */
2423     if (ts.WindowFlag & WF_WINDOWREPORT) {
2424     DispGetWindowSize(&x, &y);
2425     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "4;%d;%dt", CLocale, y, x);
2426     SendCSIstr(Report, len);
2427     }
2428     break;
2429 doda 6174
2430 doda 6173 case 18: /* get terminal size */
2431     if (ts.WindowFlag & WF_WINDOWREPORT) {
2432     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "8;%u;%ut", CLocale,
2433     NumOfLines-StatusLine, NumOfColumns);
2434     SendCSIstr(Report, len);
2435     }
2436     break;
2437 doda 6174
2438 doda 6173 case 19: // Report display size (character)
2439     if (ts.WindowFlag & WF_WINDOWREPORT) {
2440     DispGetRootWinSize(&x, &y);
2441     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "9;%d;%dt", CLocale, y, x);
2442     SendCSIstr(Report, len);
2443     }
2444     break;
2445 doda 6174
2446 doda 6173 case 20: // Report icon label
2447     switch (ts.WindowFlag & WF_TITLEREPORT) {
2448     case IdTitleReportIgnore:
2449     // nothing to do
2450     break;
2451 doda 6174
2452 doda 6173 case IdTitleReportAccept:
2453     switch (ts.AcceptTitleChangeRequest) {
2454     case IdTitleChangeRequestOff:
2455     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s", CLocale, ts.Title);
2456     break;
2457 doda 6174
2458 doda 6173 case IdTitleChangeRequestAhead:
2459     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, cv.TitleRemote, ts.Title);
2460     break;
2461 doda 6174
2462 doda 6173 case IdTitleChangeRequestLast:
2463     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "L%s %s", CLocale, ts.Title, cv.TitleRemote);
2464     break;
2465 doda 6174
2466 doda 6173 default:
2467     if (cv.TitleRemote[0] == 0) {
2468     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE