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