Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/vtterm.c

Parent Directory Parent Directory | Revision Log Revision Log


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