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 8598 - (hide annotations) (download) (as text)
Sun Mar 15 15:24:18 2020 UTC (4 years ago) by zmatsuo
File MIME type: text/x-csrc
File size: 150459 byte(s)
結合文字等を遅れて受信した際正しく表示されるよう修正

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