Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9315 - (hide annotations) (download) (as text)
Sun Jun 20 01:08:06 2021 UTC (2 years, 9 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 153150 byte(s)
TTTSet 構造体から CodePage メンバを削除

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