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