Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8766 - (hide annotations) (download) (as text)
Wed May 6 14:52:04 2020 UTC (3 years, 11 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 151826 byte(s)
CJK,2byte文字の入力をできるようにした

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