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 8750 - (hide annotations) (download) (as text)
Sun Apr 26 14:35:40 2020 UTC (3 years, 11 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 149255 byte(s)
デバグダイアログで描画APIのUnicode/ANSI切り替えができるようにした
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 doda 4256 void ParseFirst(BYTE b);
67    
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     if (ts.Language == IdKorean && ts.CodePage == 51949) {
925     #if 0
926     unsigned char buf[2];
927     int ret;
928     wchar_t wchar;
929     buf[0] = Kanji >> 8;
930     buf[1] = Kanji & 0xff;
931     ret = MultiByteToWideChar(51949, MB_ERR_INVALID_CHARS, (char *)buf, 2, &wchar, 1);
932     u32 = wchar;
933     #endif
934     u32 = MBCP_UTF32(Kanji, ts.CodePage);
935     } else if (ts.Language == IdJapanese && ts.CodePage == 932) {
936     // �������������_��CP932������������
937     //} else if (ts.KanjiCode == IdSJIS || ts.KanjiCode == IdEUC || ts.KanjiCode == IdJIS) {
938     u32 = CP932ToUTF32(Kanji);
939     } else {
940     u32 = MBCP_UTF32(Kanji, ts.CodePage);
941     }
942     CharAttrTmp.AttrEx = CharAttrTmp.Attr;
943     BuffPutUnicode(u32, CharAttrTmp, InsertMode);
944     }
945     #else
946 doda 6802 BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
947 doda 8445 #endif
948 maya 3227
949 doda 6802 if (CursorX < LineEnd - 1) {
950     MoveRight();
951     MoveRight();
952     }
953     else {
954 doda 8103 if (CursorX == LineEnd - 1) {
955     MoveRight();
956     }
957 doda 6802 UpdateStr();
958     Wrap = AutoWrapMode;
959     }
960 maya 3227 }
961    
962     void PutDebugChar(BYTE b)
963     {
964 yutakapon 3637 static BYTE buff[3];
965 doda 5589 int i;
966     BOOL svInsertMode, svAutoWrapMode;
967     BYTE svCharAttr;
968 yutakapon 3637
969 doda 5589 if (DebugFlag!=DEBUG_FLAG_NOUT) {
970     svInsertMode = InsertMode;
971     svAutoWrapMode = AutoWrapMode;
972 doda 5588 InsertMode = FALSE;
973     AutoWrapMode = TRUE;
974 maya 3227
975 doda 5589 svCharAttr = CharAttr.Attr;
976     if (CharAttr.Attr != AttrDefault) {
977     UpdateStr();
978     CharAttr.Attr = AttrDefault;
979     }
980    
981 doda 5588 if (DebugFlag==DEBUG_FLAG_HEXD) {
982     _snprintf(buff, 3, "%02X", (unsigned int) b);
983 yutakapon 3637
984 doda 5589 for (i=0; i<2; i++)
985 doda 5588 PutChar(buff[i]);
986     PutChar(' ');
987     }
988     else if (DebugFlag==DEBUG_FLAG_NORM) {
989 yutakapon 3637
990 doda 5588 if ((b & 0x80) == 0x80) {
991     UpdateStr();
992     CharAttr.Attr = AttrReverse;
993     b = b & 0x7f;
994     }
995 maya 3227
996 doda 5588 if (b<=US) {
997     PutChar('^');
998     PutChar((char)(b+0x40));
999     }
1000     else if (b==DEL) {
1001     PutChar('<');
1002     PutChar('D');
1003     PutChar('E');
1004     PutChar('L');
1005     PutChar('>');
1006     }
1007     else
1008     PutChar(b);
1009     }
1010 maya 3227
1011 doda 5589 if (CharAttr.Attr != svCharAttr) {
1012 doda 5588 UpdateStr();
1013 doda 5589 CharAttr.Attr = svCharAttr;
1014 doda 5588 }
1015 doda 5589 InsertMode = svInsertMode;
1016     AutoWrapMode = svAutoWrapMode;
1017 yutakapon 3637 }
1018 maya 3227 }
1019    
1020 doda 8445 static void PrnParseControl(BYTE b) // printer mode
1021 maya 3227 {
1022 doda 6802 switch (b) {
1023     case NUL:
1024     return;
1025     case SO:
1026 doda 6913 if ((ts.ISO2022Flag & ISO2022_SO) && ! DirectPrn) {
1027 doda 6802 if ((ts.Language==IdJapanese) &&
1028     (ts.KanjiCode==IdJIS) &&
1029     (ts.JIS7Katakana==1) &&
1030     ((ts.TermFlag & TF_FIXEDJIS)!=0))
1031     {
1032     Gn[1] = IdKatakana;
1033     }
1034     Glr[0] = 1; /* LS1 */
1035     return;
1036     }
1037     break;
1038     case SI:
1039 doda 6913 if ((ts.ISO2022Flag & ISO2022_SI) && ! DirectPrn) {
1040 doda 6802 Glr[0] = 0; /* LS0 */
1041     return;
1042     }
1043     break;
1044     case DC1:
1045     case DC3:
1046     return;
1047     case ESC:
1048     ICount = 0;
1049     JustAfterESC = TRUE;
1050     ParseMode = ModeESC;
1051     WriteToPrnFile(0, TRUE); // flush prn buff
1052     return;
1053     case CSI:
1054     if (! Accept8BitCtrl) {
1055     PutChar(b); /* Disp C1 char in VT100 mode */
1056     return;
1057     }
1058     ClearParams();
1059     FirstPrm = TRUE;
1060     ParseMode = ModeCSI;
1061     WriteToPrnFile(0, TRUE); // flush prn buff
1062     WriteToPrnFile(b, FALSE);
1063     return;
1064     }
1065     /* send the uninterpreted character to printer */
1066     WriteToPrnFile(b, TRUE);
1067 maya 3227 }
1068    
1069 doda 8445 static void ParseControl(BYTE b)
1070 maya 3227 {
1071 doda 6802 if (PrinterMode) { // printer mode
1072     PrnParseControl(b);
1073     return;
1074     }
1075 maya 3227
1076 doda 6802 if (b>=0x80) { /* C1 char */
1077     if (ts.Language==IdEnglish) { /* English mode */
1078     if (!Accept8BitCtrl) {
1079     PutChar(b); /* Disp C1 char in VT100 mode */
1080     return;
1081     }
1082     }
1083     else { /* Japanese mode */
1084     if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0) {
1085     return; /* ignore C1 char */
1086     }
1087     /* C1 chars are interpreted as C0 chars in VT100 mode */
1088     if (VTlevel < 2) {
1089     b = b & 0x7F;
1090     }
1091     }
1092     }
1093     switch (b) {
1094     /* C0 group */
1095     case ENQ:
1096     CommBinaryOut(&cv, &(ts.Answerback[0]), ts.AnswerbackLen);
1097     break;
1098     case BEL:
1099     if (ts.Beep != IdBeepOff)
1100     RingBell(ts.Beep);
1101     break;
1102     case BS:
1103     BackSpace();
1104     break;
1105     case HT:
1106     Tab();
1107     break;
1108     case LF:
1109 maya 3227 if (ts.CRReceive == IdLF) {
1110 maya 4893 // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
1111     // CR+LF���������������������B
1112     // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
1113     // (2007.1.21 yutaka)
1114 maya 3227 CarriageReturn(TRUE);
1115     LineFeed(b, TRUE);
1116     break;
1117     }
1118 maya 4893 else if (ts.CRReceive == IdAUTO) {
1119     // 9th Apr 2012: AUTO CR/LF mode (tentner)
1120     // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
1121     if(PrevCharacter != CR || !PrevCRorLFGeneratedCRLF) {
1122     CarriageReturn(TRUE);
1123     LineFeed(b, TRUE);
1124     PrevCRorLFGeneratedCRLF = TRUE;
1125     }
1126     else {
1127     PrevCRorLFGeneratedCRLF = FALSE;
1128     }
1129     break;
1130     }
1131 maya 3227
1132 doda 6802 case VT:
1133     LineFeed(b, TRUE);
1134     break;
1135 maya 3227
1136 doda 6802 case FF:
1137     if ((ts.AutoWinSwitch>0) && JustAfterESC) {
1138     CommInsert1Byte(&cv, b);
1139     CommInsert1Byte(&cv, ESC);
1140     ChangeEmu = IdTEK; /* Enter TEK Mode */
1141     }
1142     else
1143     LineFeed(b, TRUE);
1144     break;
1145     case CR:
1146     if (ts.CRReceive == IdAUTO) {
1147     // 9th Apr 2012: AUTO CR/LF mode (tentner)
1148     // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
1149     if(PrevCharacter != LF || !PrevCRorLFGeneratedCRLF) {
1150     CarriageReturn(TRUE);
1151     LineFeed(b, TRUE);
1152     PrevCRorLFGeneratedCRLF = TRUE;
1153     }
1154     else {
1155     PrevCRorLFGeneratedCRLF = FALSE;
1156     }
1157     }
1158     else {
1159     CarriageReturn(TRUE);
1160     if (ts.CRReceive==IdCRLF) {
1161     CommInsert1Byte(&cv, LF);
1162     }
1163     }
1164     break;
1165     case SO: /* LS1 */
1166 doda 6913 if (ts.ISO2022Flag & ISO2022_SO) {
1167 doda 6804 if ((ts.Language==IdJapanese) &&
1168     (ts.KanjiCode==IdJIS) &&
1169     (ts.JIS7Katakana==1) &&
1170     ((ts.TermFlag & TF_FIXEDJIS)!=0))
1171     {
1172     Gn[1] = IdKatakana;
1173     }
1174 maya 3227
1175 doda 6804 Glr[0] = 1;
1176     }
1177 doda 6802 break;
1178     case SI: /* LS0 */
1179 doda 6913 if (ts.ISO2022Flag & ISO2022_SI) {
1180 doda 6804 Glr[0] = 0;
1181     }
1182 doda 6802 break;
1183     case DLE:
1184     if ((ts.FTFlag & FT_BPAUTO)!=0)
1185     ParseMode = ModeDLE; /* Auto B-Plus activation */
1186     break;
1187     case CAN:
1188     if ((ts.FTFlag & FT_ZAUTO)!=0)
1189     ParseMode = ModeCAN; /* Auto ZMODEM activation */
1190     // else if (ts.AutoWinSwitch>0)
1191     // ChangeEmu = IdTEK; /* Enter TEK Mode */
1192     else
1193     ParseMode = ModeFirst;
1194     break;
1195     case SUB:
1196     ParseMode = ModeFirst;
1197     break;
1198     case ESC:
1199     ICount = 0;
1200     JustAfterESC = TRUE;
1201     ParseMode = ModeESC;
1202     break;
1203     case FS:
1204     case GS:
1205     case RS:
1206     case US:
1207     if (ts.AutoWinSwitch>0) {
1208     CommInsert1Byte(&cv, b);
1209     ChangeEmu = IdTEK; /* Enter TEK Mode */
1210     }
1211     break;
1212 maya 3227
1213 doda 6802 /* C1 char */
1214     case IND:
1215     LineFeed(0, TRUE);
1216     break;
1217     case NEL:
1218     LineFeed(0, TRUE);
1219     CarriageReturn(TRUE);
1220     break;
1221     case HTS:
1222     if (ts.TabStopFlag & TABF_HTS8)
1223     SetTabStop();
1224     break;
1225     case RI:
1226     CursorUpWithScroll();
1227     break;
1228     case SS2:
1229 doda 6913 if (ts.ISO2022Flag & ISO2022_SS2) {
1230     GLtmp = 2;
1231     SSflag = TRUE;
1232     }
1233 doda 6802 break;
1234     case SS3:
1235 doda 6913 if (ts.ISO2022Flag & ISO2022_SS3) {
1236     GLtmp = 3;
1237     SSflag = TRUE;
1238     }
1239 doda 6802 break;
1240     case DCS:
1241     ClearParams();
1242     ESCFlag = FALSE;
1243     ParseMode = ModeDCS;
1244     break;
1245     case SOS:
1246     ESCFlag = FALSE;
1247     ParseMode = ModeIgnore;
1248     break;
1249     case CSI:
1250     ClearParams();
1251     FirstPrm = TRUE;
1252     ParseMode = ModeCSI;
1253     break;
1254     case OSC:
1255     ClearParams();
1256     ParseMode = ModeXS;
1257     break;
1258     case PM:
1259     case APC:
1260     ESCFlag = FALSE;
1261     ParseMode = ModeIgnore;
1262     break;
1263     }
1264 maya 3227 }
1265    
1266     void SaveCursor()
1267     {
1268 doda 6802 int i;
1269     PStatusBuff Buff;
1270 maya 3227
1271 doda 6802 if (isCursorOnStatusLine)
1272     Buff = &SBuff2; // for status line
1273     else if (AltScr)
1274     Buff = &SBuff3; // for alternate screen
1275     else
1276     Buff = &SBuff1; // for main screen
1277 maya 3227
1278 doda 6802 Buff->CursorX = CursorX;
1279     Buff->CursorY = CursorY;
1280     Buff->Attr = CharAttr;
1281    
1282     Buff->Glr[0] = Glr[0];
1283     Buff->Glr[1] = Glr[1];
1284     for (i=0 ; i<=3; i++)
1285     Buff->Gn[i] = Gn[i];
1286    
1287     Buff->AutoWrapMode = AutoWrapMode;
1288     Buff->RelativeOrgMode = RelativeOrgMode;
1289 maya 3227 }
1290    
1291 doda 6802 void RestoreCursor()
1292 maya 3227 {
1293 doda 6802 int i;
1294     PStatusBuff Buff;
1295 maya 3227
1296 doda 6802 UpdateStr();
1297 maya 3227
1298 doda 6802 if (isCursorOnStatusLine)
1299     Buff = &SBuff2; // for status line
1300     else if (AltScr)
1301     Buff = &SBuff3; // for alternate screen
1302     else
1303     Buff = &SBuff1; // for main screen
1304    
1305     if (Buff->CursorX > NumOfColumns-1)
1306     Buff->CursorX = NumOfColumns-1;
1307     if (Buff->CursorY > NumOfLines-1-StatusLine)
1308     Buff->CursorY = NumOfLines-1-StatusLine;
1309     MoveCursor(Buff->CursorX, Buff->CursorY);
1310    
1311     CharAttr = Buff->Attr;
1312     BuffSetCurCharAttr(CharAttr);
1313    
1314     Glr[0] = Buff->Glr[0];
1315     Glr[1] = Buff->Glr[1];
1316     for (i=0 ; i<=3; i++)
1317     Gn[i] = Buff->Gn[i];
1318    
1319     AutoWrapMode = Buff->AutoWrapMode;
1320     RelativeOrgMode = Buff->RelativeOrgMode;
1321 maya 3227 }
1322    
1323     void AnswerTerminalType()
1324     {
1325 doda 6802 char Tmp[50];
1326 maya 3227
1327 doda 6802 if (ts.TerminalID<IdVT320 || !Send8BitMode)
1328     strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1329     else
1330     strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1331 maya 3227
1332 doda 6802 switch (ts.TerminalID) {
1333     case IdVT100:
1334     strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1335     break;
1336     case IdVT100J:
1337     strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1338     break;
1339     case IdVT101:
1340     strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1341     break;
1342     case IdVT102:
1343     strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1344     break;
1345     case IdVT102J:
1346     strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1347     break;
1348     case IdVT220J:
1349     strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1350     break;
1351     case IdVT282:
1352     strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1353     break;
1354     case IdVT320:
1355     strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1356     break;
1357     case IdVT382:
1358     strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1359     break;
1360     case IdVT420:
1361     strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1362     break;
1363     case IdVT520:
1364     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1365     break;
1366     case IdVT525:
1367     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1368     break;
1369     }
1370     strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1371 maya 3227
1372 doda 6802 CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1373 maya 3227 }
1374    
1375     void ESCSpace(BYTE b)
1376     {
1377 doda 6802 switch (b) {
1378     case 'F': // S7C1T
1379     Send8BitMode = FALSE;
1380     break;
1381     case 'G': // S8C1T
1382     if (VTlevel >= 2) {
1383     Send8BitMode = TRUE;
1384     }
1385     break;
1386     }
1387 maya 3227 }
1388    
1389     void ESCSharp(BYTE b)
1390     {
1391 doda 6802 switch (b) {
1392     case '8': /* Fill screen with "E" (DECALN) */
1393     BuffUpdateScroll();
1394     BuffFillWithE();
1395     CursorTop = 0;
1396     CursorBottom = NumOfLines-1-StatusLine;
1397     CursorLeftM = 0;
1398     CursorRightM = NumOfColumns - 1;
1399     MoveCursor(0, 0);
1400     ParseMode = ModeFirst;
1401     break;
1402     }
1403 maya 3227 }
1404    
1405     /* select double byte code set */
1406     void ESCDBCSSelect(BYTE b)
1407     {
1408 doda 6802 int Dist;
1409 maya 3227
1410 doda 6802 if (ts.Language!=IdJapanese) return;
1411 maya 3227
1412 doda 6802 switch (ICount) {
1413     case 1:
1414     if ((b=='@') || (b=='B'))
1415     {
1416     Gn[0] = IdKanji; /* Kanji -> G0 */
1417     if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1418     Glr[0] = 0; /* G0->GL */
1419     }
1420     break;
1421     case 2:
1422     /* Second intermediate char must be
1423     '(' or ')' or '*' or '+'. */
1424     Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1425     if ((b=='1') || (b=='3') ||
1426     (b=='@') || (b=='B'))
1427     {
1428     Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1429     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1430     (Dist==0))
1431     Glr[0] = 0; /* G0->GL */
1432     }
1433     break;
1434     }
1435 maya 3227 }
1436    
1437     void ESCSelectCode(BYTE b)
1438     {
1439 doda 6802 switch (b) {
1440     case '0':
1441     if (ts.AutoWinSwitch>0)
1442     ChangeEmu = IdTEK; /* enter TEK mode */
1443     break;
1444     }
1445 maya 3227 }
1446    
1447 doda 6802 /* select single byte code set */
1448 maya 3227 void ESCSBCSSelect(BYTE b)
1449     {
1450 doda 6802 int Dist;
1451 maya 3227
1452 doda 6802 /* Intermediate char must be '(' or ')' or '*' or '+'. */
1453     Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1454 maya 3227
1455 doda 6802 switch (b) {
1456     case '0': Gn[Dist] = IdSpecial; break;
1457     case '<': Gn[Dist] = IdASCII; break;
1458     case '>': Gn[Dist] = IdASCII; break;
1459     case 'A': Gn[Dist] = IdASCII; break;
1460     case 'B': Gn[Dist] = IdASCII; break;
1461     case 'H': Gn[Dist] = IdASCII; break;
1462     case 'I':
1463     if (ts.Language==IdJapanese)
1464     Gn[Dist] = IdKatakana;
1465     break;
1466     case 'J': Gn[Dist] = IdASCII; break;
1467     }
1468 maya 3227
1469 doda 6802 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) && (Dist==0))
1470     Glr[0] = 0; /* G0->GL */
1471 maya 3227 }
1472    
1473     void PrnParseEscape(BYTE b) // printer mode
1474     {
1475 doda 6802 int i;
1476 maya 3227
1477 doda 6802 ParseMode = ModeFirst;
1478     switch (ICount) {
1479     /* no intermediate char */
1480     case 0:
1481     switch (b) {
1482     case '[': /* CSI */
1483     ClearParams();
1484     FirstPrm = TRUE;
1485     WriteToPrnFile(ESC,FALSE);
1486     WriteToPrnFile('[',FALSE);
1487     ParseMode = ModeCSI;
1488     return;
1489     } /* end of case Icount=0 */
1490     break;
1491     /* one intermediate char */
1492     case 1:
1493     switch (IntChar[1]) {
1494     case '$':
1495     if (! DirectPrn) {
1496     ESCDBCSSelect(b);
1497     return;
1498     }
1499     break;
1500     case '(':
1501     case ')':
1502     case '*':
1503     case '+':
1504     if (! DirectPrn) {
1505     ESCSBCSSelect(b);
1506     return;
1507     }
1508     break;
1509     }
1510     break;
1511     /* two intermediate char */
1512     case 2:
1513     if ((! DirectPrn) &&
1514     (IntChar[1]=='$') &&
1515     ('('<=IntChar[2]) &&
1516     (IntChar[2]<='+'))
1517     {
1518     ESCDBCSSelect(b);
1519     return;
1520     }
1521     break;
1522     }
1523     // send the uninterpreted sequence to printer
1524     WriteToPrnFile(ESC,FALSE);
1525     for (i=1; i<=ICount; i++)
1526     WriteToPrnFile(IntChar[i],FALSE);
1527     WriteToPrnFile(b,TRUE);
1528 maya 3227 }
1529    
1530     void ParseEscape(BYTE b) /* b is the final char */
1531     {
1532 doda 6802 if (PrinterMode) { // printer mode
1533     PrnParseEscape(b);
1534     return;
1535     }
1536 maya 3227
1537 doda 6802 switch (ICount) {
1538     case 0: /* no intermediate char */
1539     switch (b) {
1540     case '6': // DECBI
1541     if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1542     CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1543     if (CursorX == CursorLeftM)
1544     BuffScrollRight(1);
1545     else
1546     MoveCursor(CursorX-1, CursorY);
1547     }
1548     break;
1549     case '7': SaveCursor(); break;
1550     case '8': RestoreCursor(); break;
1551     case '9': // DECFI
1552     if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1553     CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1554     if (CursorX == CursorRightM)
1555     BuffScrollLeft(1);
1556     else
1557     MoveCursor(CursorX+1, CursorY);
1558     }
1559     break;
1560     case '=': AppliKeyMode = TRUE; break;
1561     case '>': AppliKeyMode = FALSE; break;
1562     case 'D': /* IND */
1563     LineFeed(0,TRUE);
1564     break;
1565     case 'E': /* NEL */
1566     MoveCursor(0,CursorY);
1567     LineFeed(0,TRUE);
1568     break;
1569     case 'H': /* HTS */
1570     if (ts.TabStopFlag & TABF_HTS7)
1571     SetTabStop();
1572     break;
1573     case 'M': /* RI */
1574     CursorUpWithScroll();
1575     break;
1576     case 'N': /* SS2 */
1577 doda 6913 if (ts.ISO2022Flag & ISO2022_SS2) {
1578     GLtmp = 2;
1579     SSflag = TRUE;
1580     }
1581 doda 6802 break;
1582     case 'O': /* SS3 */
1583 doda 6913 if (ts.ISO2022Flag & ISO2022_SS3) {
1584     GLtmp = 3;
1585     SSflag = TRUE;
1586     }
1587 doda 6802 break;
1588     case 'P': /* DCS */
1589     ClearParams();
1590     ESCFlag = FALSE;
1591     ParseMode = ModeDCS;
1592     return;
1593     case 'X': /* SOS */
1594     case '^': /* APC */
1595     case '_': /* PM */
1596     ESCFlag = FALSE;
1597     ParseMode = ModeIgnore;
1598     return;
1599     case 'Z': /* DECID */
1600     AnswerTerminalType();
1601     break;
1602     case '[': /* CSI */
1603     ClearParams();
1604     FirstPrm = TRUE;
1605     ParseMode = ModeCSI;
1606     return;
1607     case '\\': break; /* ST */
1608     case ']': /* XTERM sequence (OSC) */
1609     ClearParams();
1610     ParseMode = ModeXS;
1611     return;
1612     case 'c': /* Hardware reset */
1613     HideStatusLine();
1614     ResetTerminal();
1615     ClearUserKey();
1616     ClearBuffer();
1617     if (ts.PortType==IdSerial) // reset serial port
1618     CommResetSerial(&ts, &cv, TRUE);
1619     break;
1620     case 'g': /* Visual Bell (screen original?) */
1621     RingBell(IdBeepVisual);
1622     break;
1623 doda 6913 case 'n': /* LS2 */
1624     if (ts.ISO2022Flag & ISO2022_LS2) {
1625     Glr[0] = 2;
1626     }
1627     break;
1628     case 'o': /* LS3 */
1629     if (ts.ISO2022Flag & ISO2022_LS3) {
1630     Glr[0] = 3;
1631     }
1632     break;
1633     case '|': /* LS3R */
1634     if (ts.ISO2022Flag & ISO2022_LS3R) {
1635     Glr[1] = 3;
1636     }
1637     break;
1638     case '}': /* LS2R */
1639     if (ts.ISO2022Flag & ISO2022_LS2R) {
1640     Glr[1] = 2;
1641     }
1642     break;
1643     case '~': /* LS1R */
1644     if (ts.ISO2022Flag & ISO2022_LS1R) {
1645     Glr[1] = 1;
1646     }
1647     break;
1648 doda 6802 }
1649     break;
1650     /* end of case Icount=0 */
1651    
1652     case 1: /* one intermediate char */
1653     switch (IntChar[1]) {
1654     case ' ': ESCSpace(b); break;
1655     case '#': ESCSharp(b); break;
1656     case '$': ESCDBCSSelect(b); break;
1657     case '%': break;
1658     case '(':
1659     case ')':
1660     case '*':
1661     case '+':
1662     ESCSBCSSelect(b);
1663     break;
1664     }
1665     break;
1666    
1667     case 2: /* two intermediate char */
1668     if ((IntChar[1]=='$') && ('('<=IntChar[2]) && (IntChar[2]<='+'))
1669     ESCDBCSSelect(b);
1670     else if ((IntChar[1]=='%') && (IntChar[2]=='!'))
1671     ESCSelectCode(b);
1672     break;
1673     }
1674     ParseMode = ModeFirst;
1675 maya 3227 }
1676    
1677     void EscapeSequence(BYTE b)
1678     {
1679 doda 6173 if (b<=US)
1680     ParseControl(b);
1681     else if ((b>=0x20) && (b<=0x2F)) {
1682 doda 6174 // TODO: ICount �� IntCharMax ���B�������A������ IntChar ���u����������������?
1683 doda 6173 if (ICount<IntCharMax)
1684     ICount++;
1685     IntChar[ICount] = b;
1686     }
1687     else if ((b>=0x30) && (b<=0x7E))
1688     ParseEscape(b);
1689     else if ((b>=0x80) && (b<=0x9F))
1690     ParseControl(b);
1691     else if (b>=0xA0) {
1692     ParseMode=ModeFirst;
1693     ParseFirst(b);
1694     }
1695 maya 3227
1696 doda 6173 JustAfterESC = FALSE;
1697 maya 3227 }
1698    
1699 doda 6174 #define CheckParamVal(p,m) \
1700     if ((p) == 0) { \
1701     (p) = 1; \
1702     } \
1703     else if ((p) > (m) || p < 0) { \
1704     (p) = (m); \
1705     }
1706    
1707     #define CheckParamValMax(p,m) \
1708     if ((p) > (m) || p <= 0) { \
1709     (p) = (m); \
1710     }
1711    
1712     #define RequiredParams(n) \
1713     if ((n) > 1) { \
1714     while (NParam < n) { \
1715     NParam++; \
1716     Param[NParam] = 0; \
1717     NSParam[NParam] = 0; \
1718     } \
1719     }
1720    
1721 doda 8445 // ICH
1722     static void CSInsertCharacter(void)
1723 doda 6173 {
1724     // Insert space characters at cursor
1725 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1726 maya 3227
1727 doda 6173 BuffUpdateScroll();
1728 doda 6174 BuffInsertSpace(Param[1]);
1729 doda 6173 }
1730 maya 3227
1731 doda 5429 void CSCursorUp(BOOL AffectMargin) // CUU / VPB
1732     {
1733     int topMargin, NewY;
1734 maya 3227
1735 doda 6174 CheckParamVal(Param[1], CursorY);
1736 maya 3227
1737 doda 5429 if (AffectMargin && CursorY >= CursorTop)
1738     topMargin = CursorTop;
1739     else
1740     topMargin = 0;
1741 maya 3227
1742 doda 5429 NewY = CursorY - Param[1];
1743     if (NewY < topMargin)
1744     NewY = topMargin;
1745 maya 3227
1746 doda 5429 MoveCursor(CursorX, NewY);
1747     }
1748 maya 3227
1749 doda 5429 void CSCursorUp1() // CPL
1750     {
1751     MoveCursor(CursorLeftM, CursorY);
1752     CSCursorUp(TRUE);
1753     }
1754 maya 3227
1755 doda 5429 void CSCursorDown(BOOL AffectMargin) // CUD / VPR
1756     {
1757     int bottomMargin, NewY;
1758    
1759     if (AffectMargin && CursorY <= CursorBottom)
1760     bottomMargin = CursorBottom;
1761     else
1762     bottomMargin = NumOfLines-StatusLine-1;
1763    
1764 doda 6174 CheckParamVal(Param[1], bottomMargin);
1765    
1766 doda 5429 NewY = CursorY + Param[1];
1767     if (NewY > bottomMargin)
1768     NewY = bottomMargin;
1769    
1770     MoveCursor(CursorX, NewY);
1771     }
1772    
1773     void CSCursorDown1() // CNL
1774     {
1775     MoveCursor(CursorLeftM, CursorY);
1776     CSCursorDown(TRUE);
1777     }
1778    
1779 maya 3227 void CSScreenErase()
1780     {
1781     BuffUpdateScroll();
1782     switch (Param[1]) {
1783 doda 6173 case 0:
1784 maya 3227 // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1785     // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1786     // �����������������B(2005.5.29 yutaka)
1787     // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1788 doda 6435 if (ts.ScrollWindowClearScreen &&
1789 maya 3227 (CursorX == 0 && CursorY == 0)) {
1790 doda 6173 // Erase screen (scroll out)
1791 maya 3227 BuffClearScreen();
1792     UpdateWindow(HVTWin);
1793    
1794     } else {
1795 doda 6173 // Erase characters from cursor to the end of screen
1796 maya 3227 BuffEraseCurToEnd();
1797     }
1798     break;
1799    
1800 doda 6173 case 1:
1801     // Erase characters from home to cursor
1802 maya 3227 BuffEraseHomeToCur();
1803     break;
1804    
1805 doda 6173 case 2:
1806     // Erase screen (scroll out)
1807 maya 3227 BuffClearScreen();
1808     UpdateWindow(HVTWin);
1809 doda 5564 if (ClearThenHome && !isCursorOnStatusLine) {
1810     if (RelativeOrgMode) {
1811     MoveCursor(0, 0);
1812     }
1813     else {
1814     MoveCursor(CursorLeftM, CursorTop);
1815     }
1816     }
1817 maya 3227 break;
1818 doda 8383
1819     case 3:
1820     if (ts.TermFlag & TF_REMOTECLEARSBUFF) {
1821     ClearBuffer();
1822     }
1823     break;
1824 maya 3227 }
1825     }
1826    
1827 doda 4070 void CSQSelScreenErase()
1828     {
1829     BuffUpdateScroll();
1830     switch (Param[1]) {
1831 doda 6173 case 0:
1832     // Erase characters from cursor to end
1833 doda 4070 BuffSelectedEraseCurToEnd();
1834     break;
1835    
1836 doda 6173 case 1:
1837     // Erase characters from home to cursor
1838 doda 4070 BuffSelectedEraseHomeToCur();
1839     break;
1840    
1841 doda 6173 case 2:
1842     // Erase entire screen
1843 doda 4070 BuffSelectedEraseScreen();
1844     break;
1845 doda 8383
1846     case 3:
1847     if (ts.TermFlag & TF_REMOTECLEARSBUFF) {
1848     ClearBuffer();
1849     }
1850     break;
1851 doda 4070 }
1852     }
1853    
1854 doda 6173 void CSInsertLine()
1855     {
1856     // Insert lines at current position
1857     int Count, YEnd;
1858 maya 3227
1859 doda 6174 if (CursorY < CursorTop || CursorY > CursorBottom) {
1860 doda 6173 return;
1861 doda 6174 }
1862 maya 3227
1863 doda 6174 CheckParamVal(Param[1], NumOfLines);
1864    
1865 doda 6173 Count = Param[1];
1866 maya 3227
1867 doda 6173 YEnd = CursorBottom;
1868     if (CursorY > YEnd)
1869     YEnd = NumOfLines-1-StatusLine;
1870 doda 6174
1871 doda 6173 if (Count > YEnd+1 - CursorY)
1872     Count = YEnd+1 - CursorY;
1873 maya 3227
1874 doda 6173 BuffInsertLines(Count,YEnd);
1875     }
1876 maya 3227
1877 doda 6173 void CSLineErase()
1878     {
1879     BuffUpdateScroll();
1880     switch (Param[1]) {
1881     case 0: /* erase char from cursor to end of line */
1882     BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1883     break;
1884 doda 4070
1885 doda 6173 case 1: /* erase char from start of line to cursor */
1886     BuffEraseCharsInLine(0,CursorX+1);
1887     break;
1888 maya 3227
1889 doda 6173 case 2: /* erase entire line */
1890     BuffEraseCharsInLine(0,NumOfColumns);
1891     break;
1892     }
1893     }
1894 maya 3227
1895 doda 8445 static void CSQSelLineErase(void)
1896 doda 6173 {
1897     BuffUpdateScroll();
1898     switch (Param[1]) {
1899     case 0: /* erase char from cursor to end of line */
1900     BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
1901     break;
1902 maya 3227
1903 doda 6173 case 1: /* erase char from start of line to cursor */
1904     BuffSelectedEraseCharsInLine(0,CursorX+1);
1905     break;
1906 maya 3227
1907 doda 6173 case 2: /* erase entire line */
1908     BuffSelectedEraseCharsInLine(0,NumOfColumns);
1909     break;
1910     }
1911     }
1912 maya 3227
1913 doda 6173 void CSDeleteNLines()
1914     // Delete lines from current line
1915     {
1916     int Count, YEnd;
1917 maya 3227
1918 doda 6174 if (CursorY < CursorTop || CursorY > CursorBottom) {
1919 doda 6173 return;
1920 doda 6174 }
1921    
1922     CheckParamVal(Param[1], NumOfLines);
1923 doda 6173 Count = Param[1];
1924 maya 3227
1925 doda 6173 YEnd = CursorBottom;
1926     if (CursorY > YEnd)
1927     YEnd = NumOfLines-1-StatusLine;
1928 doda 6174
1929 doda 6173 if (Count > YEnd+1-CursorY)
1930     Count = YEnd+1-CursorY;
1931 doda 6174
1932 doda 6173 BuffDeleteLines(Count,YEnd);
1933     }
1934 maya 3227
1935 doda 8445 // DCH
1936     static void CSDeleteCharacter(void)
1937 doda 6173 {
1938     // Delete characters in current line from cursor
1939 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1940 maya 3227
1941 doda 6173 BuffUpdateScroll();
1942     BuffDeleteChars(Param[1]);
1943     }
1944 maya 3227
1945 doda 8445 // ECH
1946     static void CSEraseCharacter(void)
1947 doda 6173 {
1948 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1949    
1950 doda 6173 BuffUpdateScroll();
1951     BuffEraseChars(Param[1]);
1952     }
1953    
1954 doda 8329 void CSRepeatCharacter()
1955     {
1956     CheckParamVal(Param[1], NumOfColumns * NumOfLines);
1957    
1958     BuffUpdateScroll();
1959     RepeatChar(LastPutCharacter, Param[1]);
1960     }
1961    
1962 doda 6173 void CSScrollUp()
1963     {
1964 doda 6174 // TODO: �X�N���[���������l���[���s�����������������v����
1965     CheckParamVal(Param[1], INT_MAX);
1966    
1967 doda 6173 BuffUpdateScroll();
1968     BuffRegionScrollUpNLines(Param[1]);
1969     }
1970    
1971     void CSScrollDown()
1972     {
1973 doda 6174 CheckParamVal(Param[1], NumOfLines);
1974    
1975 doda 6173 BuffUpdateScroll();
1976     BuffRegionScrollDownNLines(Param[1]);
1977     }
1978    
1979     void CSForwardTab()
1980     {
1981 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1982 doda 6173 CursorForwardTab(Param[1], AutoWrapMode);
1983     }
1984    
1985     void CSBackwardTab()
1986     {
1987 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1988 doda 6173 CursorBackwardTab(Param[1]);
1989     }
1990    
1991 doda 5324 void CSMoveToColumnN() // CHA / HPA
1992     {
1993 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1994 maya 3227
1995 doda 5324 Param[1]--;
1996 maya 3227
1997 doda 5324 if (RelativeOrgMode) {
1998     if (CursorLeftM + Param[1] > CursorRightM )
1999     MoveCursor(CursorRightM, CursorY);
2000     else
2001     MoveCursor(CursorLeftM + Param[1], CursorY);
2002     }
2003     else {
2004     MoveCursor(Param[1], CursorY);
2005     }
2006     }
2007 maya 3227
2008 doda 5429 void CSCursorRight(BOOL AffectMargin) // CUF / HPR
2009 doda 5324 {
2010 doda 5429 int NewX, rightMargin;
2011 doda 5324
2012 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2013 doda 5324
2014 doda 6174 if (AffectMargin && CursorX <= CursorRightM) {
2015 doda 5429 rightMargin = CursorRightM;
2016 doda 6174 }
2017     else {
2018 doda 5429 rightMargin = NumOfColumns-1;
2019 doda 6174 }
2020 doda 5429
2021 doda 5324 NewX = CursorX + Param[1];
2022 doda 5429 if (NewX > rightMargin)
2023     NewX = rightMargin;
2024 doda 5324
2025     MoveCursor(NewX, CursorY);
2026     }
2027    
2028 doda 5429 void CSCursorLeft(BOOL AffectMargin) // CUB / HPB
2029 doda 5324 {
2030 doda 5429 int NewX, leftMargin;
2031 doda 5324
2032 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2033 doda 5324
2034 doda 6174 if (AffectMargin && CursorX >= CursorLeftM) {
2035 doda 5429 leftMargin = CursorLeftM;
2036 doda 6174 }
2037     else {
2038 doda 5429 leftMargin = 0;
2039 doda 6174 }
2040 doda 5324
2041 doda 5429 NewX = CursorX - Param[1];
2042 doda 6174 if (NewX < leftMargin) {
2043 doda 5429 NewX = leftMargin;
2044 doda 6174 }
2045 doda 5324
2046     MoveCursor(NewX, CursorY);
2047     }
2048    
2049 doda 6174 void CSMoveToLineN() // VPA
2050 doda 6173 {
2051 doda 6174 CheckParamVal(Param[1], NumOfLines-StatusLine);
2052    
2053 doda 6173 if (RelativeOrgMode) {
2054     if (CursorTop+Param[1]-1 > CursorBottom)
2055     MoveCursor(CursorX,CursorBottom);
2056     else
2057     MoveCursor(CursorX,CursorTop+Param[1]-1);
2058     }
2059     else {
2060     if (Param[1] > NumOfLines-StatusLine)
2061     MoveCursor(CursorX,NumOfLines-1-StatusLine);
2062     else
2063     MoveCursor(CursorX,Param[1]-1);
2064     }
2065 doda 6602 Fallbacked = FALSE;
2066 doda 6173 }
2067 maya 3227
2068 doda 5324 void CSMoveToXY() // CUP / HVP
2069     {
2070     int NewX, NewY;
2071 maya 3227
2072 doda 6174 RequiredParams(2);
2073     CheckParamVal(Param[1], NumOfLines-StatusLine);
2074     CheckParamVal(Param[2], NumOfColumns);
2075 maya 3227
2076 doda 5324 NewY = Param[1] - 1;
2077     NewX = Param[2] - 1;
2078    
2079     if (isCursorOnStatusLine)
2080     NewY = CursorY;
2081     else if (RelativeOrgMode) {
2082     NewX += CursorLeftM;
2083     if (NewX > CursorRightM)
2084     NewX = CursorRightM;
2085    
2086     NewY += CursorTop;
2087     if (NewY > CursorBottom)
2088     NewY = CursorBottom;
2089     }
2090     else {
2091     if (NewY > NumOfLines-1-StatusLine)
2092     NewY = NumOfLines-1-StatusLine;
2093     }
2094    
2095     MoveCursor(NewX, NewY);
2096 doda 6602 Fallbacked = FALSE;
2097 doda 5324 }
2098    
2099 doda 6173 void CSDeleteTabStop()
2100     {
2101     ClearTabStop(Param[1]);
2102     }
2103 maya 3227
2104 doda 6173 void CS_h_Mode() // SM
2105     {
2106     switch (Param[1]) {
2107     case 2: // KAM
2108     KeybEnabled = FALSE; break;
2109     case 4: // IRM
2110     InsertMode = TRUE; break;
2111     case 12: // SRM
2112     ts.LocalEcho = 0;
2113     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
2114     TelChangeEcho();
2115     break;
2116     case 20: // LF/NL
2117     LFMode = TRUE;
2118     ts.CRSend = IdCRLF;
2119     cv.CRSend = IdCRLF;
2120     break;
2121     case 33: // WYSTCURM
2122     if (ts.WindowFlag & WF_CURSORCHANGE) {
2123     ts.NonblinkingCursor = TRUE;
2124     ChangeCaret();
2125     }
2126     break;
2127     case 34: // WYULCURM
2128     if (ts.WindowFlag & WF_CURSORCHANGE) {
2129     ts.CursorShape = IdHCur;
2130     ChangeCaret();
2131     }
2132     break;
2133     }
2134     }
2135 maya 3227
2136 doda 6173 void CS_i_Mode() // MC
2137     {
2138     switch (Param[1]) {
2139     /* print screen */
2140     // PrintEX -- TRUE: print screen
2141     // FALSE: scroll region
2142     case 0:
2143     if (ts.TermFlag&TF_PRINTERCTRL) {
2144     BuffPrint(! PrintEX);
2145     }
2146     break;
2147     /* printer controller mode off */
2148     case 4: break; /* See PrnParseCS() */
2149     /* printer controller mode on */
2150     case 5:
2151     if (ts.TermFlag&TF_PRINTERCTRL) {
2152     if (! AutoPrintMode)
2153     OpenPrnFile();
2154     DirectPrn = (ts.PrnDev[0]!=0);
2155     PrinterMode = TRUE;
2156     }
2157     break;
2158 doda 4397 }
2159 doda 6173 }
2160    
2161     void CS_l_Mode() // RM
2162     {
2163     switch (Param[1]) {
2164     case 2: // KAM
2165     KeybEnabled = TRUE; break;
2166     case 4: // IRM
2167     InsertMode = FALSE; break;
2168     case 12: // SRM
2169     ts.LocalEcho = 1;
2170     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
2171     TelChangeEcho();
2172     break;
2173     case 20: // LF/NL
2174     LFMode = FALSE;
2175     ts.CRSend = IdCR;
2176     cv.CRSend = IdCR;
2177     break;
2178     case 33: // WYSTCURM
2179     if (ts.WindowFlag & WF_CURSORCHANGE) {
2180     ts.NonblinkingCursor = FALSE;
2181     ChangeCaret();
2182     }
2183     break;
2184     case 34: // WYULCURM
2185     if (ts.WindowFlag & WF_CURSORCHANGE) {
2186     ts.CursorShape = IdBlkCur;
2187     ChangeCaret();
2188     }
2189     break;
2190 doda 4397 }
2191 doda 6173 }
2192 maya 3227
2193 doda 6173 void CS_n_Mode() // DSR
2194     {
2195     char Report[16];
2196     int X, Y, len;
2197 maya 3227
2198 doda 6173 switch (Param[1]) {
2199     case 5:
2200     /* Device Status Report -> Ready */
2201     SendCSIstr("0n", 0);
2202     break;
2203     case 6:
2204     /* Cursor Position Report */
2205     if (isCursorOnStatusLine) {
2206     X = CursorX + 1;
2207     Y = 1;
2208     }
2209     else if (RelativeOrgMode) {
2210     X = CursorX - CursorLeftM + 1;
2211     Y = CursorY - CursorTop + 1;
2212     }
2213     else {
2214     X = CursorX + 1;
2215     Y = CursorY+1;
2216     }
2217     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, X);
2218     SendCSIstr(Report, len);
2219     break;
2220 doda 5336 }
2221 doda 6173 }
2222 maya 3227
2223 doda 5095 void ParseSGRParams(PCharAttr attr, PCharAttr mask, int start)
2224 maya 3227 {
2225 doda 5073 int i, j, P, r, g, b, color;
2226 doda 5095 TCharAttr dummy;
2227 maya 3227
2228 doda 5095 if (mask == NULL) {
2229     mask = &dummy;
2230     }
2231    
2232 doda 6173 for (i=start ; i<=NParam ; i++) {
2233 maya 3227 P = Param[i];
2234     switch (P) {
2235 doda 6173 case 0: /* Clear all */
2236 doda 5095 attr->Attr = DefCharAttr.Attr;
2237     attr->Attr2 = DefCharAttr.Attr2 | (attr->Attr2&Attr2Protect);
2238 doda 8445 #if UNICODE_INTERNAL_BUFF
2239     attr->AttrEx = attr->Attr;
2240     #endif
2241 doda 5095 attr->Fore = DefCharAttr.Fore;
2242     attr->Back = DefCharAttr.Back;
2243     mask->Attr = AttrSgrMask;
2244     mask->Attr2 = Attr2ColorMask;
2245 maya 3227 break;
2246    
2247 doda 6173 case 1: /* Bold */
2248 doda 5095 attr->Attr |= AttrBold;
2249     mask->Attr |= AttrBold;
2250 maya 3227 break;
2251    
2252 doda 6173 case 4: /* Under line */
2253 doda 5095 attr->Attr |= AttrUnder;
2254     mask->Attr |= AttrUnder;
2255 maya 3227 break;
2256    
2257 doda 6173 case 5: /* Blink */
2258 doda 5095 attr->Attr |= AttrBlink;
2259     mask->Attr |= AttrBlink;
2260 maya 3227 break;
2261    
2262 doda 6173 case 7: /* Reverse */
2263 doda 5095 attr->Attr |= AttrReverse;
2264     mask->Attr |= AttrReverse;
2265 maya 3227 break;
2266    
2267 doda 6173 case 22: /* Bold off */
2268 doda 5095 attr->Attr &= ~ AttrBold;
2269     mask->Attr |= AttrBold;
2270 maya 3227 break;
2271    
2272 doda 6173 case 24: /* Under line off */
2273 doda 5095 attr->Attr &= ~ AttrUnder;
2274     mask->Attr |= AttrUnder;
2275 maya 3227 break;
2276    
2277 doda 6173 case 25: /* Blink off */
2278 doda 5095 attr->Attr &= ~ AttrBlink;
2279     mask->Attr |= AttrBlink;
2280 maya 3227 break;
2281    
2282 doda 6173 case 27: /* Reverse off */
2283 doda 5095 attr->Attr &= ~ AttrReverse;
2284     mask->Attr |= AttrReverse;
2285 maya 3227 break;
2286    
2287 doda 6173 case 30:
2288     case 31:
2289     case 32:
2290     case 33:
2291     case 34:
2292     case 35:
2293     case 36:
2294     case 37: /* text color */
2295 doda 5095 attr->Attr2 |= Attr2Fore;
2296     mask->Attr2 |= Attr2Fore;
2297     attr->Fore = P - 30;
2298 maya 3227 break;
2299    
2300 doda 6173 case 38: /* text color (256color mode) */
2301 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
2302     /*
2303     * Change foreground color. accept following formats.
2304     *
2305     * 38 ; 2 ; r ; g ; b
2306     * 38 ; 2 : r : g : b
2307     * 38 : 2 : r : g : b
2308     * 38 ; 5 ; idx
2309     * 38 ; 5 : idx
2310     * 38 : 5 : idx
2311     *
2312     */
2313     color = -1;
2314     j = 0;
2315     if (NSParam[i] > 0) {
2316     P = SubParam[i][1];
2317     j++;
2318     }
2319     else if (i < NParam) {
2320     P = Param[i+1];
2321     if (P == 2 || P == 5) {
2322     i++;
2323     }
2324     }
2325     switch (P) {
2326 doda 6173 case 2:
2327 doda 5073 r = g = b = 0;
2328     if (NSParam[i] > 0) {
2329     if (j < NSParam[i]) {
2330     r = SubParam[i][++j];
2331     if (j < NSParam[i]) {
2332     g = SubParam[i][++j];
2333     }
2334     if (j < NSParam[i]) {
2335     b = SubParam[i][++j];
2336     }
2337     color = DispFindClosestColor(r, g, b);
2338     }
2339     }
2340     else if (i < NParam && NSParam[i+1] > 0) {
2341     r = Param[++i];
2342     g = SubParam[i][1];
2343     if (NSParam[i] > 1) {
2344     b = SubParam[i][2];
2345     }
2346     color = DispFindClosestColor(r, g, b);
2347     }
2348     else if (i+2 < NParam) {
2349     r = Param[++i];
2350     g = Param[++i];
2351     b = Param[++i];
2352     color = DispFindClosestColor(r, g, b);
2353     }
2354     break;
2355 doda 6173 case 5:
2356 doda 5073 if (NSParam[i] > 0) {
2357     if (j < NSParam[i]) {
2358     color = SubParam[i][++j];
2359     }
2360     }
2361     else if (i < NParam) {
2362     color = Param[++i];
2363     }
2364     break;
2365     }
2366 doda 5077 if (color >= 0 && color < 256) {
2367 doda 5095 attr->Attr2 |= Attr2Fore;
2368     mask->Attr2 |= Attr2Fore;
2369     attr->Fore = color;
2370 maya 3227 }
2371     }
2372     break;
2373    
2374 doda 6173 case 39: /* Reset text color */
2375 doda 5095 attr->Attr2 &= ~ Attr2Fore;
2376     mask->Attr2 |= Attr2Fore;
2377     attr->Fore = AttrDefaultFG;
2378 maya 3227 break;
2379    
2380 doda 6173 case 40:
2381     case 41:
2382     case 42:
2383     case 43:
2384     case 44:
2385     case 45:
2386     case 46:
2387     case 47: /* Back color */
2388 doda 5095 attr->Attr2 |= Attr2Back;
2389     mask->Attr2 |= Attr2Back;
2390     attr->Back = P - 40;
2391 maya 3227 break;
2392    
2393 doda 6173 case 48: /* Back color (256color mode) */
2394 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
2395     color = -1;
2396     j = 0;
2397     if (NSParam[i] > 0) {
2398     P = SubParam[i][1];
2399     j++;
2400     }
2401     else if (i < NParam) {
2402     P = Param[i+1];
2403     if (P == 2 || P == 5) {
2404     i++;
2405     }
2406     }
2407     switch (P) {
2408 doda 6173 case 2:
2409 doda 5073 r = g = b = 0;
2410     if (NSParam[i] > 0) {
2411     if (j < NSParam[i]) {
2412     r = SubParam[i][++j];
2413     if (j < NSParam[i]) {
2414     g = SubParam[i][++j];
2415     }
2416     if (j < NSParam[i]) {
2417     b = SubParam[i][++j];
2418     }
2419     color = DispFindClosestColor(r, g, b);
2420     }
2421     }
2422     else if (i < NParam && NSParam[i+1] > 0) {
2423     r = Param[++i];
2424     g = SubParam[i][1];
2425     if (NSParam[i] > 1) {
2426     b = SubParam[i][2];
2427     }
2428     color = DispFindClosestColor(r, g, b);
2429     }
2430     else if (i+2 < NParam) {
2431     r = Param[++i];
2432     g = Param[++i];
2433     b = Param[++i];
2434     color = DispFindClosestColor(r, g, b);
2435     }
2436     break;
2437 doda 6173 case 5:
2438 doda 5073 if (NSParam[i] > 0) {
2439     if (j < NSParam[i]) {
2440     color = SubParam[i][++j];
2441     }
2442     }
2443     else if (i < NParam) {
2444     color = Param[++i];
2445     }
2446     break;
2447     }
2448 doda 5077 if (color >= 0 && color < 256) {
2449 doda 5095 attr->Attr2 |= Attr2Back;
2450     mask->Attr2 |= Attr2Back;
2451     attr->Back = color;
2452 maya 3227 }
2453     }
2454     break;
2455    
2456 doda 6173 case 49: /* Reset back color */
2457 doda 5095 attr->Attr2 &= ~ Attr2Back;
2458     mask->Attr2 |= Attr2Back;
2459     attr->Back = AttrDefaultBG;
2460 maya 3227 break;
2461    
2462 doda 6173 case 90:
2463     case 91:
2464     case 92:
2465     case 93:
2466     case 94:
2467     case 95:
2468     case 96:
2469     case 97: /* aixterm style text color */
2470 maya 3227 if (ts.ColorFlag & CF_AIXTERM16) {
2471 doda 5095 attr->Attr2 |= Attr2Fore;
2472     mask->Attr2 |= Attr2Fore;
2473     attr->Fore = P - 90 + 8;
2474 maya 3227 }
2475     break;
2476    
2477 doda 6173 case 100:
2478 maya 3227 if (! (ts.ColorFlag & CF_AIXTERM16)) {