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 9085 - (hide annotations) (download) (as text)
Sun Dec 20 12:12:31 2020 UTC (3 years, 3 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/vtterm.c
File MIME type: text/x-csrc
File size: 152963 byte(s)
BPlus の BPStart(), QuickVAN の QVStart() API を使用しないようにした

- BPSendStart(), BPStartReceive() に統一
- bplusダイアログ修正
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 <mbstring.h>
36     #include <locale.h>
37 doda 4225 #include <ctype.h>
38 zmatsuo 8391 #if !defined(_CRTDBG_MAP_ALLOC)
39     #define _CRTDBG_MAP_ALLOC
40     #endif
41     #include <stdlib.h>
42 zmatsuo 7405 #include <crtdbg.h>
43 doda 8445 #include <assert.h>
44 maya 3227
45     #include "buffer.h"
46     #include "ttwinman.h"
47     #include "ttcommon.h"
48     #include "commlib.h"
49     #include "vtdisp.h"
50     #include "keyboard.h"
51     #include "ttlib.h"
52     #include "ttftypes.h"
53     #include "filesys.h"
54     #include "teraprn.h"
55     #include "telnet.h"
56 doda 4278 #include "ttime.h"
57 doda 4769 #include "clipboar.h"
58 zmatsuo 7462 #include "codeconv.h"
59 zmatsuo 8750 #include "unicode.h"
60 zmatsuo 8860 #include "ttdde.h"
61 zmatsuo 8904 #include "checkeol.h"
62 maya 3227
63     #include "vtterm.h"
64    
65 doda 8445 #include "unicode_test.h"
66    
67 zmatsuo 8766 static void ParseFirst(BYTE b);
68 doda 4256
69 doda 4246 #define Accept8BitCtrl ((VTlevel >= 2) && (ts.TermFlag & TF_ACCEPT8BITCTRL))
70 doda 3443
71 maya 3227 /* Parsing modes */
72     #define ModeFirst 0
73     #define ModeESC 1
74     #define ModeDCS 2
75     #define ModeDCUserKey 3
76     #define ModeSOS 4
77     #define ModeCSI 5
78     #define ModeXS 6
79     #define ModeDLE 7
80     #define ModeCAN 8
81 doda 5911 #define ModeIgnore 9
82 maya 3227
83 doda 5073 #define NParamMax 16
84     #define NSParamMax 16
85     #define IntCharMax 5
86 maya 3227
87 doda 3997 /* DEC Locator Flag */
88     #define DecLocatorOneShot 1
89     #define DecLocatorPixel 2
90     #define DecLocatorButtonDown 4
91     #define DecLocatorButtonUp 8
92     #define DecLocatorFiltered 16
93    
94 doda 5316 void RingBell(int type);
95 maya 3227 void VisualBell();
96 doda 3999 BOOL DecLocatorReport(int Event, int Button);
97 maya 3227
98     /* character attribute */
99     static TCharAttr CharAttr;
100    
101     /* various modes of VT emulation */
102     static BOOL RelativeOrgMode;
103     static BOOL InsertMode;
104     static BOOL LFMode;
105 doda 5564 static BOOL ClearThenHome;
106 maya 3227 static BOOL AutoWrapMode;
107     static BOOL FocusReportMode;
108 doda 3743 static BOOL AltScr;
109 doda 5324 static BOOL LRMarginMode;
110 doda 7086 static BOOL RectangleMode;
111 doda 7140 static BOOL BracketedPaste;
112 maya 3227
113 zmatsuo 8822 static char BracketStart[] = "\033[200~";
114     static char BracketEnd[] = "\033[201~";
115     static int BracketStartLen = (sizeof(BracketStart)-1);
116     static int BracketEndLen = (sizeof(BracketEnd)-1);
117 doda 7140
118 doda 4246 static int VTlevel;
119    
120 zmatsuo 8822 static BOOL AcceptWheelToCursor;
121 doda 4293
122 maya 3227 // save/restore cursor
123     typedef struct {
124 doda 6802 int CursorX, CursorY;
125     TCharAttr Attr;
126     int Glr[2], Gn[4]; // G0-G3, GL & GR
127     BOOL AutoWrapMode;
128     BOOL RelativeOrgMode;
129 maya 3227 } TStatusBuff;
130     typedef TStatusBuff *PStatusBuff;
131    
132 maya 4893 // currently only used for AUTO CR/LF receive mode
133 zmatsuo 8822 static BYTE PrevCharacter;
134     static BOOL PrevCRorLFGeneratedCRLF; // indicates that previous CR or LF really generated a CR+LF
135 maya 4893
136 zmatsuo 8822 static BYTE LastPutCharacter;
137 doda 8329
138 maya 3227 // status buffer for main screen & status line
139 doda 3797 static TStatusBuff SBuff1, SBuff2, SBuff3;
140 maya 3227
141     static BOOL ESCFlag, JustAfterESC;
142 zmatsuo 8822 static BOOL KanjiIn; // TRUE = MBCS��1byte�������M��������
143 maya 3227 static BOOL EUCkanaIn, EUCsupIn;
144     static int EUCcount;
145     static BOOL Special;
146    
147     static int Param[NParamMax+1];
148 doda 5073 static int SubParam[NParamMax+1][NSParamMax+1];
149     static int NParam, NSParam[NParamMax+1];
150 maya 3227 static BOOL FirstPrm;
151     static BYTE IntChar[IntCharMax+1];
152     static int ICount;
153     static BYTE Prv;
154 doda 4291 static int ParseMode;
155 maya 3227 static int ChangeEmu;
156    
157 doda 5096 typedef struct tstack {
158 doda 6802 char *title;
159     struct tstack *next;
160 doda 5096 } TStack;
161     typedef TStack *PTStack;
162 zmatsuo 8822 static PTStack TitleStack = NULL;
163 doda 5096
164 maya 3227 /* user defined keys */
165     static BOOL WaitKeyId, WaitHi;
166    
167     /* GL, GR code group */
168     static int Glr[2];
169     /* G0, G1, G2, G3 code group */
170     static int Gn[4];
171     /* GL for single shift 2/3 */
172     static int GLtmp;
173     /* single shift 2/3 flag */
174     static BOOL SSflag;
175     /* JIS -> SJIS conversion flag */
176     static BOOL ConvJIS;
177     static WORD Kanji;
178 doda 6602 static BOOL Fallbacked;
179 maya 3227
180     // variables for status line mode
181     static int StatusX=0;
182     static BOOL StatusWrap=FALSE;
183     static BOOL StatusCursor=TRUE;
184     static int MainX, MainY; //cursor registers
185     static int MainTop, MainBottom; // scroll region registers
186     static BOOL MainWrap;
187     static BOOL MainCursor=TRUE;
188    
189     /* status for printer escape sequences */
190 doda 6802 static BOOL PrintEX = TRUE; // printing extent
191 maya 3227 // (TRUE: screen, FALSE: scroll region)
192     static BOOL AutoPrintMode = FALSE;
193     static BOOL PrinterMode = FALSE;
194     static BOOL DirectPrn = FALSE;
195    
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 zmatsuo 7405 char *result;
373 doda 6802 if (ts.Language==IdJapanese) {
374     Gn[0] = IdASCII;
375     Gn[1] = IdKatakana;
376     Gn[2] = IdKatakana;
377     Gn[3] = IdKanji;
378     Glr[0] = 0;
379     if ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0))
380     Glr[1] = 2; // 8-bit katakana
381     else
382     Glr[1] = 3;
383     }
384     else {
385     Gn[0] = IdASCII;
386     Gn[1] = IdSpecial;
387     Gn[2] = IdASCII;
388     Gn[3] = IdASCII;
389     Glr[0] = 0;
390     Glr[1] = 0;
391     cv.SendCode = IdASCII;
392     cv.SendKanjiFlag = FALSE;
393     cv.EchoCode = IdASCII;
394     cv.EchoKanjiFlag = FALSE;
395     }
396     /* Kanji flag */
397     KanjiIn = FALSE;
398     EUCkanaIn = FALSE;
399     EUCsupIn = FALSE;
400     SSflag = FALSE;
401     ConvJIS = FALSE;
402     Fallbacked = FALSE;
403 maya 3227
404 doda 6802 cv.Language = ts.Language;
405     cv.CRSend = ts.CRSend;
406     cv.KanjiCodeEcho = ts.KanjiCode;
407     cv.JIS7KatakanaEcho = ts.JIS7Katakana;
408     cv.KanjiCodeSend = ts.KanjiCodeSend;
409     cv.JIS7KatakanaSend = ts.JIS7KatakanaSend;
410     cv.KanjiIn = ts.KanjiIn;
411     cv.KanjiOut = ts.KanjiOut;
412 doda 7402
413 zmatsuo 7405 // ���P�[��������
414     // wctomb ������
415     result = setlocale(LC_ALL, ts.Locale);
416     if (result == NULL) {
417     // ��������Locale���������Z�b�g����������?
418     // default���Z�b�g��������
419     strcpy(ts.Locale, DEFAULT_LOCALE);
420     result = setlocale(LC_ALL, ts.Locale);
421     }
422 yutakapon 7983 // �p����Windows�����Ats.Locale���f�t�H���g��"japanese"�����������A
423     // setlocale�� NULL �����������ATera Term���N�������������Bstrrchr��
424     // ��1��������NULL���w���������������B
425     // setlocale ���������������R�[�h�y�[�W���������A���s��������
426     // ANSI�R�[�h�y�[�W�����������B
427 yutakapon 7978 if (result)
428     ts.CodePage = atoi(strrchr(result, '.')+1);
429 yutakapon 7983 else
430     ts.CodePage = GetACP();
431 maya 3227 }
432    
433     void ResetKeypadMode(BOOL DisabledModeOnly)
434     {
435 doda 6802 if (!DisabledModeOnly || ts.DisableAppKeypad)
436     AppliKeyMode = FALSE;
437     if (!DisabledModeOnly || ts.DisableAppCursor)
438     AppliCursorMode = FALSE;
439 maya 3227 }
440    
441     void MoveToMainScreen()
442     {
443 doda 6802 StatusX = CursorX;
444     StatusWrap = Wrap;
445     StatusCursor = IsCaretEnabled();
446 maya 3227
447 doda 6802 CursorTop = MainTop;
448     CursorBottom = MainBottom;
449     Wrap = MainWrap;
450     DispEnableCaret(MainCursor);
451     MoveCursor(MainX, MainY); // move to main screen
452 maya 3227 }
453    
454 zmatsuo 8861 /**
455 zmatsuo 8904 * 1�L�����N�^(unsigned int, char32_t)��macro���o��
456 zmatsuo 8861 */
457 zmatsuo 8904 static void DDEPut1U32(unsigned int u32)
458 zmatsuo 8822 {
459 zmatsuo 8904 if (DDELog) {
460     // UTF-8 ���o������
461 zmatsuo 8861 char u8_buf[4];
462     size_t u8_len = UTF32ToUTF8(u32, u8_buf, _countof(u8_buf));
463 zmatsuo 8904 size_t i;
464 zmatsuo 8861 for (i = 0; i < u8_len; i++) {
465     BYTE b = u8_buf[i];
466 zmatsuo 8904 DDEPut1(b);
467 zmatsuo 8861 }
468     }
469 zmatsuo 8822 }
470    
471 zmatsuo 8861 /**
472 zmatsuo 8904 * ���O���������������s�R�[�h���o��
473 zmatsuo 8861 */
474     static void OutputLogNewLine(vtterm_work_t *vtterm)
475 zmatsuo 8822 {
476 zmatsuo 8904 switch(vtterm->log_cr_type) {
477     case 0:
478     // CR + LF
479     FLogPutUTF32(CR);
480     FLogPutUTF32(LF);
481     break;
482     case 1:
483     // CR
484     FLogPutUTF32(CR);
485     break;
486     case 2:
487     // LF
488     FLogPutUTF32(LF);
489     break;
490 zmatsuo 8822 }
491     }
492    
493 zmatsuo 8861 /**
494     * 1�L�����N�^(unsigned int, char32_t)�����O(or/and macro���M�o�b�t�@)���o��
495     */
496 zmatsuo 8822 static void OutputLogUTF32(unsigned int u32)
497     {
498 zmatsuo 8906 vtterm_work_t *vtterm;
499     CheckEOLRet r;
500    
501     if (!FLogIsOpendText() && !DDELog) {
502 zmatsuo 8904 return;
503     }
504 zmatsuo 8906 vtterm = &vtterm_work;
505     r = CheckEOLCheck(vtterm->check_eol, u32);
506 zmatsuo 8904 if ((r & CheckEOLOutputEOL) != 0) {
507     // ���O�A���s���o��
508 zmatsuo 8906 if (FLogIsOpendText()) {
509 zmatsuo 8861 OutputLogNewLine(vtterm);
510 zmatsuo 8822 }
511 zmatsuo 8904
512     // �}�N���A���s���o��
513     if (DDELog) {
514     DDEPut1(CR);
515     DDEPut1(LF);
516 zmatsuo 8822 }
517     }
518 zmatsuo 8904 if ((r & CheckEOLOutputChar) != 0) {
519     // ���O�Au32���o��
520 zmatsuo 8906 if (FLogIsOpendText()) {
521 zmatsuo 8904 FLogPutUTF32(u32);
522 zmatsuo 8822 }
523 zmatsuo 8904
524     // �}�N���Au32���o��
525     if (DDELog) {
526     DDEPut1U32(u32);
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     BuffDumpCurrentLine(b);
694    
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     WriteToPrnFile(b,TRUE);
797     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     BYTE c = RussConv(ts.RussHost, IdWindows, b);
884     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     WriteToPrnFile(b, TRUE);
910     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     WriteToPrnFile(HIBYTE(Kanji),FALSE);
963     WriteToPrnFile(LOBYTE(Kanji),TRUE);
964     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     WriteToPrnFile(HIBYTE(Kanji),FALSE);
972     WriteToPrnFile(LOBYTE(Kanji),TRUE);
973     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     goto default_;
1042     }
1043     break;
1044     case IdChinese:
1045     if (ts.KanjiCode == IdCnGB2312) {
1046     // CP936 GB2312
1047     u32 = MBCP_UTF32(Kanji, 936);
1048     }
1049     else if (ts.KanjiCode == IdCnBig5) {
1050     // CP950 Big5
1051     u32 = MBCP_UTF32(Kanji, 950);
1052     }
1053     else {
1054     assert(FALSE);
1055     goto default_;
1056     }
1057     break;
1058     default:
1059     default_:
1060     assert(FALSE);
1061 doda 8445 u32 = MBCP_UTF32(Kanji, ts.CodePage);
1062 zmatsuo 8766 break;
1063 doda 8445 }
1064     CharAttrTmp.AttrEx = CharAttrTmp.Attr;
1065     BuffPutUnicode(u32, CharAttrTmp, InsertMode);
1066     }
1067     #else
1068 doda 6802 BuffPutKanji(Kanji, CharAttrTmp, InsertMode);
1069 doda 8445 #endif
1070 maya 3227
1071 doda 6802 if (CursorX < LineEnd - 1) {
1072     MoveRight();
1073     MoveRight();
1074     }
1075     else {
1076 doda 8103 if (CursorX == LineEnd - 1) {
1077     MoveRight();
1078     }
1079 doda 6802 UpdateStr();
1080     Wrap = AutoWrapMode;
1081     }
1082 maya 3227 }
1083    
1084     void PutDebugChar(BYTE b)
1085     {
1086 yutakapon 3637 static BYTE buff[3];
1087 doda 5589 int i;
1088     BOOL svInsertMode, svAutoWrapMode;
1089     BYTE svCharAttr;
1090 yutakapon 3637
1091 doda 5589 if (DebugFlag!=DEBUG_FLAG_NOUT) {
1092     svInsertMode = InsertMode;
1093     svAutoWrapMode = AutoWrapMode;
1094 doda 5588 InsertMode = FALSE;
1095     AutoWrapMode = TRUE;
1096 maya 3227
1097 doda 5589 svCharAttr = CharAttr.Attr;
1098     if (CharAttr.Attr != AttrDefault) {
1099     UpdateStr();
1100     CharAttr.Attr = AttrDefault;
1101     }
1102    
1103 doda 5588 if (DebugFlag==DEBUG_FLAG_HEXD) {
1104     _snprintf(buff, 3, "%02X", (unsigned int) b);
1105 yutakapon 3637
1106 doda 5589 for (i=0; i<2; i++)
1107 doda 5588 PutChar(buff[i]);
1108     PutChar(' ');
1109     }
1110     else if (DebugFlag==DEBUG_FLAG_NORM) {
1111 yutakapon 3637
1112 doda 5588 if ((b & 0x80) == 0x80) {
1113     UpdateStr();
1114     CharAttr.Attr = AttrReverse;
1115     b = b & 0x7f;
1116     }
1117 maya 3227
1118 doda 5588 if (b<=US) {
1119     PutChar('^');
1120     PutChar((char)(b+0x40));
1121     }
1122     else if (b==DEL) {
1123     PutChar('<');
1124     PutChar('D');
1125     PutChar('E');
1126     PutChar('L');
1127     PutChar('>');
1128     }
1129     else
1130     PutChar(b);
1131     }
1132 maya 3227
1133 doda 5589 if (CharAttr.Attr != svCharAttr) {
1134 doda 5588 UpdateStr();
1135 doda 5589 CharAttr.Attr = svCharAttr;
1136 doda 5588 }
1137 doda 5589 InsertMode = svInsertMode;
1138     AutoWrapMode = svAutoWrapMode;
1139 yutakapon 3637 }
1140 maya 3227 }
1141    
1142 doda 8445 static void PrnParseControl(BYTE b) // printer mode
1143 maya 3227 {
1144 doda 6802 switch (b) {
1145     case NUL:
1146     return;
1147     case SO:
1148 doda 6913 if ((ts.ISO2022Flag & ISO2022_SO) && ! DirectPrn) {
1149 doda 6802 if ((ts.Language==IdJapanese) &&
1150     (ts.KanjiCode==IdJIS) &&
1151     (ts.JIS7Katakana==1) &&
1152     ((ts.TermFlag & TF_FIXEDJIS)!=0))
1153     {
1154     Gn[1] = IdKatakana;
1155     }
1156     Glr[0] = 1; /* LS1 */
1157     return;
1158     }
1159     break;
1160     case SI:
1161 doda 6913 if ((ts.ISO2022Flag & ISO2022_SI) && ! DirectPrn) {
1162 doda 6802 Glr[0] = 0; /* LS0 */
1163     return;
1164     }
1165     break;
1166     case DC1:
1167     case DC3:
1168     return;
1169     case ESC:
1170     ICount = 0;
1171     JustAfterESC = TRUE;
1172     ParseMode = ModeESC;
1173     WriteToPrnFile(0, TRUE); // flush prn buff
1174     return;
1175     case CSI:
1176     if (! Accept8BitCtrl) {
1177     PutChar(b); /* Disp C1 char in VT100 mode */
1178     return;
1179     }
1180     ClearParams();
1181     FirstPrm = TRUE;
1182     ParseMode = ModeCSI;
1183     WriteToPrnFile(0, TRUE); // flush prn buff
1184     WriteToPrnFile(b, FALSE);
1185     return;
1186     }
1187     /* send the uninterpreted character to printer */
1188     WriteToPrnFile(b, TRUE);
1189 maya 3227 }
1190    
1191 doda 8445 static void ParseControl(BYTE b)
1192 maya 3227 {
1193 doda 6802 if (PrinterMode) { // printer mode
1194     PrnParseControl(b);
1195     return;
1196     }
1197 maya 3227
1198 doda 6802 if (b>=0x80) { /* C1 char */
1199     if (ts.Language==IdEnglish) { /* English mode */
1200     if (!Accept8BitCtrl) {
1201     PutChar(b); /* Disp C1 char in VT100 mode */
1202     return;
1203     }
1204     }
1205     else { /* Japanese mode */
1206     if ((ts.TermFlag & TF_ACCEPT8BITCTRL)==0) {
1207     return; /* ignore C1 char */
1208     }
1209     /* C1 chars are interpreted as C0 chars in VT100 mode */
1210     if (VTlevel < 2) {
1211     b = b & 0x7F;
1212     }
1213     }
1214     }
1215     switch (b) {
1216     /* C0 group */
1217     case ENQ:
1218     CommBinaryOut(&cv, &(ts.Answerback[0]), ts.AnswerbackLen);
1219     break;
1220     case BEL:
1221     if (ts.Beep != IdBeepOff)
1222     RingBell(ts.Beep);
1223     break;
1224     case BS:
1225     BackSpace();
1226     break;
1227     case HT:
1228     Tab();
1229     break;
1230     case LF:
1231 maya 3227 if (ts.CRReceive == IdLF) {
1232 maya 4893 // ���M�������s�R�[�h�� LF ���������A�T�[�o���� LF ���������������������������A
1233     // CR+LF���������������������B
1234     // cf. http://www.neocom.ca/forum/viewtopic.php?t=216
1235     // (2007.1.21 yutaka)
1236 maya 3227 CarriageReturn(TRUE);
1237     LineFeed(b, TRUE);
1238     break;
1239     }
1240 maya 4893 else if (ts.CRReceive == IdAUTO) {
1241     // 9th Apr 2012: AUTO CR/LF mode (tentner)
1242     // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
1243     if(PrevCharacter != CR || !PrevCRorLFGeneratedCRLF) {
1244     CarriageReturn(TRUE);
1245     LineFeed(b, TRUE);
1246     PrevCRorLFGeneratedCRLF = TRUE;
1247     }
1248     else {
1249     PrevCRorLFGeneratedCRLF = FALSE;
1250     }
1251     break;
1252     }
1253 maya 3227
1254 doda 6802 case VT:
1255     LineFeed(b, TRUE);
1256     break;
1257 maya 3227
1258 doda 6802 case FF:
1259     if ((ts.AutoWinSwitch>0) && JustAfterESC) {
1260     CommInsert1Byte(&cv, b);
1261     CommInsert1Byte(&cv, ESC);
1262     ChangeEmu = IdTEK; /* Enter TEK Mode */
1263     }
1264     else
1265     LineFeed(b, TRUE);
1266     break;
1267     case CR:
1268     if (ts.CRReceive == IdAUTO) {
1269     // 9th Apr 2012: AUTO CR/LF mode (tentner)
1270     // a CR or LF will generated a CR+LF, if the next character is the opposite, it will be ignored
1271     if(PrevCharacter != LF || !PrevCRorLFGeneratedCRLF) {
1272     CarriageReturn(TRUE);
1273     LineFeed(b, TRUE);
1274     PrevCRorLFGeneratedCRLF = TRUE;
1275     }
1276     else {
1277     PrevCRorLFGeneratedCRLF = FALSE;
1278     }
1279     }
1280     else {
1281     CarriageReturn(TRUE);
1282     if (ts.CRReceive==IdCRLF) {
1283     CommInsert1Byte(&cv, LF);
1284     }
1285     }
1286     break;
1287     case SO: /* LS1 */
1288 doda 6913 if (ts.ISO2022Flag & ISO2022_SO) {
1289 doda 6804 if ((ts.Language==IdJapanese) &&
1290     (ts.KanjiCode==IdJIS) &&
1291     (ts.JIS7Katakana==1) &&
1292     ((ts.TermFlag & TF_FIXEDJIS)!=0))
1293     {
1294     Gn[1] = IdKatakana;
1295     }
1296 maya 3227
1297 doda 6804 Glr[0] = 1;
1298     }
1299 doda 6802 break;
1300     case SI: /* LS0 */
1301 doda 6913 if (ts.ISO2022Flag & ISO2022_SI) {
1302 doda 6804 Glr[0] = 0;
1303     }
1304 doda 6802 break;
1305     case DLE:
1306     if ((ts.FTFlag & FT_BPAUTO)!=0)
1307     ParseMode = ModeDLE; /* Auto B-Plus activation */
1308     break;
1309     case CAN:
1310     if ((ts.FTFlag & FT_ZAUTO)!=0)
1311     ParseMode = ModeCAN; /* Auto ZMODEM activation */
1312     // else if (ts.AutoWinSwitch>0)
1313     // ChangeEmu = IdTEK; /* Enter TEK Mode */
1314     else
1315     ParseMode = ModeFirst;
1316     break;
1317     case SUB:
1318     ParseMode = ModeFirst;
1319     break;
1320     case ESC:
1321     ICount = 0;
1322     JustAfterESC = TRUE;
1323     ParseMode = ModeESC;
1324     break;
1325     case FS:
1326     case GS:
1327     case RS:
1328     case US:
1329     if (ts.AutoWinSwitch>0) {
1330     CommInsert1Byte(&cv, b);
1331     ChangeEmu = IdTEK; /* Enter TEK Mode */
1332     }
1333     break;
1334 maya 3227
1335 doda 6802 /* C1 char */
1336     case IND:
1337     LineFeed(0, TRUE);
1338     break;
1339     case NEL:
1340     LineFeed(0, TRUE);
1341     CarriageReturn(TRUE);
1342     break;
1343     case HTS:
1344     if (ts.TabStopFlag & TABF_HTS8)
1345     SetTabStop();
1346     break;
1347     case RI:
1348     CursorUpWithScroll();
1349     break;
1350     case SS2:
1351 doda 6913 if (ts.ISO2022Flag & ISO2022_SS2) {
1352     GLtmp = 2;
1353     SSflag = TRUE;
1354     }
1355 doda 6802 break;
1356     case SS3:
1357 doda 6913 if (ts.ISO2022Flag & ISO2022_SS3) {
1358     GLtmp = 3;
1359     SSflag = TRUE;
1360     }
1361 doda 6802 break;
1362     case DCS:
1363     ClearParams();
1364     ESCFlag = FALSE;
1365     ParseMode = ModeDCS;
1366     break;
1367     case SOS:
1368     ESCFlag = FALSE;
1369     ParseMode = ModeIgnore;
1370     break;
1371     case CSI:
1372     ClearParams();
1373     FirstPrm = TRUE;
1374     ParseMode = ModeCSI;
1375     break;
1376     case OSC:
1377     ClearParams();
1378     ParseMode = ModeXS;
1379     break;
1380     case PM:
1381     case APC:
1382     ESCFlag = FALSE;
1383     ParseMode = ModeIgnore;
1384     break;
1385     }
1386 maya 3227 }
1387    
1388     void SaveCursor()
1389     {
1390 doda 6802 int i;
1391     PStatusBuff Buff;
1392 maya 3227
1393 doda 6802 if (isCursorOnStatusLine)
1394     Buff = &SBuff2; // for status line
1395     else if (AltScr)
1396     Buff = &SBuff3; // for alternate screen
1397     else
1398     Buff = &SBuff1; // for main screen
1399 maya 3227
1400 doda 6802 Buff->CursorX = CursorX;
1401     Buff->CursorY = CursorY;
1402     Buff->Attr = CharAttr;
1403    
1404     Buff->Glr[0] = Glr[0];
1405     Buff->Glr[1] = Glr[1];
1406     for (i=0 ; i<=3; i++)
1407     Buff->Gn[i] = Gn[i];
1408    
1409     Buff->AutoWrapMode = AutoWrapMode;
1410     Buff->RelativeOrgMode = RelativeOrgMode;
1411 maya 3227 }
1412    
1413 doda 6802 void RestoreCursor()
1414 maya 3227 {
1415 doda 6802 int i;
1416     PStatusBuff Buff;
1417 maya 3227
1418 doda 6802 UpdateStr();
1419 maya 3227
1420 doda 6802 if (isCursorOnStatusLine)
1421     Buff = &SBuff2; // for status line
1422     else if (AltScr)
1423     Buff = &SBuff3; // for alternate screen
1424     else
1425     Buff = &SBuff1; // for main screen
1426    
1427     if (Buff->CursorX > NumOfColumns-1)
1428     Buff->CursorX = NumOfColumns-1;
1429     if (Buff->CursorY > NumOfLines-1-StatusLine)
1430     Buff->CursorY = NumOfLines-1-StatusLine;
1431     MoveCursor(Buff->CursorX, Buff->CursorY);
1432    
1433     CharAttr = Buff->Attr;
1434     BuffSetCurCharAttr(CharAttr);
1435    
1436     Glr[0] = Buff->Glr[0];
1437     Glr[1] = Buff->Glr[1];
1438     for (i=0 ; i<=3; i++)
1439     Gn[i] = Buff->Gn[i];
1440    
1441     AutoWrapMode = Buff->AutoWrapMode;
1442     RelativeOrgMode = Buff->RelativeOrgMode;
1443 maya 3227 }
1444    
1445     void AnswerTerminalType()
1446     {
1447 doda 6802 char Tmp[50];
1448 maya 3227
1449 doda 6802 if (ts.TerminalID<IdVT320 || !Send8BitMode)
1450     strncpy_s(Tmp, sizeof(Tmp),"\033[?", _TRUNCATE);
1451     else
1452     strncpy_s(Tmp, sizeof(Tmp),"\233?", _TRUNCATE);
1453 maya 3227
1454 doda 6802 switch (ts.TerminalID) {
1455     case IdVT100:
1456     strncat_s(Tmp,sizeof(Tmp),"1;2",_TRUNCATE);
1457     break;
1458     case IdVT100J:
1459     strncat_s(Tmp,sizeof(Tmp),"5;2",_TRUNCATE);
1460     break;
1461     case IdVT101:
1462     strncat_s(Tmp,sizeof(Tmp),"1;0",_TRUNCATE);
1463     break;
1464     case IdVT102:
1465     strncat_s(Tmp,sizeof(Tmp),"6",_TRUNCATE);
1466     break;
1467     case IdVT102J:
1468     strncat_s(Tmp,sizeof(Tmp),"15",_TRUNCATE);
1469     break;
1470     case IdVT220J:
1471     strncat_s(Tmp,sizeof(Tmp),"62;1;2;5;6;7;8",_TRUNCATE);
1472     break;
1473     case IdVT282:
1474     strncat_s(Tmp,sizeof(Tmp),"62;1;2;4;5;6;7;8;10;11",_TRUNCATE);
1475     break;
1476     case IdVT320:
1477     strncat_s(Tmp,sizeof(Tmp),"63;1;2;6;7;8",_TRUNCATE);
1478     break;
1479     case IdVT382:
1480     strncat_s(Tmp,sizeof(Tmp),"63;1;2;4;5;6;7;8;10;15",_TRUNCATE);
1481     break;
1482     case IdVT420:
1483     strncat_s(Tmp,sizeof(Tmp),"64;1;2;7;8;9;15;18;21",_TRUNCATE);
1484     break;
1485     case IdVT520:
1486     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;8;9;12;18;19;21;23;24;42;44;45;46",_TRUNCATE);
1487     break;
1488     case IdVT525:
1489     strncat_s(Tmp,sizeof(Tmp),"65;1;2;7;9;12;18;19;21;22;23;24;42;44;45;46",_TRUNCATE);
1490     break;
1491     }
1492     strncat_s(Tmp,sizeof(Tmp),"c",_TRUNCATE);
1493 maya 3227
1494 doda 6802 CommBinaryOut(&cv,Tmp,strlen(Tmp)); /* Report terminal ID */
1495 maya 3227 }
1496    
1497     void ESCSpace(BYTE b)
1498     {
1499 doda 6802 switch (b) {
1500     case 'F': // S7C1T
1501     Send8BitMode = FALSE;
1502     break;
1503     case 'G': // S8C1T
1504     if (VTlevel >= 2) {
1505     Send8BitMode = TRUE;
1506     }
1507     break;
1508     }
1509 maya 3227 }
1510    
1511     void ESCSharp(BYTE b)
1512     {
1513 doda 6802 switch (b) {
1514     case '8': /* Fill screen with "E" (DECALN) */
1515     BuffUpdateScroll();
1516     BuffFillWithE();
1517     CursorTop = 0;
1518     CursorBottom = NumOfLines-1-StatusLine;
1519     CursorLeftM = 0;
1520     CursorRightM = NumOfColumns - 1;
1521     MoveCursor(0, 0);
1522     ParseMode = ModeFirst;
1523     break;
1524     }
1525 maya 3227 }
1526    
1527     /* select double byte code set */
1528     void ESCDBCSSelect(BYTE b)
1529     {
1530 doda 6802 int Dist;
1531 maya 3227
1532 doda 6802 if (ts.Language!=IdJapanese) return;
1533 maya 3227
1534 doda 6802 switch (ICount) {
1535     case 1:
1536     if ((b=='@') || (b=='B'))
1537     {
1538     Gn[0] = IdKanji; /* Kanji -> G0 */
1539     if ((ts.TermFlag & TF_AUTOINVOKE)!=0)
1540     Glr[0] = 0; /* G0->GL */
1541     }
1542     break;
1543     case 2:
1544     /* Second intermediate char must be
1545     '(' or ')' or '*' or '+'. */
1546     Dist = (IntChar[2]-'(') & 3; /* G0 - G3 */
1547     if ((b=='1') || (b=='3') ||
1548     (b=='@') || (b=='B'))
1549     {
1550     Gn[Dist] = IdKanji; /* Kanji -> G0-3 */
1551     if (((ts.TermFlag & TF_AUTOINVOKE)!=0) &&
1552     (Dist==0))
1553     Glr[0] = 0; /* G0->GL */
1554     }
1555     break;
1556     }
1557 maya 3227 }
1558    
1559     void ESCSelectCode(BYTE b)
1560     {
1561 doda 6802 switch (b) {
1562     case '0':
1563     if (ts.AutoWinSwitch>0)
1564     ChangeEmu = IdTEK; /* enter TEK mode */
1565     break;
1566     }
1567 maya 3227 }
1568    
1569 doda 6802 /* select single byte code set */
1570 maya 3227 void ESCSBCSSelect(BYTE b)
1571     {
1572 doda 6802 int Dist;
1573 maya 3227
1574 doda 6802 /* Intermediate char must be '(' or ')' or '*' or '+'. */
1575     Dist = (IntChar[1]-'(') & 3; /* G0 - G3 */
1576 maya 3227
1577 doda 6802 switch (b) {
1578     case '0': Gn[Dist] = IdSpecial; break;
1579     case '<': Gn[Dist] = IdASCII; break;
1580     case '>': Gn[Dist] = IdASCII; break;
1581     case 'A': Gn[Dist] = IdASCII; break;
1582     case 'B': Gn[Dist] = IdASCII; break;
1583     case 'H': Gn[Dist] = IdASCII; break;
1584     case 'I':
1585     if (ts.Language==IdJapanese)
1586     Gn[Dist] = IdKatakana;
1587     break;
1588     case 'J': Gn[Dist] = IdASCII; break;
1589     }
1590 maya 3227
1591 doda 6802 if (((ts.TermFlag & TF_AUTOINVOKE)!=0) && (Dist==0))
1592     Glr[0] = 0; /* G0->GL */
1593 maya 3227 }
1594    
1595     void PrnParseEscape(BYTE b) // printer mode
1596     {
1597 doda 6802 int i;
1598 maya 3227
1599 doda 6802 ParseMode = ModeFirst;
1600     switch (ICount) {
1601     /* no intermediate char */
1602     case 0:
1603     switch (b) {
1604     case '[': /* CSI */
1605     ClearParams();
1606     FirstPrm = TRUE;
1607     WriteToPrnFile(ESC,FALSE);
1608     WriteToPrnFile('[',FALSE);
1609     ParseMode = ModeCSI;
1610     return;
1611     } /* end of case Icount=0 */
1612     break;
1613     /* one intermediate char */
1614     case 1:
1615     switch (IntChar[1]) {
1616     case '$':
1617     if (! DirectPrn) {
1618     ESCDBCSSelect(b);
1619     return;
1620     }
1621     break;
1622     case '(':
1623     case ')':
1624     case '*':
1625     case '+':
1626     if (! DirectPrn) {
1627     ESCSBCSSelect(b);
1628     return;
1629     }
1630     break;
1631     }
1632     break;
1633     /* two intermediate char */
1634     case 2:
1635     if ((! DirectPrn) &&
1636     (IntChar[1]=='$') &&
1637     ('('<=IntChar[2]) &&
1638     (IntChar[2]<='+'))
1639     {
1640     ESCDBCSSelect(b);
1641     return;
1642     }
1643     break;
1644     }
1645     // send the uninterpreted sequence to printer
1646     WriteToPrnFile(ESC,FALSE);
1647     for (i=1; i<=ICount; i++)
1648     WriteToPrnFile(IntChar[i],FALSE);
1649     WriteToPrnFile(b,TRUE);
1650 maya 3227 }
1651    
1652     void ParseEscape(BYTE b) /* b is the final char */
1653     {
1654 doda 6802 if (PrinterMode) { // printer mode
1655     PrnParseEscape(b);
1656     return;
1657     }
1658 maya 3227
1659 doda 6802 switch (ICount) {
1660     case 0: /* no intermediate char */
1661     switch (b) {
1662     case '6': // DECBI
1663     if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1664     CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1665     if (CursorX == CursorLeftM)
1666     BuffScrollRight(1);
1667     else
1668     MoveCursor(CursorX-1, CursorY);
1669     }
1670     break;
1671     case '7': SaveCursor(); break;
1672     case '8': RestoreCursor(); break;
1673     case '9': // DECFI
1674     if (CursorY >= CursorTop && CursorY <= CursorBottom &&
1675     CursorX >= CursorLeftM && CursorX <= CursorRightM) {
1676     if (CursorX == CursorRightM)
1677     BuffScrollLeft(1);
1678     else
1679     MoveCursor(CursorX+1, CursorY);
1680     }
1681     break;
1682     case '=': AppliKeyMode = TRUE; break;
1683     case '>': AppliKeyMode = FALSE; break;
1684     case 'D': /* IND */
1685     LineFeed(0,TRUE);
1686     break;
1687     case 'E': /* NEL */
1688     MoveCursor(0,CursorY);
1689     LineFeed(0,TRUE);
1690     break;
1691     case 'H': /* HTS */
1692     if (ts.TabStopFlag & TABF_HTS7)
1693     SetTabStop();
1694     break;
1695     case 'M': /* RI */
1696     CursorUpWithScroll();
1697     break;
1698     case 'N': /* SS2 */
1699 doda 6913 if (ts.ISO2022Flag & ISO2022_SS2) {
1700     GLtmp = 2;
1701     SSflag = TRUE;
1702     }
1703 doda 6802 break;
1704     case 'O': /* SS3 */
1705 doda 6913 if (ts.ISO2022Flag & ISO2022_SS3) {
1706     GLtmp = 3;
1707     SSflag = TRUE;
1708     }
1709 doda 6802 break;
1710     case 'P': /* DCS */
1711     ClearParams();
1712     ESCFlag = FALSE;
1713     ParseMode = ModeDCS;
1714     return;
1715     case 'X': /* SOS */
1716     case '^': /* APC */
1717     case '_': /* PM */
1718     ESCFlag = FALSE;
1719     ParseMode = ModeIgnore;
1720     return;
1721     case 'Z': /* DECID */
1722     AnswerTerminalType();
1723     break;
1724     case '[': /* CSI */
1725     ClearParams();
1726     FirstPrm = TRUE;
1727     ParseMode = ModeCSI;
1728     return;
1729     case '\\': break; /* ST */
1730     case ']': /* XTERM sequence (OSC) */
1731     ClearParams();
1732     ParseMode = ModeXS;
1733     return;
1734     case 'c': /* Hardware reset */
1735     HideStatusLine();
1736     ResetTerminal();
1737     ClearUserKey();
1738     ClearBuffer();
1739     if (ts.PortType==IdSerial) // reset serial port
1740     CommResetSerial(&ts, &cv, TRUE);
1741     break;
1742     case 'g': /* Visual Bell (screen original?) */
1743     RingBell(IdBeepVisual);
1744     break;
1745 doda 6913 case 'n': /* LS2 */
1746     if (ts.ISO2022Flag & ISO2022_LS2) {
1747     Glr[0] = 2;
1748     }
1749     break;
1750     case 'o': /* LS3 */
1751     if (ts.ISO2022Flag & ISO2022_LS3) {
1752     Glr[0] = 3;
1753     }
1754     break;
1755     case '|': /* LS3R */
1756     if (ts.ISO2022Flag & ISO2022_LS3R) {
1757     Glr[1] = 3;
1758     }
1759     break;
1760     case '}': /* LS2R */
1761     if (ts.ISO2022Flag & ISO2022_LS2R) {
1762     Glr[1] = 2;
1763     }
1764     break;
1765     case '~': /* LS1R */
1766     if (ts.ISO2022Flag & ISO2022_LS1R) {
1767     Glr[1] = 1;
1768     }
1769     break;
1770 doda 6802 }
1771     break;
1772     /* end of case Icount=0 */
1773    
1774     case 1: /* one intermediate char */
1775     switch (IntChar[1]) {
1776     case ' ': ESCSpace(b); break;
1777     case '#': ESCSharp(b); break;
1778     case '$': ESCDBCSSelect(b); break;
1779     case '%': break;
1780     case '(':
1781     case ')':
1782     case '*':
1783     case '+':
1784     ESCSBCSSelect(b);
1785     break;
1786     }
1787     break;
1788    
1789     case 2: /* two intermediate char */
1790     if ((IntChar[1]=='$') && ('('<=IntChar[2]) && (IntChar[2]<='+'))
1791     ESCDBCSSelect(b);
1792     else if ((IntChar[1]=='%') && (IntChar[2]=='!'))
1793     ESCSelectCode(b);
1794     break;
1795     }
1796     ParseMode = ModeFirst;
1797 maya 3227 }
1798    
1799     void EscapeSequence(BYTE b)
1800     {
1801 doda 6173 if (b<=US)
1802     ParseControl(b);
1803     else if ((b>=0x20) && (b<=0x2F)) {
1804 doda 6174 // TODO: ICount �� IntCharMax ���B�������A������ IntChar ���u����������������?
1805 doda 6173 if (ICount<IntCharMax)
1806     ICount++;
1807     IntChar[ICount] = b;
1808     }
1809     else if ((b>=0x30) && (b<=0x7E))
1810     ParseEscape(b);
1811     else if ((b>=0x80) && (b<=0x9F))
1812     ParseControl(b);
1813     else if (b>=0xA0) {
1814     ParseMode=ModeFirst;
1815     ParseFirst(b);
1816     }
1817 maya 3227
1818 doda 6173 JustAfterESC = FALSE;
1819 maya 3227 }
1820    
1821 doda 6174 #define CheckParamVal(p,m) \
1822     if ((p) == 0) { \
1823     (p) = 1; \
1824     } \
1825     else if ((p) > (m) || p < 0) { \
1826     (p) = (m); \
1827     }
1828    
1829     #define CheckParamValMax(p,m) \
1830     if ((p) > (m) || p <= 0) { \
1831     (p) = (m); \
1832     }
1833    
1834     #define RequiredParams(n) \
1835     if ((n) > 1) { \
1836     while (NParam < n) { \
1837     NParam++; \
1838     Param[NParam] = 0; \
1839     NSParam[NParam] = 0; \
1840     } \
1841     }
1842    
1843 doda 8445 // ICH
1844     static void CSInsertCharacter(void)
1845 doda 6173 {
1846     // Insert space characters at cursor
1847 doda 6174 CheckParamVal(Param[1], NumOfColumns);
1848 maya 3227
1849 doda 6173 BuffUpdateScroll();
1850 doda 6174 BuffInsertSpace(Param[1]);
1851 doda 6173 }
1852 maya 3227
1853 doda 5429 void CSCursorUp(BOOL AffectMargin) // CUU / VPB
1854     {
1855     int topMargin, NewY;
1856 maya 3227
1857 doda 6174 CheckParamVal(Param[1], CursorY);
1858 maya 3227
1859 doda 5429 if (AffectMargin && CursorY >= CursorTop)
1860     topMargin = CursorTop;
1861     else
1862     topMargin = 0;
1863 maya 3227
1864 doda 5429 NewY = CursorY - Param[1];
1865     if (NewY < topMargin)
1866     NewY = topMargin;
1867 maya 3227
1868 doda 5429 MoveCursor(CursorX, NewY);
1869     }
1870 maya 3227
1871 doda 5429 void CSCursorUp1() // CPL
1872     {
1873     MoveCursor(CursorLeftM, CursorY);
1874     CSCursorUp(TRUE);
1875     }
1876 maya 3227
1877 doda 5429 void CSCursorDown(BOOL AffectMargin) // CUD / VPR
1878     {
1879     int bottomMargin, NewY;
1880    
1881     if (AffectMargin && CursorY <= CursorBottom)
1882     bottomMargin = CursorBottom;
1883     else
1884     bottomMargin = NumOfLines-StatusLine-1;
1885    
1886 doda 6174 CheckParamVal(Param[1], bottomMargin);
1887    
1888 doda 5429 NewY = CursorY + Param[1];
1889     if (NewY > bottomMargin)
1890     NewY = bottomMargin;
1891    
1892     MoveCursor(CursorX, NewY);
1893     }
1894    
1895     void CSCursorDown1() // CNL
1896     {
1897     MoveCursor(CursorLeftM, CursorY);
1898     CSCursorDown(TRUE);
1899     }
1900    
1901 maya 3227 void CSScreenErase()
1902     {
1903     BuffUpdateScroll();
1904     switch (Param[1]) {
1905 doda 6173 case 0:
1906 maya 3227 // <ESC>[H(Cursor in left upper corner)�������J�[�\�������������w�������������A
1907     // <ESC>[J��<ESC>[2J�����������������A�����������A���s�o�b�t�@���X�N���[���A�E�g
1908     // �����������������B(2005.5.29 yutaka)
1909     // �R���t�B�O���[�V�������������������������������B(2008.5.3 yutaka)
1910 doda 6435 if (ts.ScrollWindowClearScreen &&
1911 maya 3227 (CursorX == 0 && CursorY == 0)) {
1912 doda 6173 // Erase screen (scroll out)
1913 maya 3227 BuffClearScreen();
1914     UpdateWindow(HVTWin);
1915    
1916     } else {
1917 doda 6173 // Erase characters from cursor to the end of screen
1918 maya 3227 BuffEraseCurToEnd();
1919     }
1920     break;
1921    
1922 doda 6173 case 1:
1923     // Erase characters from home to cursor
1924 maya 3227 BuffEraseHomeToCur();
1925     break;
1926    
1927 doda 6173 case 2:
1928     // Erase screen (scroll out)
1929 maya 3227 BuffClearScreen();
1930     UpdateWindow(HVTWin);
1931 doda 5564 if (ClearThenHome && !isCursorOnStatusLine) {
1932     if (RelativeOrgMode) {
1933     MoveCursor(0, 0);
1934     }
1935     else {
1936     MoveCursor(CursorLeftM, CursorTop);
1937     }
1938     }
1939 maya 3227 break;
1940 doda 8383
1941     case 3:
1942     if (ts.TermFlag & TF_REMOTECLEARSBUFF) {
1943     ClearBuffer();
1944     }
1945     break;
1946 maya 3227 }
1947     }
1948    
1949 doda 4070 void CSQSelScreenErase()
1950     {
1951     BuffUpdateScroll();
1952     switch (Param[1]) {
1953 doda 6173 case 0:
1954     // Erase characters from cursor to end
1955 doda 4070 BuffSelectedEraseCurToEnd();
1956     break;
1957    
1958 doda 6173 case 1:
1959     // Erase characters from home to cursor
1960 doda 4070 BuffSelectedEraseHomeToCur();
1961     break;
1962    
1963 doda 6173 case 2:
1964     // Erase entire screen
1965 doda 4070 BuffSelectedEraseScreen();
1966     break;
1967 doda 8383
1968     case 3:
1969     if (ts.TermFlag & TF_REMOTECLEARSBUFF) {
1970     ClearBuffer();
1971     }
1972     break;
1973 doda 4070 }
1974     }
1975    
1976 doda 6173 void CSInsertLine()
1977     {
1978     // Insert lines at current position
1979     int Count, YEnd;
1980 maya 3227
1981 doda 6174 if (CursorY < CursorTop || CursorY > CursorBottom) {
1982 doda 6173 return;
1983 doda 6174 }
1984 maya 3227
1985 doda 6174 CheckParamVal(Param[1], NumOfLines);
1986    
1987 doda 6173 Count = Param[1];
1988 maya 3227
1989 doda 6173 YEnd = CursorBottom;
1990     if (CursorY > YEnd)
1991     YEnd = NumOfLines-1-StatusLine;
1992 doda 6174
1993 doda 6173 if (Count > YEnd+1 - CursorY)
1994     Count = YEnd+1 - CursorY;
1995 maya 3227
1996 doda 6173 BuffInsertLines(Count,YEnd);
1997     }
1998 maya 3227
1999 doda 6173 void CSLineErase()
2000     {
2001     BuffUpdateScroll();
2002     switch (Param[1]) {
2003     case 0: /* erase char from cursor to end of line */
2004     BuffEraseCharsInLine(CursorX,NumOfColumns-CursorX);
2005     break;
2006 doda 4070
2007 doda 6173 case 1: /* erase char from start of line to cursor */
2008     BuffEraseCharsInLine(0,CursorX+1);
2009     break;
2010 maya 3227
2011 doda 6173 case 2: /* erase entire line */
2012     BuffEraseCharsInLine(0,NumOfColumns);
2013     break;
2014     }
2015     }
2016 maya 3227
2017 doda 8445 static void CSQSelLineErase(void)
2018 doda 6173 {
2019     BuffUpdateScroll();
2020     switch (Param[1]) {
2021     case 0: /* erase char from cursor to end of line */
2022     BuffSelectedEraseCharsInLine(CursorX,NumOfColumns-CursorX);
2023     break;
2024 maya 3227
2025 doda 6173 case 1: /* erase char from start of line to cursor */
2026     BuffSelectedEraseCharsInLine(0,CursorX+1);
2027     break;
2028 maya 3227
2029 doda 6173 case 2: /* erase entire line */
2030     BuffSelectedEraseCharsInLine(0,NumOfColumns);
2031     break;
2032     }
2033     }
2034 maya 3227
2035 doda 6173 void CSDeleteNLines()
2036     // Delete lines from current line
2037     {
2038     int Count, YEnd;
2039 maya 3227
2040 doda 6174 if (CursorY < CursorTop || CursorY > CursorBottom) {
2041 doda 6173 return;
2042 doda 6174 }
2043    
2044     CheckParamVal(Param[1], NumOfLines);
2045 doda 6173 Count = Param[1];
2046 maya 3227
2047 doda 6173 YEnd = CursorBottom;
2048     if (CursorY > YEnd)
2049     YEnd = NumOfLines-1-StatusLine;
2050 doda 6174
2051 doda 6173 if (Count > YEnd+1-CursorY)
2052     Count = YEnd+1-CursorY;
2053 doda 6174
2054 doda 6173 BuffDeleteLines(Count,YEnd);
2055     }
2056 maya 3227
2057 doda 8445 // DCH
2058     static void CSDeleteCharacter(void)
2059 doda 6173 {
2060     // Delete characters in current line from cursor
2061 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2062 maya 3227
2063 doda 6173 BuffUpdateScroll();
2064     BuffDeleteChars(Param[1]);
2065     }
2066 maya 3227
2067 doda 8445 // ECH
2068     static void CSEraseCharacter(void)
2069 doda 6173 {
2070 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2071    
2072 doda 6173 BuffUpdateScroll();
2073     BuffEraseChars(Param[1]);
2074     }
2075    
2076 doda 8329 void CSRepeatCharacter()
2077     {
2078     CheckParamVal(Param[1], NumOfColumns * NumOfLines);
2079    
2080     BuffUpdateScroll();
2081     RepeatChar(LastPutCharacter, Param[1]);
2082     }
2083    
2084 doda 6173 void CSScrollUp()
2085     {
2086 doda 6174 // TODO: �X�N���[���������l���[���s�����������������v����
2087     CheckParamVal(Param[1], INT_MAX);
2088    
2089 doda 6173 BuffUpdateScroll();
2090     BuffRegionScrollUpNLines(Param[1]);
2091     }
2092    
2093     void CSScrollDown()
2094     {
2095 doda 6174 CheckParamVal(Param[1], NumOfLines);
2096    
2097 doda 6173 BuffUpdateScroll();
2098     BuffRegionScrollDownNLines(Param[1]);
2099     }
2100    
2101     void CSForwardTab()
2102     {
2103 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2104 doda 6173 CursorForwardTab(Param[1], AutoWrapMode);
2105     }
2106    
2107     void CSBackwardTab()
2108     {
2109 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2110 doda 6173 CursorBackwardTab(Param[1]);
2111     }
2112    
2113 doda 5324 void CSMoveToColumnN() // CHA / HPA
2114     {
2115 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2116 maya 3227
2117 doda 5324 Param[1]--;
2118 maya 3227
2119 doda 5324 if (RelativeOrgMode) {
2120     if (CursorLeftM + Param[1] > CursorRightM )
2121     MoveCursor(CursorRightM, CursorY);
2122     else
2123     MoveCursor(CursorLeftM + Param[1], CursorY);
2124     }
2125     else {
2126     MoveCursor(Param[1], CursorY);
2127     }
2128     }
2129 maya 3227
2130 doda 5429 void CSCursorRight(BOOL AffectMargin) // CUF / HPR
2131 doda 5324 {
2132 doda 5429 int NewX, rightMargin;
2133 doda 5324
2134 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2135 doda 5324
2136 doda 6174 if (AffectMargin && CursorX <= CursorRightM) {
2137 doda 5429 rightMargin = CursorRightM;
2138 doda 6174 }
2139     else {
2140 doda 5429 rightMargin = NumOfColumns-1;
2141 doda 6174 }
2142 doda 5429
2143 doda 5324 NewX = CursorX + Param[1];
2144 doda 5429 if (NewX > rightMargin)
2145     NewX = rightMargin;
2146 doda 5324
2147     MoveCursor(NewX, CursorY);
2148     }
2149    
2150 doda 5429 void CSCursorLeft(BOOL AffectMargin) // CUB / HPB
2151 doda 5324 {
2152 doda 5429 int NewX, leftMargin;
2153 doda 5324
2154 doda 6174 CheckParamVal(Param[1], NumOfColumns);
2155 doda 5324
2156 doda 6174 if (AffectMargin && CursorX >= CursorLeftM) {
2157 doda 5429 leftMargin = CursorLeftM;
2158 doda 6174 }
2159     else {
2160 doda 5429 leftMargin = 0;
2161 doda 6174 }
2162 doda 5324
2163 doda 5429 NewX = CursorX - Param[1];
2164 doda 6174 if (NewX < leftMargin) {
2165 doda 5429 NewX = leftMargin;
2166 doda 6174 }
2167 doda 5324
2168     MoveCursor(NewX, CursorY);
2169     }
2170    
2171 doda 6174 void CSMoveToLineN() // VPA
2172 doda 6173 {
2173 doda 6174 CheckParamVal(Param[1], NumOfLines-StatusLine);
2174    
2175 doda 6173 if (RelativeOrgMode) {
2176     if (CursorTop+Param[1]-1 > CursorBottom)
2177     MoveCursor(CursorX,CursorBottom);
2178     else
2179     MoveCursor(CursorX,CursorTop+Param[1]-1);
2180     }
2181     else {
2182     if (Param[1] > NumOfLines-StatusLine)
2183     MoveCursor(CursorX,NumOfLines-1-StatusLine);
2184     else
2185     MoveCursor(CursorX,Param[1]-1);
2186     }
2187 doda 6602 Fallbacked = FALSE;
2188 doda 6173 }
2189 maya 3227
2190 doda 5324 void CSMoveToXY() // CUP / HVP
2191     {
2192     int NewX, NewY;
2193 maya 3227
2194 doda 6174 RequiredParams(2);
2195     CheckParamVal(Param[1], NumOfLines-StatusLine);
2196     CheckParamVal(Param[2], NumOfColumns);
2197 maya 3227
2198 doda 5324 NewY = Param[1] - 1;
2199     NewX = Param[2] - 1;
2200    
2201     if (isCursorOnStatusLine)
2202     NewY = CursorY;
2203     else if (RelativeOrgMode) {
2204     NewX += CursorLeftM;
2205     if (NewX > CursorRightM)
2206     NewX = CursorRightM;
2207    
2208     NewY += CursorTop;
2209     if (NewY > CursorBottom)
2210     NewY = CursorBottom;
2211     }
2212     else {
2213     if (NewY > NumOfLines-1-StatusLine)
2214     NewY = NumOfLines-1-StatusLine;
2215     }
2216    
2217     MoveCursor(NewX, NewY);
2218 doda 6602 Fallbacked = FALSE;
2219 doda 5324 }
2220    
2221 doda 6173 void CSDeleteTabStop()
2222     {
2223     ClearTabStop(Param[1]);
2224     }
2225 maya 3227
2226 doda 6173 void CS_h_Mode() // SM
2227     {
2228     switch (Param[1]) {
2229     case 2: // KAM
2230     KeybEnabled = FALSE; break;
2231     case 4: // IRM
2232     InsertMode = TRUE; break;
2233     case 12: // SRM
2234     ts.LocalEcho = 0;
2235     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
2236     TelChangeEcho();
2237     break;
2238     case 20: // LF/NL
2239     LFMode = TRUE;
2240     ts.CRSend = IdCRLF;
2241     cv.CRSend = IdCRLF;
2242     break;
2243     case 33: // WYSTCURM
2244     if (ts.WindowFlag & WF_CURSORCHANGE) {
2245     ts.NonblinkingCursor = TRUE;
2246     ChangeCaret();
2247     }
2248     break;
2249     case 34: // WYULCURM
2250     if (ts.WindowFlag & WF_CURSORCHANGE) {
2251     ts.CursorShape = IdHCur;
2252     ChangeCaret();
2253     }
2254     break;
2255     }
2256     }
2257 maya 3227
2258 doda 6173 void CS_i_Mode() // MC
2259     {
2260     switch (Param[1]) {
2261     /* print screen */
2262     // PrintEX -- TRUE: print screen
2263     // FALSE: scroll region
2264     case 0:
2265     if (ts.TermFlag&TF_PRINTERCTRL) {
2266     BuffPrint(! PrintEX);
2267     }
2268     break;
2269     /* printer controller mode off */
2270     case 4: break; /* See PrnParseCS() */
2271     /* printer controller mode on */
2272     case 5:
2273     if (ts.TermFlag&TF_PRINTERCTRL) {
2274     if (! AutoPrintMode)
2275     OpenPrnFile();
2276     DirectPrn = (ts.PrnDev[0]!=0);
2277     PrinterMode = TRUE;
2278     }
2279     break;
2280 doda 4397 }
2281 doda 6173 }
2282    
2283     void CS_l_Mode() // RM
2284     {
2285     switch (Param[1]) {
2286     case 2: // KAM
2287     KeybEnabled = TRUE; break;
2288     case 4: // IRM
2289     InsertMode = FALSE; break;
2290     case 12: // SRM
2291     ts.LocalEcho = 1;
2292     if (cv.Ready && cv.TelFlag && (ts.TelEcho>0))
2293     TelChangeEcho();
2294     break;
2295     case 20: // LF/NL
2296     LFMode = FALSE;
2297     ts.CRSend = IdCR;
2298     cv.CRSend = IdCR;
2299     break;
2300     case 33: // WYSTCURM
2301     if (ts.WindowFlag & WF_CURSORCHANGE) {
2302     ts.NonblinkingCursor = FALSE;
2303     ChangeCaret();
2304     }
2305     break;
2306     case 34: // WYULCURM
2307     if (ts.WindowFlag & WF_CURSORCHANGE) {
2308     ts.CursorShape = IdBlkCur;
2309     ChangeCaret();
2310     }
2311     break;
2312 doda 4397 }
2313 doda 6173 }
2314 maya 3227
2315 doda 6173 void CS_n_Mode() // DSR
2316     {
2317     char Report[16];
2318     int X, Y, len;
2319 maya 3227
2320 doda 6173 switch (Param[1]) {
2321     case 5:
2322     /* Device Status Report -> Ready */
2323     SendCSIstr("0n", 0);
2324     break;
2325     case 6:
2326     /* Cursor Position Report */
2327     if (isCursorOnStatusLine) {
2328     X = CursorX + 1;
2329     Y = 1;
2330     }
2331     else if (RelativeOrgMode) {
2332     X = CursorX - CursorLeftM + 1;
2333     Y = CursorY - CursorTop + 1;
2334     }
2335     else {
2336     X = CursorX + 1;
2337     Y = CursorY+1;
2338     }
2339     len = _snprintf_s_l(Report, sizeof(Report), _TRUNCATE, "%u;%uR", CLocale, Y, X);
2340     SendCSIstr(Report, len);
2341     break;
2342 doda 5336 }
2343 doda 6173 }
2344 maya 3227
2345 doda 5095 void ParseSGRParams(PCharAttr attr, PCharAttr mask, int start)
2346 maya 3227 {
2347 doda 5073 int i, j, P, r, g, b, color;
2348 doda 5095 TCharAttr dummy;
2349 maya 3227
2350 doda 5095 if (mask == NULL) {
2351     mask = &dummy;
2352     }
2353    
2354 doda 6173 for (i=start ; i<=NParam ; i++) {
2355 maya 3227 P = Param[i];
2356     switch (P) {
2357 doda 6173 case 0: /* Clear all */
2358 doda 5095 attr->Attr = DefCharAttr.Attr;
2359     attr->Attr2 = DefCharAttr.Attr2 | (attr->Attr2&Attr2Protect);
2360 doda 8445 #if UNICODE_INTERNAL_BUFF
2361     attr->AttrEx = attr->Attr;
2362     #endif
2363 doda 5095 attr->Fore = DefCharAttr.Fore;
2364     attr->Back = DefCharAttr.Back;
2365     mask->Attr = AttrSgrMask;
2366     mask->Attr2 = Attr2ColorMask;
2367 maya 3227 break;
2368    
2369 doda 6173 case 1: /* Bold */
2370 doda 5095 attr->Attr |= AttrBold;
2371     mask->Attr |= AttrBold;
2372 maya 3227 break;
2373    
2374 doda 6173 case 4: /* Under line */
2375 doda 5095 attr->Attr |= AttrUnder;
2376     mask->Attr |= AttrUnder;
2377 maya 3227 break;
2378    
2379 doda 6173 case 5: /* Blink */
2380 doda 5095 attr->Attr |= AttrBlink;
2381     mask->Attr |= AttrBlink;
2382 maya 3227 break;
2383    
2384 doda 6173 case 7: /* Reverse */
2385 doda 5095 attr->Attr |= AttrReverse;
2386     mask->Attr |= AttrReverse;
2387 maya 3227 break;
2388    
2389 doda 6173 case 22: /* Bold off */
2390 doda 5095 attr->Attr &= ~ AttrBold;
2391     mask->Attr |= AttrBold;
2392 maya 3227 break;
2393    
2394 doda 6173 case 24: /* Under line off */
2395 doda 5095 attr->Attr &= ~ AttrUnder;
2396     mask->Attr |= AttrUnder;
2397 maya 3227 break;
2398    
2399 doda 6173 case 25: /* Blink off */
2400 doda 5095 attr->Attr &= ~ AttrBlink;
2401     mask->Attr |= AttrBlink;
2402 maya 3227 break;
2403    
2404 doda 6173 case 27: /* Reverse off */
2405 doda 5095 attr->Attr &= ~ AttrReverse;
2406     mask->Attr |= AttrReverse;
2407 maya 3227 break;
2408    
2409 doda 6173 case 30:
2410     case 31:
2411     case 32:
2412     case 33:
2413     case 34:
2414     case 35:
2415     case 36:
2416     case 37: /* text color */
2417 doda 5095 attr->Attr2 |= Attr2Fore;
2418     mask->Attr2 |= Attr2Fore;
2419     attr->Fore = P - 30;
2420 maya 3227 break;
2421    
2422 doda 6173 case 38: /* text color (256color mode) */
2423 doda 5073 if (ts.ColorFlag & CF_XTERM256) {
2424     /*
2425     * Change foreground color. accept following formats.
2426     *
2427     * 38 ; 2 ; r ; g ; b
2428     * 38 ; 2 : r : g : b
2429     * 38 : 2 : r : g : b
2430     * 38 ; 5 ; idx
2431     * 38 ; 5 : idx
2432     * 38 : 5 : idx
2433     *
2434     */
2435     color = -1;
2436     j = 0;
2437     if (NSParam[i] > 0) {
2438     P = SubParam[i][1];
2439     j++;
2440     }
2441     else if (i < NParam) {
2442     P = Param[i+1];
2443     if (P == 2 || P == 5) {
2444     i++;
2445     }
2446     }
2447     switch (P) {
2448 doda 6173 case 2:
2449 doda 5073 r = g = b = 0;
2450     if (NSParam[i] > 0) {
2451     if (j < NSParam[i]) {
2452     r = SubParam[i][++j];
2453     if (j < NSParam[i]) {
2454     g = SubParam[i][++j];
2455     }
2456     if (j < NSParam[i]) {
2457     b = SubParam[i][++j];
2458     }
2459     color = DispFindClosestColor(r, g, b);
2460     }
2461     }
2462     else if (i < NParam && NSParam[i+1] > 0) {
2463     r = Param[++i];
2464     g = SubParam[i][1];
2465     if (NSParam[i] > 1) {
2466     b = SubParam[i][2];
2467     }
2468     color = DispFindClosestColor(r, g, b);
2469     }
2470     else if (i+2 < NParam) {
2471     r = Param[++i];
2472     g = Param[++i];
2473     b = Param[++i];
2474     color = DispFindClosestColor(r, g, b);
2475     }
2476     break;
2477 doda 6173 case 5:
2478 doda 5073 if (NSParam[i] > 0) {
2479     if (j < NSParam[i]) {
2480     color = SubParam[i][++j];
2481     }
2482     }
2483     else if (i < NParam) {
2484     color = Param[++i];
2485     }
2486     break;
2487     }
2488 doda 5077 if (color >= 0 && color < 256) {
2489