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