Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8445 - (hide annotations) (download) (as text)
Tue Dec 17 12:15:31 2019 UTC (4 years, 3 months ago) by doda
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 160843 byte(s)
Merge branch 'unicode_buf'
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3 doda 8445 * (C) 2004-2019 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, scroll buffer routines */
31    
32     #include "teraterm.h"
33     #include <string.h>
34 yutakapon 4707 #include <stdio.h>
35 doda 8445 #include <windows.h>
36     #define _CRTDBG_MAP_ALLOC
37     #include <crtdbg.h>
38     #include <mbstring.h>
39     #include <assert.h>
40     #include <errno.h>
41 maya 3227
42 doda 8445 #include "tttypes.h"
43 maya 3227 #include "ttwinman.h"
44     #include "teraprn.h"
45     #include "vtdisp.h"
46     #include "clipboar.h"
47     #include "telnet.h"
48     #include "ttplug.h" /* TTPLUG */
49 doda 8445 #include "codeconv.h"
50     #include "unicode.h"
51 maya 3227 #include "buffer.h"
52 doda 8445 #include "unicode_test.h"
53 maya 3227
54 doda 8445 #if UNICODE_INTERNAL_BUFF
55 maya 3227
56 doda 8445 typedef unsigned long char32_t; // C++11
57    
58     // �o�b�t�@�������p1������������
59     typedef struct {
60     char32_t u32;
61     char32_t u32_last;
62     char WidthProperty; // 'W' or 'F' or 'H' or 'A' (����������)
63     char HalfWidth; // TRUE/FALSE = ���p/�S�p (�\������������������)
64     char Padding; // TRUE = �S�p�������l���� or �s�����l����
65     char Emoji; // TRUE = �G����
66     char CombinationCharCount16; // charactor count
67     char CombinationCharSize16; // buffer size
68     char CombinationCharCount32;
69     char CombinationCharSize32;
70     wchar_t *pCombinationChars16;
71     char32_t *pCombinationChars32;
72     wchar_t wc2[2];
73     } buff_char_t;
74     #endif
75    
76 maya 3227 #define BuffXMax TermWidthMax
77     //#define BuffYMax 100000
78     //#define BuffSizeMax 8000000
79     // �X�N���[���o�b�t�@�����������g�� (2004.11.28 yutaka)
80     #define BuffYMax 500000
81     #define BuffSizeMax (BuffYMax * 80)
82    
83     // status line
84 doda 6435 int StatusLine; //0: none 1: shown
85 doda 5324 /* top, bottom, left & right margin */
86     int CursorTop, CursorBottom, CursorLeftM, CursorRightM;
87 doda 8400 BOOL Selected, Selecting;
88 maya 3227 BOOL Wrap;
89    
90     static WORD TabStops[256];
91     static int NTabStops;
92    
93     static WORD BuffLock = 0;
94    
95     static PCHAR CodeBuff; /* Character code buffer */
96     static PCHAR AttrBuff; /* Attribute buffer */
97     static PCHAR AttrBuff2; /* Color attr buffer */
98     static PCHAR AttrBuffFG; /* Foreground color attr buffer */
99     static PCHAR AttrBuffBG; /* Background color attr buffer */
100     static PCHAR CodeLine;
101     static PCHAR AttrLine;
102     static PCHAR AttrLine2;
103     static PCHAR AttrLineFG;
104     static PCHAR AttrLineBG;
105 doda 8445 #if UNICODE_INTERNAL_BUFF
106     static buff_char_t *CodeBuffW;
107     static buff_char_t *CodeLineW;
108     #endif
109 maya 3227 static LONG LinePtr;
110     static LONG BufferSize;
111     static int NumOfLinesInBuff;
112     static int BuffStartAbs, BuffEndAbs;
113 doda 8400 static POINT SelectStart, SelectStartTmp, SelectEnd, SelectEndOld;
114     static DWORD SelectStartTime;
115 maya 3227 static BOOL BoxSelect;
116     static POINT DblClkStart, DblClkEnd;
117    
118 doda 8445 // �`��
119     static int StrChangeStart; // �`���J�n X (Y=CursorY)
120     static int StrChangeCount; // �`���L�����N�^��(���p�P��),0�������`����������������
121 maya 3227
122     static BOOL SeveralPageSelect; // add (2005.5.15 yutaka)
123    
124     static TCharAttr CurCharAttr;
125    
126 doda 8445 static char *SaveBuff = NULL;
127     static int SaveBuffX;
128     static int SaveBuffY;
129 doda 3743
130 doda 8445 #if UNICODE_INTERNAL_BUFF
131     static void BuffDrawLineI(int DrawX, int DrawY, int SY, int IStart, int IEnd);
132     #endif
133    
134     #if UNICODE_INTERNAL_BUFF
135     static void BuffSetChar2(buff_char_t *buff, char32_t u32, char property, BOOL half_width, char emoji)
136 maya 3227 {
137 doda 8445 size_t wstr_len;
138     buff_char_t *p = buff;
139     if (p->pCombinationChars16 != NULL) {
140     free(p->pCombinationChars16);
141     p->pCombinationChars16 = NULL;
142     }
143     p->CombinationCharCount16 = 0;
144     p->CombinationCharSize16 = 0;
145     if (p->pCombinationChars32 != NULL) {
146     free(p->pCombinationChars32);
147     p->pCombinationChars32 = NULL;
148     }
149     p->CombinationCharCount32 = 0;
150     p->CombinationCharSize32 = 0;
151     p->WidthProperty = property;
152     p->HalfWidth = (char)half_width;
153     p->u32 = u32;
154     p->u32_last = u32;
155     p->Padding = FALSE;
156     p->Emoji = emoji;
157    
158     //
159     wstr_len = UTF32ToUTF16(u32, &p->wc2[0], 2);
160     switch (wstr_len) {
161     case 0:
162     default:
163     p->wc2[0] = 0;
164     p->wc2[1] = 0;
165     break;
166     case 1:
167     p->wc2[1] = 0;
168     break;
169     case 2:
170     break;
171     }
172     }
173    
174     static void BuffSetChar(buff_char_t *buff, char32_t u32, char property)
175     {
176     BuffSetChar2(buff, u32, property, TRUE, FALSE);
177     }
178    
179     /**
180     * �����������A�R���r�l�[�V����
181     */
182     static void BuffAddChar(buff_char_t *buff, char32_t u32)
183     {
184     buff_char_t *p = buff;
185     assert(p->u32 != 0);
186     // �������������������g������
187     if (p->CombinationCharSize16 < p->CombinationCharCount16 + 2) {
188     size_t new_size = p->CombinationCharSize16;
189     new_size = new_size == 0 ? 5 : new_size * 2;
190     p->pCombinationChars16 = realloc(p->pCombinationChars16, sizeof(wchar_t) * new_size);
191     p->CombinationCharSize16 = (char)new_size;
192     }
193     if (p->CombinationCharSize32 < p->CombinationCharCount32 + 2) {
194     size_t new_size = p->CombinationCharSize32;
195     new_size = new_size == 0 ? 5 : new_size * 2;
196     p->pCombinationChars32 = realloc(p->pCombinationChars32, sizeof(char32_t) * new_size);
197     p->CombinationCharSize32 = (char)new_size;
198     }
199    
200     // UTF-32
201     p->u32_last = u32;
202     p->pCombinationChars32[(size_t)p->CombinationCharCount32] = u32;
203     p->CombinationCharCount32++;
204    
205     // UTF-16
206     {
207     wchar_t *u16 = &p->pCombinationChars16[(size_t)p->CombinationCharCount16];
208     size_t wlen = UTF32ToUTF16(u32, u16, 2);
209     p->CombinationCharCount16 += (char)wlen;
210     }
211     }
212    
213     static void memcpyW(buff_char_t *dest, const buff_char_t *src, size_t count)
214     {
215     size_t i;
216     memcpy(dest, src, count * sizeof(buff_char_t));
217     for (i=0; i<count; i++) {
218     buff_char_t *p = &dest[i];
219     size_t size = p->CombinationCharSize16;
220     if (size > 0) {
221     wchar_t *new_buf = malloc(sizeof(wchar_t) * size);
222     memcpy(new_buf, p->pCombinationChars16, sizeof(wchar_t) * size);
223     p->pCombinationChars16 = new_buf;
224     }
225     size = p->CombinationCharSize32;
226     if (size > 0) {
227     char32_t *new_buf = malloc(sizeof(char32_t) * size);
228     memcpy(new_buf, p->pCombinationChars32, sizeof(char32_t) * size);
229     p->pCombinationChars32 = new_buf;
230     }
231     }
232     }
233    
234     static void memsetW(buff_char_t *dest, wchar_t ch, size_t count)
235     {
236     size_t i;
237     for (i=0; i<count; i++) {
238     BuffSetChar(dest, ch, 'H');
239     dest++;
240     }
241     }
242    
243     static void memmoveW(buff_char_t *dest, const buff_char_t *src, size_t count)
244     {
245     memmove(dest, src, count * sizeof(buff_char_t));
246     }
247    
248     static BOOL IsBuffPadding(const buff_char_t *b)
249     {
250     if (b->Padding == TRUE)
251     return TRUE;
252     if (b->u32 == 0)
253     return TRUE;
254     return FALSE;
255     }
256    
257     static BOOL IsBuffFullWidth(const buff_char_t *b)
258     {
259     if (b->HalfWidth == FALSE)
260     return TRUE;
261     return FALSE;
262     }
263    
264     #endif
265    
266     static LONG GetLinePtr(int Line)
267     {
268 maya 3393 LONG Ptr;
269 maya 3227
270 maya 3393 Ptr = (LONG)(BuffStartAbs + Line) * (LONG)(NumOfColumns);
271     while (Ptr>=BufferSize) {
272     Ptr = Ptr - BufferSize;
273     }
274     return Ptr;
275 maya 3227 }
276    
277 doda 8445 static LONG NextLinePtr(LONG Ptr)
278 maya 3227 {
279 maya 3393 Ptr = Ptr + (LONG)NumOfColumns;
280     if (Ptr >= BufferSize) {
281     Ptr = Ptr - BufferSize;
282     }
283     return Ptr;
284 maya 3227 }
285    
286 doda 8445 static LONG PrevLinePtr(LONG Ptr)
287 maya 3227 {
288 maya 3393 Ptr = Ptr - (LONG)NumOfColumns;
289     if (Ptr < 0) {
290     Ptr = Ptr + BufferSize;
291     }
292     return Ptr;
293 maya 3227 }
294    
295 doda 8445 static BOOL ChangeBuffer(int Nx, int Ny)
296 maya 3227 {
297 maya 3393 LONG NewSize;
298     int NxCopy, NyCopy, i;
299     PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG;
300     LONG SrcPtr, DestPtr;
301     WORD LockOld;
302 doda 8445 #if UNICODE_INTERNAL_BUFF
303     buff_char_t *CodeDestW;
304     #endif
305 maya 3227
306 maya 3393 if (Nx > BuffXMax) {
307     Nx = BuffXMax;
308     }
309     if (ts.ScrollBuffMax > BuffYMax) {
310     ts.ScrollBuffMax = BuffYMax;
311     }
312     if (Ny > ts.ScrollBuffMax) {
313     Ny = ts.ScrollBuffMax;
314     }
315 maya 3227
316 maya 3393 if ( (LONG)Nx * (LONG)Ny > BuffSizeMax ) {
317     Ny = BuffSizeMax / Nx;
318     }
319 maya 3227
320 maya 3393 NewSize = (LONG)Nx * (LONG)Ny;
321 maya 3227
322 doda 8445 CodeDest = NULL;
323     AttrDest = NULL;
324     AttrDest2 = NULL;
325     AttrDestFG = NULL;
326     AttrDestBG = NULL;
327     #if UNICODE_INTERNAL_BUFF
328     CodeDestW = NULL;
329     #endif
330 maya 3227
331 doda 8445 CodeDest = malloc(NewSize);
332     if (CodeDest == NULL) {
333 doda 3686 goto allocate_error;
334 maya 3393 }
335 doda 8445 AttrDest = malloc(NewSize);
336     if (AttrDest == NULL) {
337 doda 3686 goto allocate_error;
338 maya 3393 }
339 doda 8445 AttrDest2 = malloc(NewSize);
340     if (AttrDest2 == NULL) {
341 doda 3686 goto allocate_error;
342 maya 3393 }
343 doda 8445 AttrDestFG = malloc(NewSize);
344     if (AttrDestFG == NULL) {
345 doda 3686 goto allocate_error;
346 maya 3393 }
347 doda 8445 AttrDestBG = malloc(NewSize);
348     if (AttrDestBG == NULL) {
349 doda 3686 goto allocate_error;
350 maya 3393 }
351 doda 8445 #if UNICODE_INTERNAL_BUFF
352     CodeDestW = malloc(NewSize * sizeof(buff_char_t));
353     if (CodeDestW == NULL) {
354     goto allocate_error;
355     }
356     #endif
357 maya 3227
358 maya 3393 memset(&CodeDest[0], 0x20, NewSize);
359 doda 8445 #if UNICODE_INTERNAL_BUFF
360     memset(&CodeDestW[0], 0, NewSize * sizeof(buff_char_t));
361     memsetW(&CodeDestW[0], 0x20, NewSize);
362     #endif
363 maya 3393 memset(&AttrDest[0], AttrDefault, NewSize);
364     memset(&AttrDest2[0], AttrDefault, NewSize);
365     memset(&AttrDestFG[0], AttrDefaultFG, NewSize);
366     memset(&AttrDestBG[0], AttrDefaultBG, NewSize);
367 doda 8445 if ( CodeBuff != NULL ) {
368 maya 3393 if ( NumOfColumns > Nx ) {
369     NxCopy = Nx;
370     }
371     else {
372     NxCopy = NumOfColumns;
373     }
374 maya 3227
375 maya 3393 if ( BuffEnd > Ny ) {
376     NyCopy = Ny;
377     }
378     else {
379     NyCopy = BuffEnd;
380     }
381     LockOld = BuffLock;
382     LockBuffer();
383     SrcPtr = GetLinePtr(BuffEnd-NyCopy);
384     DestPtr = 0;
385     for (i = 1 ; i <= NyCopy ; i++) {
386     memcpy(&CodeDest[DestPtr],&CodeBuff[SrcPtr],NxCopy);
387 doda 8445 #if UNICODE_INTERNAL_BUFF
388     memcpyW(&CodeDestW[DestPtr],&CodeBuffW[SrcPtr],NxCopy);
389     #endif
390 maya 3393 memcpy(&AttrDest[DestPtr],&AttrBuff[SrcPtr],NxCopy);
391     memcpy(&AttrDest2[DestPtr],&AttrBuff2[SrcPtr],NxCopy);
392     memcpy(&AttrDestFG[DestPtr],&AttrBuffFG[SrcPtr],NxCopy);
393     memcpy(&AttrDestBG[DestPtr],&AttrBuffBG[SrcPtr],NxCopy);
394 doda 3766 if (AttrDest[DestPtr+NxCopy-1] & AttrKanji) {
395     CodeDest[DestPtr+NxCopy-1] = ' ';
396     AttrDest[DestPtr+NxCopy-1] ^= AttrKanji;
397     }
398 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
399     DestPtr = DestPtr + (LONG)Nx;
400     }
401     FreeBuffer();
402     }
403     else {
404     LockOld = 0;
405     NyCopy = NumOfLines;
406     Selected = FALSE;
407     }
408 maya 3227
409 maya 3393 if (Selected) {
410     SelectStart.y = SelectStart.y - BuffEnd + NyCopy;
411     SelectEnd.y = SelectEnd.y - BuffEnd + NyCopy;
412     if (SelectStart.y < 0) {
413     SelectStart.y = 0;
414     SelectStart.x = 0;
415     }
416     if (SelectEnd.y<0) {
417     SelectEnd.x = 0;
418     SelectEnd.y = 0;
419     }
420 maya 3227
421 maya 3393 Selected = (SelectEnd.y > SelectStart.y) ||
422 zmatsuo 8411 ((SelectEnd.y == SelectStart.y) &&
423 maya 3393 (SelectEnd.x > SelectStart.x));
424     }
425 maya 3227
426 doda 8445 CodeBuff = CodeDest;
427     AttrBuff = AttrDest;
428     AttrBuff2 = AttrDest2;
429     AttrBuffFG = AttrDestFG;
430     AttrBuffBG = AttrDestBG;
431     #if UNICODE_INTERNAL_BUFF
432     CodeBuffW = CodeDestW;
433     #endif
434 maya 3393 BufferSize = NewSize;
435     NumOfLinesInBuff = Ny;
436     BuffStartAbs = 0;
437     BuffEnd = NyCopy;
438 maya 3227
439 maya 3393 if (BuffEnd==NumOfLinesInBuff) {
440     BuffEndAbs = 0;
441     }
442     else {
443     BuffEndAbs = BuffEnd;
444     }
445 maya 3227
446 maya 3393 PageStart = BuffEnd - NumOfLines;
447    
448     LinePtr = 0;
449     if (LockOld>0) {
450     CodeLine = CodeBuff;
451 doda 8445 #if UNICODE_INTERNAL_BUFF
452     CodeLineW = CodeBuffW;
453     #endif
454 maya 3393 AttrLine = AttrBuff;
455     AttrLine2 = AttrBuff2;
456     AttrLineFG = AttrBuffFG;
457     AttrLineBG = AttrBuffBG;
458     }
459     else {
460 doda 8445 ;
461 maya 3393 }
462     BuffLock = LockOld;
463    
464     return TRUE;
465 doda 3686
466     allocate_error:
467 doda 8445 if (CodeDest) free(CodeDest);
468     if (AttrDest) free(AttrDest);
469     if (AttrDest2) free(AttrDest2);
470     if (AttrDestFG) free(AttrDestFG);
471     if (AttrDestBG) free(AttrDestBG);
472     #if UNICODE_INTERNAL_BUFF
473     if (CodeDestW) free(CodeDestW);
474     #endif
475 doda 3686 return FALSE;
476 maya 3227 }
477    
478     void InitBuffer()
479     {
480 maya 3393 int Ny;
481 maya 3227
482 maya 3393 /* setup terminal */
483     NumOfColumns = ts.TerminalWidth;
484     NumOfLines = ts.TerminalHeight;
485 maya 3227
486 doda 6785 if (NumOfColumns <= 0)
487     NumOfColumns = 80;
488     else if (NumOfColumns > TermWidthMax)
489     NumOfColumns = TermWidthMax;
490    
491     if (NumOfLines <= 0)
492     NumOfLines = 24;
493     else if (NumOfLines > TermHeightMax)
494     NumOfLines = TermHeightMax;
495    
496 maya 3393 /* setup window */
497     if (ts.EnableScrollBuff>0) {
498     if (ts.ScrollBuffSize < NumOfLines) {
499     ts.ScrollBuffSize = NumOfLines;
500     }
501     Ny = ts.ScrollBuffSize;
502     }
503     else {
504     Ny = NumOfLines;
505     }
506 maya 3227
507 maya 3393 if (! ChangeBuffer(NumOfColumns,Ny)) {
508     PostQuitMessage(0);
509     }
510 maya 3227
511 maya 3393 if (ts.EnableScrollBuff>0) {
512     ts.ScrollBuffSize = NumOfLinesInBuff;
513     }
514 maya 3227
515 maya 3393 StatusLine = 0;
516 maya 3227 }
517    
518 doda 8445 static void NewLine(int Line)
519 maya 3227 {
520 maya 3393 LinePtr = GetLinePtr(Line);
521     CodeLine = &CodeBuff[LinePtr];
522     AttrLine = &AttrBuff[LinePtr];
523     AttrLine2 = &AttrBuff2[LinePtr];
524     AttrLineFG = &AttrBuffFG[LinePtr];
525     AttrLineBG = &AttrBuffBG[LinePtr];
526 doda 8445 #if UNICODE_INTERNAL_BUFF
527     CodeLineW = &CodeBuffW[LinePtr];
528     #endif
529 maya 3227 }
530    
531     void LockBuffer()
532     {
533 maya 3393 BuffLock++;
534     if (BuffLock>1) {
535     return;
536     }
537     NewLine(PageStart+CursorY);
538 maya 3227 }
539    
540     void UnlockBuffer()
541     {
542 maya 3393 if (BuffLock==0) {
543     return;
544     }
545     BuffLock--;
546     if (BuffLock>0) {
547     return;
548     }
549 maya 3227 }
550    
551     void FreeBuffer()
552     {
553 maya 3393 BuffLock = 1;
554     UnlockBuffer();
555 doda 8445 if (CodeBuff!=NULL) {
556     free(CodeBuff);
557     CodeBuff = NULL;
558 maya 3393 }
559 doda 8445 #if UNICODE_INTERNAL_BUFF
560     if (CodeBuffW != NULL) {
561     free(CodeBuffW);
562     CodeBuffW = NULL;
563 maya 3393 }
564 doda 8445 #endif
565     if (AttrBuff!=NULL) {
566     free(AttrBuff);
567     AttrBuff = NULL;
568 maya 3393 }
569 doda 8445 if (AttrBuff2!=NULL) {
570     free(AttrBuff2);
571     AttrBuff2 = NULL;
572 maya 3393 }
573 doda 8445 if (AttrBuffFG!=NULL) {
574     free(AttrBuffFG);
575     AttrBuffFG = NULL;
576 maya 3393 }
577 doda 8445 if (AttrBuffBG!=NULL) {
578     free(AttrBuffBG);
579     AttrBuffBG = NULL;
580     }
581 maya 3227 }
582    
583     void BuffAllSelect()
584     {
585     SelectStart.x = 0;
586     SelectStart.y = 0;
587     SelectEnd.x = 0;
588     SelectEnd.y = BuffEnd;
589     // SelectEnd.x = NumOfColumns;
590     // SelectEnd.y = BuffEnd - 1;
591 doda 8400 Selecting = TRUE;
592 maya 3227 }
593    
594     void BuffScreenSelect()
595     {
596     int X, Y;
597     DispConvWinToScreen(0, 0, &X, &Y, NULL);
598     SelectStart.x = X;
599     SelectStart.y = Y + PageStart;
600     SelectEnd.x = 0;
601     SelectEnd.y = SelectStart.y + NumOfLines;
602     // SelectEnd.x = X + NumOfColumns;
603     // SelectEnd.y = Y + PageStart + NumOfLines - 1;
604 doda 8400 Selecting = TRUE;
605 maya 3227 }
606    
607     void BuffCancelSelection()
608     {
609     SelectStart.x = 0;
610     SelectStart.y = 0;
611     SelectEnd.x = 0;
612     SelectEnd.y = 0;
613 doda 8400 Selecting = FALSE;
614 maya 3227 }
615    
616     void BuffReset()
617     // Reset buffer status. don't update real display
618     // called by ResetTerminal()
619     {
620 maya 3393 int i;
621 maya 3227
622 maya 3393 /* Cursor */
623     NewLine(PageStart);
624     WinOrgX = 0;
625     WinOrgY = 0;
626     NewOrgX = 0;
627     NewOrgY = 0;
628 maya 3227
629 maya 3393 /* Top/bottom margin */
630     CursorTop = 0;
631     CursorBottom = NumOfLines-1;
632 doda 5324 CursorLeftM = 0;
633     CursorRightM = NumOfColumns-1;
634 maya 3227
635 maya 3393 /* Tab stops */
636     NTabStops = (NumOfColumns-1) >> 3;
637     for (i=1 ; i<=NTabStops ; i++) {
638 doda 8445 TabStops[i-1] = (WORD)(i*8);
639 maya 3393 }
640 maya 3227
641 maya 3393 /* Initialize text selection region */
642     SelectStart.x = 0;
643     SelectStart.y = 0;
644     SelectEnd = SelectStart;
645     SelectEndOld = SelectStart;
646     Selected = FALSE;
647 maya 3227
648 maya 3393 StrChangeCount = 0;
649     Wrap = FALSE;
650     StatusLine = 0;
651 maya 3227
652 maya 3393 SeveralPageSelect = FALSE; // yutaka
653 doda 3745
654     /* Alternate Screen Buffer */
655     BuffDiscardSavedScreen();
656 maya 3227 }
657    
658     void BuffScroll(int Count, int Bottom)
659     {
660 maya 3393 int i, n;
661     LONG SrcPtr, DestPtr;
662     int BuffEndOld;
663 maya 3227
664 maya 3393 if (Count>NumOfLinesInBuff) {
665     Count = NumOfLinesInBuff;
666     }
667 maya 3227
668 maya 3393 DestPtr = GetLinePtr(PageStart+NumOfLines-1+Count);
669     n = Count;
670     if (Bottom<NumOfLines-1) {
671     SrcPtr = GetLinePtr(PageStart+NumOfLines-1);
672     for (i=NumOfLines-1; i>=Bottom+1; i--) {
673     memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
674 doda 8445 #if UNICODE_INTERNAL_BUFF
675     memcpyW(&(CodeBuffW[DestPtr]),&(CodeBuffW[SrcPtr]),NumOfColumns);
676     #endif
677 maya 3393 memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
678     memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
679     memcpy(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
680     memcpy(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
681     memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
682 doda 8445 #if UNICODE_INTERNAL_BUFF
683     memsetW(&(CodeBuffW[SrcPtr]),0x20,NumOfColumns);
684     #endif
685 maya 3393 memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
686 doda 4070 memset(&(AttrBuff2[SrcPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
687 maya 3393 memset(&(AttrBuffFG[SrcPtr]),CurCharAttr.Fore,NumOfColumns);
688     memset(&(AttrBuffBG[SrcPtr]),CurCharAttr.Back,NumOfColumns);
689     SrcPtr = PrevLinePtr(SrcPtr);
690     DestPtr = PrevLinePtr(DestPtr);
691     n--;
692     }
693     }
694     for (i = 1 ; i <= n ; i++) {
695     memset(&CodeBuff[DestPtr],0x20,NumOfColumns);
696 doda 8445 #if UNICODE_INTERNAL_BUFF
697     memsetW(&CodeBuffW[DestPtr],0x20,NumOfColumns);
698     #endif
699 maya 3393 memset(&AttrBuff[DestPtr],AttrDefault,NumOfColumns);
700 doda 4070 memset(&AttrBuff2[DestPtr],CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
701 maya 3393 memset(&AttrBuffFG[DestPtr],CurCharAttr.Fore,NumOfColumns);
702     memset(&AttrBuffBG[DestPtr],CurCharAttr.Back,NumOfColumns);
703     DestPtr = PrevLinePtr(DestPtr);
704     }
705 maya 3227
706 maya 3393 BuffEndAbs = BuffEndAbs + Count;
707     if (BuffEndAbs >= NumOfLinesInBuff) {
708     BuffEndAbs = BuffEndAbs - NumOfLinesInBuff;
709     }
710     BuffEndOld = BuffEnd;
711     BuffEnd = BuffEnd + Count;
712     if (BuffEnd >= NumOfLinesInBuff) {
713     BuffEnd = NumOfLinesInBuff;
714     BuffStartAbs = BuffEndAbs;
715     }
716     PageStart = BuffEnd-NumOfLines;
717 maya 3227
718 maya 3393 if (Selected) {
719     SelectStart.y = SelectStart.y - Count + BuffEnd - BuffEndOld;
720     SelectEnd.y = SelectEnd.y - Count + BuffEnd - BuffEndOld;
721     if ( SelectStart.y<0 ) {
722     SelectStart.x = 0;
723     SelectStart.y = 0;
724     }
725     if ( SelectEnd.y<0 ) {
726     SelectEnd.x = 0;
727     SelectEnd.y = 0;
728     }
729     Selected = (SelectEnd.y > SelectStart.y) ||
730     ((SelectEnd.y==SelectStart.y) &&
731     (SelectEnd.x > SelectStart.x));
732     }
733 maya 3227
734 maya 3393 NewLine(PageStart+CursorY);
735 maya 3227 }
736    
737     void NextLine()
738     {
739 maya 3393 LinePtr = NextLinePtr(LinePtr);
740     CodeLine = &CodeBuff[LinePtr];
741     AttrLine = &AttrBuff[LinePtr];
742     AttrLine2 = &AttrBuff2[LinePtr];
743     AttrLineFG = &AttrBuffFG[LinePtr];
744     AttrLineBG = &AttrBuffBG[LinePtr];
745 doda 8445 #if UNICODE_INTERNAL_BUFF
746     CodeLineW = &CodeBuffW[LinePtr];
747     #endif
748 maya 3227 }
749    
750     void PrevLine()
751     {
752 maya 3393 LinePtr = PrevLinePtr(LinePtr);
753     CodeLine = &CodeBuff[LinePtr];
754     AttrLine = &AttrBuff[LinePtr];
755     AttrLine2 = &AttrBuff2[LinePtr];
756     AttrLineFG = &AttrBuffFG[LinePtr];
757     AttrLineBG = &AttrBuffBG[LinePtr];
758 doda 8445 #if UNICODE_INTERNAL_BUFF
759     CodeLineW = &CodeBuffW[LinePtr];
760     #endif
761 maya 3227 }
762    
763     // If cursor is on left/right half of a Kanji, erase it.
764     // LR: left(0)/right(1) flag
765 doda 8445 // LR 0 �J�[�\��������������
766     // 1 �J�[�\�����������E��
767     static void EraseKanji(int LR)
768     {
769     #if UNICODE_INTERNAL_BUFF
770     buff_char_t *p;
771     int bx;
772     if (CursorX < LR) {
773     // �S�p������������
774     return;
775     }
776     bx = CursorX-LR;
777     p = &CodeLineW[bx];
778     if (IsBuffFullWidth(p)) {
779     // �S�p��������
780     BuffSetChar(p, ' ', 'H');
781     CodeLine[bx] = 0x20;
782     AttrLine[bx] = CurCharAttr.Attr;
783     AttrLine2[bx] = CurCharAttr.Attr2;
784     AttrLineFG[bx] = CurCharAttr.Fore;
785     AttrLineBG[bx] = CurCharAttr.Back;
786     if (bx+1 < NumOfColumns) {
787     BuffSetChar(p + 1, ' ', 'H');
788     CodeLine[bx+1] = 0x20;
789     AttrLine[bx+1] = CurCharAttr.Attr;
790     AttrLine2[bx+1] = CurCharAttr.Attr2;
791     AttrLineFG[bx+1] = CurCharAttr.Fore;
792     AttrLineBG[bx+1] = CurCharAttr.Back;
793     }
794     }
795     #else
796 maya 3393 if ((CursorX-LR>=0) &&
797     ((AttrLine[CursorX-LR] & AttrKanji) != 0)) {
798     CodeLine[CursorX-LR] = 0x20;
799     AttrLine[CursorX-LR] = CurCharAttr.Attr;
800     AttrLine2[CursorX-LR] = CurCharAttr.Attr2;
801     AttrLineFG[CursorX-LR] = CurCharAttr.Fore;
802     AttrLineBG[CursorX-LR] = CurCharAttr.Back;
803     if (CursorX-LR+1 < NumOfColumns) {
804     CodeLine[CursorX-LR+1] = 0x20;
805     AttrLine[CursorX-LR+1] = CurCharAttr.Attr;
806     AttrLine2[CursorX-LR+1] = CurCharAttr.Attr2;
807     AttrLineFG[CursorX-LR+1] = CurCharAttr.Fore;
808     AttrLineBG[CursorX-LR+1] = CurCharAttr.Back;
809     }
810     }
811 doda 8445 #endif
812 maya 3227 }
813    
814 doda 5371 void EraseKanjiOnLRMargin(LONG ptr, int count)
815     {
816     int i;
817     LONG pos;
818    
819     if (count < 1)
820     return;
821    
822     for (i=0; i<count; i++) {
823     pos = ptr + CursorLeftM-1;
824     if (CursorLeftM>0 && (AttrBuff[pos] & AttrKanji)) {
825     CodeBuff[pos] = 0x20;
826 doda 8445 #if UNICODE_INTERNAL_BUFF
827     BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
828     #endif
829 doda 5371 AttrBuff[pos] &= ~AttrKanji;
830     pos++;
831     CodeBuff[pos] = 0x20;
832 doda 8445 #if UNICODE_INTERNAL_BUFF
833     BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
834     #endif
835 doda 5371 AttrBuff[pos] &= ~AttrKanji;
836     }
837     pos = ptr + CursorRightM;
838     if (CursorRightM < NumOfColumns-1 && (AttrBuff[pos] & AttrKanji)) {
839     CodeBuff[pos] = 0x20;
840 doda 8445 #if UNICODE_INTERNAL_BUFF
841     BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
842     #endif
843 doda 5371 AttrBuff[pos] &= ~AttrKanji;
844     pos++;
845     CodeBuff[pos] = 0x20;
846 doda 8445 #if UNICODE_INTERNAL_BUFF
847     BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
848     #endif
849 doda 5371 AttrBuff[pos] &= ~AttrKanji;
850     }
851     ptr = NextLinePtr(ptr);
852     }
853     }
854    
855 doda 8445 // Insert space characters at the current position
856     // Count: Number of characters to be inserted
857     #if UNICODE_INTERNAL_BUFF
858 maya 3227 void BuffInsertSpace(int Count)
859 doda 8445 {
860     int MoveLen;
861     int extr = 0;
862     int sx;
863     buff_char_t *b;
864    
865     if (CursorX < CursorLeftM || CursorX > CursorRightM)
866     return;
867    
868     NewLine(PageStart + CursorY);
869    
870     sx = CursorX;
871     b = &CodeLineW[CursorX];
872     if (IsBuffPadding(b)) {
873     /* if cursor is on right half of a kanji, erase the kanji */
874     BuffSetChar(b - 1, ' ', 'H');
875     BuffSetChar(b, ' ', 'H');
876     AttrLine[CursorX] &= ~AttrKanji;
877     sx--;
878     extr++;
879     }
880    
881     if (CursorRightM < NumOfColumns - 1 && (AttrLine[CursorRightM] & AttrKanji)) {
882     CodeLine[CursorRightM + 1] = 0x20;
883     BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
884     AttrLine[CursorRightM + 1] &= ~AttrKanji;
885     extr++;
886     }
887    
888     if (Count > CursorRightM + 1 - CursorX)
889     Count = CursorRightM + 1 - CursorX;
890    
891     MoveLen = CursorRightM + 1 - CursorX - Count;
892    
893     if (MoveLen > 0) {
894     memmove(&(CodeLine[CursorX + Count]), &(CodeLine[CursorX]), MoveLen);
895     memmoveW(&(CodeLineW[CursorX + Count]), &(CodeLineW[CursorX]), MoveLen);
896     memmove(&(AttrLine[CursorX + Count]), &(AttrLine[CursorX]), MoveLen);
897     memmove(&(AttrLine2[CursorX + Count]), &(AttrLine2[CursorX]), MoveLen);
898     memmove(&(AttrLineFG[CursorX + Count]), &(AttrLineFG[CursorX]), MoveLen);
899     memmove(&(AttrLineBG[CursorX + Count]), &(AttrLineBG[CursorX]), MoveLen);
900     }
901     memset(&(CodeLine[CursorX]), 0x20, Count);
902     memsetW(&(CodeLineW[CursorX]), 0x20, Count);
903     memset(&(AttrLine[CursorX]), AttrDefault, Count);
904     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
905     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
906     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
907     /* last char in current line is kanji first? */
908     if ((AttrLine[CursorRightM] & AttrKanji) != 0) {
909     /* then delete it */
910     CodeLine[CursorRightM] = 0x20;
911     BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
912     AttrLine[CursorRightM] &= ~AttrKanji;
913     }
914     BuffUpdateRect(sx, CursorY, CursorRightM + extr, CursorY);
915     }
916     #else
917     void BuffInsertSpace(int Count)
918 maya 3227 // Insert space characters at the current position
919     // Count: Number of characters to be inserted
920     {
921 doda 5326 int MoveLen;
922 doda 5371 int extr=0;
923 doda 5324
924 doda 5326 if (CursorX < CursorLeftM || CursorX > CursorRightM)
925     return;
926    
927 maya 3393 NewLine(PageStart+CursorY);
928 maya 3227
929 doda 5324 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8)
930 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
931 maya 3227
932 doda 5371 if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) {
933     CodeLine[CursorRightM+1] = 0x20;
934 doda 8445 #if UNICODE_INTERNAL_BUFF
935     BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
936     #endif
937 doda 5371 AttrLine[CursorRightM+1] &= ~AttrKanji;
938     extr = 1;
939     }
940    
941 doda 5326 if (Count > CursorRightM + 1 - CursorX)
942     Count = CursorRightM + 1 - CursorX;
943 doda 5324
944 doda 5326 MoveLen = CursorRightM + 1 - CursorX - Count;
945 doda 5324
946     if (MoveLen > 0) {
947     memmove(&(CodeLine[CursorX+Count]), &(CodeLine[CursorX]), MoveLen);
948 doda 8445 #if UNICODE_INTERNAL_BUFF
949     memmoveW(&(CodeLineW[CursorX+Count]), &(CodeLineW[CursorX]), MoveLen);
950     #endif
951 doda 5324 memmove(&(AttrLine[CursorX+Count]), &(AttrLine[CursorX]), MoveLen);
952     memmove(&(AttrLine2[CursorX+Count]), &(AttrLine2[CursorX]), MoveLen);
953     memmove(&(AttrLineFG[CursorX+Count]), &(AttrLineFG[CursorX]), MoveLen);
954     memmove(&(AttrLineBG[CursorX+Count]), &(AttrLineBG[CursorX]), MoveLen);
955 maya 3393 }
956 doda 5324 memset(&(CodeLine[CursorX]), 0x20, Count);
957 doda 8445 #if UNICODE_INTERNAL_BUFF
958     memsetW(&(CodeLineW[CursorX]), 0x20, Count);
959     #endif
960 doda 5324 memset(&(AttrLine[CursorX]), AttrDefault, Count);
961     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
962     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
963     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
964 maya 3393 /* last char in current line is kanji first? */
965 doda 5326 if ((AttrLine[CursorRightM] & AttrKanji) != 0) {
966 maya 3393 /* then delete it */
967 doda 5326 CodeLine[CursorRightM] = 0x20;
968 doda 8445 #if UNICODE_INTERNAL_BUFF
969     BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
970     #endif
971 doda 5371 AttrLine[CursorRightM] &= ~AttrKanji;
972 maya 3393 }
973 doda 5371 BuffUpdateRect(CursorX, CursorY, CursorRightM+extr, CursorY);
974 maya 3227 }
975 doda 8445 #endif
976 maya 3227
977     void BuffEraseCurToEnd()
978     // Erase characters from cursor to the end of screen
979     {
980 maya 3393 LONG TmpPtr;
981     int offset;
982     int i, YEnd;
983 maya 3227
984 maya 3393 NewLine(PageStart+CursorY);
985 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
986 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
987     }
988     offset = CursorX;
989     TmpPtr = GetLinePtr(PageStart+CursorY);
990     YEnd = NumOfLines-1;
991 doda 5324 if (StatusLine && !isCursorOnStatusLine) {
992 maya 3393 YEnd--;
993     }
994     for (i = CursorY ; i <= YEnd ; i++) {
995     memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset);
996 doda 8445 #if UNICODE_INTERNAL_BUFF
997     memsetW(&(CodeBuffW[TmpPtr+offset]),0x20,NumOfColumns-offset);
998     #endif
999 maya 3393 memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset);
1000 doda 4070 memset(&(AttrBuff2[TmpPtr+offset]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset);
1001 maya 3393 memset(&(AttrBuffFG[TmpPtr+offset]),CurCharAttr.Fore,NumOfColumns-offset);
1002     memset(&(AttrBuffBG[TmpPtr+offset]),CurCharAttr.Back,NumOfColumns-offset);
1003     offset = 0;
1004     TmpPtr = NextLinePtr(TmpPtr);
1005     }
1006     /* update window */
1007     DispEraseCurToEnd(YEnd);
1008 maya 3227 }
1009    
1010     void BuffEraseHomeToCur()
1011     // Erase characters from home to cursor
1012     {
1013 maya 3393 LONG TmpPtr;
1014     int offset;
1015     int i, YHome;
1016 maya 3227
1017 maya 3393 NewLine(PageStart+CursorY);
1018 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1019 maya 3393 EraseKanji(0); /* if cursor is on left half of a kanji, erase the kanji */
1020     }
1021     offset = NumOfColumns;
1022 doda 5324 if (isCursorOnStatusLine) {
1023 maya 3393 YHome = CursorY;
1024     }
1025     else {
1026     YHome = 0;
1027     }
1028     TmpPtr = GetLinePtr(PageStart+YHome);
1029     for (i = YHome ; i <= CursorY ; i++) {
1030     if (i==CursorY) {
1031     offset = CursorX+1;
1032     }
1033     memset(&(CodeBuff[TmpPtr]),0x20,offset);
1034 doda 8445 #if UNICODE_INTERNAL_BUFF
1035     memsetW(&(CodeBuffW[TmpPtr]),0x20,offset);
1036     #endif
1037 maya 3393 memset(&(AttrBuff[TmpPtr]),AttrDefault,offset);
1038 doda 4070 memset(&(AttrBuff2[TmpPtr]),CurCharAttr.Attr2 & Attr2ColorMask, offset);
1039 maya 3393 memset(&(AttrBuffFG[TmpPtr]),CurCharAttr.Fore,offset);
1040     memset(&(AttrBuffBG[TmpPtr]),CurCharAttr.Back,offset);
1041     TmpPtr = NextLinePtr(TmpPtr);
1042     }
1043 maya 3227
1044 maya 3393 /* update window */
1045     DispEraseHomeToCur(YHome);
1046 maya 3227 }
1047    
1048     void BuffInsertLines(int Count, int YEnd)
1049     // Insert lines at current position
1050     // Count: number of lines to be inserted
1051     // YEnd: bottom line number of scroll region (screen coordinate)
1052     {
1053 doda 5324 int i, linelen;
1054 doda 5371 int extl=0, extr=0;
1055 maya 3393 LONG SrcPtr, DestPtr;
1056 maya 3227
1057 maya 3393 BuffUpdateScroll();
1058 maya 3227
1059 doda 5371 if (CursorLeftM > 0)
1060     extl = 1;
1061     if (CursorRightM < NumOfColumns-1)
1062     extr = 1;
1063     if (extl || extr)
1064     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
1065    
1066 doda 5324 SrcPtr = GetLinePtr(PageStart+YEnd-Count) + CursorLeftM;
1067     DestPtr = GetLinePtr(PageStart+YEnd) + CursorLeftM;
1068     linelen = CursorRightM - CursorLeftM + 1;
1069 maya 3393 for (i= YEnd-Count ; i>=CursorY ; i--) {
1070 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
1071 doda 8445 #if UNICODE_INTERNAL_BUFF
1072     memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
1073     #endif
1074 doda 5324 memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
1075     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
1076     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
1077     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
1078 maya 3393 SrcPtr = PrevLinePtr(SrcPtr);
1079     DestPtr = PrevLinePtr(DestPtr);
1080     }
1081     for (i = 1 ; i <= Count ; i++) {
1082 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
1083 doda 8445 #if UNICODE_INTERNAL_BUFF
1084     memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
1085     #endif
1086 doda 5324 memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
1087     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
1088     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
1089     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
1090 maya 3393 DestPtr = PrevLinePtr(DestPtr);
1091     }
1092 maya 3227
1093 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || !DispInsertLines(Count, YEnd)) {
1094 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
1095 maya 3393 }
1096 maya 3227 }
1097    
1098     void BuffEraseCharsInLine(int XStart, int Count)
1099     // erase characters in the current line
1100     // XStart: start position of erasing
1101     // Count: number of characters to be erased
1102     {
1103 maya 3393 BOOL LineContinued=FALSE;
1104 doda 3312
1105 maya 3393 if (ts.EnableContinuedLineCopy && XStart == 0 && (AttrLine[0] & AttrLineContinued)) {
1106     LineContinued = TRUE;
1107     }
1108 doda 3312
1109 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1110 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1111     }
1112 maya 3227
1113 maya 3393 NewLine(PageStart+CursorY);
1114     memset(&(CodeLine[XStart]),0x20,Count);
1115 doda 8445 #if UNICODE_INTERNAL_BUFF
1116     memsetW(&(CodeLineW[XStart]),0x20,Count);
1117     #endif
1118 maya 3393 memset(&(AttrLine[XStart]),AttrDefault,Count);
1119 doda 4070 memset(&(AttrLine2[XStart]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
1120 maya 3393 memset(&(AttrLineFG[XStart]),CurCharAttr.Fore,Count);
1121     memset(&(AttrLineBG[XStart]),CurCharAttr.Back,Count);
1122 maya 3227
1123 maya 3393 if (ts.EnableContinuedLineCopy) {
1124     if (LineContinued) {
1125     BuffLineContinued(TRUE);
1126     }
1127    
1128     if (XStart + Count >= NumOfColumns) {
1129     AttrBuff[NextLinePtr(LinePtr)] &= ~AttrLineContinued;
1130     }
1131     }
1132 doda 3312
1133 maya 3393 DispEraseCharsInLine(XStart, Count);
1134 maya 3227 }
1135    
1136     void BuffDeleteLines(int Count, int YEnd)
1137     // Delete lines from current line
1138     // Count: number of lines to be deleted
1139     // YEnd: bottom line number of scroll region (screen coordinate)
1140     {
1141 doda 5324 int i, linelen;
1142 doda 5371 int extl=0, extr=0;
1143 maya 3393 LONG SrcPtr, DestPtr;
1144 maya 3227
1145 maya 3393 BuffUpdateScroll();
1146 maya 3227
1147 doda 5371 if (CursorLeftM > 0)
1148     extl = 1;
1149     if (CursorRightM < NumOfColumns-1)
1150     extr = 1;
1151     if (extl || extr)
1152     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
1153    
1154 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorY+Count) + (LONG)CursorLeftM;
1155     DestPtr = GetLinePtr(PageStart+CursorY) + (LONG)CursorLeftM;
1156     linelen = CursorRightM - CursorLeftM + 1;
1157 maya 3393 for (i=CursorY ; i<= YEnd-Count ; i++) {
1158 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
1159 doda 8445 #if UNICODE_INTERNAL_BUFF
1160     memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
1161     #endif
1162 doda 5324 memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
1163     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
1164     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
1165     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
1166 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
1167     DestPtr = NextLinePtr(DestPtr);
1168     }
1169     for (i = YEnd+1-Count ; i<=YEnd ; i++) {
1170 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
1171 doda 8445 #if UNICODE_INTERNAL_BUFF
1172     memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
1173     #endif
1174 doda 5324 memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
1175     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
1176     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
1177     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
1178 maya 3393 DestPtr = NextLinePtr(DestPtr);
1179     }
1180 maya 3227
1181 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || ! DispDeleteLines(Count,YEnd)) {
1182 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
1183 maya 3393 }
1184 maya 3227 }
1185    
1186     // Delete characters in current line from cursor
1187     // Count: number of characters to be deleted
1188 doda 8445 #if UNICODE_INTERNAL_BUFF
1189     void BuffDeleteChars(int Count)
1190 maya 3227 {
1191 doda 5325 int MoveLen;
1192 doda 8445 int extr = 0;
1193     buff_char_t *b;
1194    
1195     if (Count > CursorRightM + 1 - CursorX)
1196     Count = CursorRightM + 1 - CursorX;
1197    
1198     if (CursorX < CursorLeftM || CursorX > CursorRightM)
1199     return;
1200    
1201     NewLine(PageStart + CursorY);
1202    
1203     b = &CodeLineW[CursorX];
1204    
1205     if (IsBuffPadding(b)) {
1206     // �S�p���E���A�S�p���X�y�[�X���u��������
1207     BuffSetChar(b - 1, ' ', 'H');
1208     BuffSetChar(b, ' ', 'H');
1209     }
1210     if (IsBuffFullWidth(b)) {
1211     // �S�p�������A�S�p���X�y�[�X���u��������
1212     BuffSetChar(b, ' ', 'H');
1213     BuffSetChar(b + 1, ' ', 'H');
1214     }
1215     if (Count > 1) {
1216     // �I�[���`�F�b�N
1217     if (IsBuffPadding(b + Count)) {
1218     // �S�p���E���A�S�p���X�y�[�X���u��������
1219     BuffSetChar(b + Count - 1, ' ', 'H');
1220     BuffSetChar(b + Count, ' ', 'H');
1221     }
1222     }
1223    
1224     if (CursorRightM < NumOfColumns - 1 && (AttrLine[CursorRightM] & AttrKanji)) {
1225     CodeLine[CursorRightM] = 0x20;
1226     BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
1227     AttrLine[CursorRightM] &= ~AttrKanji;
1228     CodeLine[CursorRightM + 1] = 0x20;
1229     BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
1230     AttrLine[CursorRightM + 1] &= ~AttrKanji;
1231     extr = 1;
1232     }
1233    
1234     MoveLen = CursorRightM + 1 - CursorX - Count;
1235    
1236     if (MoveLen > 0) {
1237     memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX + Count]), MoveLen);
1238     memmoveW(&(CodeLineW[CursorX]), &(CodeLineW[CursorX + Count]), MoveLen);
1239     memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX + Count]), MoveLen);
1240     memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX + Count]), MoveLen);
1241     memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX + Count]), MoveLen);
1242     memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX + Count]), MoveLen);
1243     }
1244     memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count);
1245     memsetW(&(CodeLineW[CursorX + MoveLen]), ' ', Count);
1246     memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count);
1247     memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
1248     memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count);
1249     memset(&(AttrLineBG[CursorX + MoveLen]), CurCharAttr.Back, Count);
1250    
1251     BuffUpdateRect(CursorX, CursorY, CursorRightM + extr, CursorY);
1252     }
1253     #else
1254     void BuffDeleteChars(int Count)
1255     {
1256     int MoveLen;
1257 doda 5371 int extr=0;
1258 doda 5325
1259     if (CursorX < CursorLeftM || CursorX > CursorRightM)
1260     return;
1261    
1262 maya 3393 NewLine(PageStart+CursorY);
1263 maya 3227
1264 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1265 maya 3393 EraseKanji(0); /* if cursor is on left harf of a kanji, erase the kanji */
1266     EraseKanji(1); /* if cursor on right half... */
1267     }
1268 maya 3227
1269 doda 5371 if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) {
1270     CodeLine[CursorRightM] = 0x20;
1271     AttrLine[CursorRightM] &= ~AttrKanji;
1272     CodeLine[CursorRightM+1] = 0x20;
1273     AttrLine[CursorRightM+1] &= ~AttrKanji;
1274     extr = 1;
1275     }
1276    
1277 doda 5325 if (Count > CursorRightM + 1 - CursorX)
1278     Count = CursorRightM + 1 - CursorX;
1279    
1280     MoveLen = CursorRightM + 1 - CursorX - Count;
1281    
1282     if (MoveLen > 0) {
1283     memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX+Count]), MoveLen);
1284     memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX+Count]), MoveLen);
1285     memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX+Count]), MoveLen);
1286     memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX+Count]), MoveLen);
1287     memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX+Count]), MoveLen);
1288 maya 3393 }
1289 doda 5325 memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count);
1290     memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count);
1291     memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
1292     memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count);
1293     memset(&(AttrLineBG[CursorX + MoveLen]), CurCharAttr.Back, Count);
1294 maya 3227
1295 doda 5371 BuffUpdateRect(CursorX, CursorY, CursorRightM+extr, CursorY);
1296 maya 3227 }
1297 doda 8445 #endif
1298 maya 3227
1299     // Erase characters in current line from cursor
1300     // Count: number of characters to be deleted
1301 doda 8445 #if UNICODE_INTERNAL_BUFF
1302     void BuffEraseChars(int Count)
1303 maya 3227 {
1304 doda 8445 int extr = 0;
1305     int sx = CursorX;
1306     buff_char_t *b;
1307     NewLine(PageStart + CursorY);
1308    
1309     if (Count > NumOfColumns - CursorX) {
1310     Count = NumOfColumns - CursorX;
1311     }
1312    
1313     b = &CodeLineW[CursorX];
1314     if (IsBuffPadding(b)) {
1315     // �S�p���E���A�S�p���X�y�[�X���u��������
1316     BuffSetChar(b - 1, ' ', 'H');
1317     BuffSetChar(b, ' ', 'H');
1318     sx--;
1319     extr++;
1320     }
1321     if (IsBuffFullWidth(b)) {
1322     // �S�p�������A�S�p���X�y�[�X���u��������
1323     BuffSetChar(b, ' ', 'H');
1324     BuffSetChar(b + 1, ' ', 'H');
1325     if (Count == 1) {
1326     extr++;
1327     }
1328     }
1329     if (Count > 1) {
1330     // �I�[���`�F�b�N
1331     if (IsBuffPadding(b + Count)) {
1332     // �S�p���E���A�S�p���X�y�[�X���u��������
1333     BuffSetChar(b + Count - 1, ' ', 'H');
1334     BuffSetChar(b + Count, ' ', 'H');
1335     extr++;
1336     }
1337     }
1338    
1339     memset(&(CodeLine[CursorX]), 0x20, Count);
1340     #if UNICODE_INTERNAL_BUFF
1341     memsetW(&(CodeLineW[CursorX]), 0x20, Count);
1342     #endif
1343     memset(&(AttrLine[CursorX]), AttrDefault, Count);
1344     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
1345     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
1346     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
1347    
1348     /* update window */
1349     DispEraseCharsInLine(sx, Count + extr);
1350     }
1351     #else
1352     void BuffEraseChars(int Count)
1353     {
1354 maya 3393 NewLine(PageStart+CursorY);
1355 maya 3227
1356 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1357 maya 3393 EraseKanji(0); /* if cursor is on left harf of a kanji, erase the kanji */
1358     EraseKanji(1); /* if cursor on right half... */
1359     }
1360 maya 3227
1361 maya 3393 if (Count > NumOfColumns-CursorX) {
1362     Count = NumOfColumns-CursorX;
1363     }
1364     memset(&(CodeLine[CursorX]),0x20,Count);
1365 doda 8445 #if UNICODE_INTERNAL_BUFF
1366     memsetW(&(CodeLineW[CursorX]),0x20,Count);
1367     #endif
1368 maya 3393 memset(&(AttrLine[CursorX]),AttrDefault,Count);
1369 doda 4070 memset(&(AttrLine2[CursorX]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
1370 maya 3393 memset(&(AttrLineFG[CursorX]),CurCharAttr.Fore,Count);
1371     memset(&(AttrLineBG[CursorX]),CurCharAttr.Back,Count);
1372 maya 3227
1373 maya 3393 /* update window */
1374     DispEraseCharsInLine(CursorX,Count);
1375 maya 3227 }
1376 doda 8445 #endif
1377 maya 3227
1378     void BuffFillWithE()
1379     // Fill screen with 'E' characters
1380     {
1381 maya 3393 LONG TmpPtr;
1382     int i;
1383 maya 3227
1384 maya 3393 TmpPtr = GetLinePtr(PageStart);
1385     for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) {
1386     memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns);
1387 doda 8445 #if UNICODE_INTERNAL_BUFF
1388     memsetW(&(CodeBuffW[TmpPtr]),'E',NumOfColumns);
1389     #endif
1390 maya 3393 memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns);
1391     memset(&(AttrBuff2[TmpPtr]),AttrDefault,NumOfColumns);
1392     memset(&(AttrBuffFG[TmpPtr]),AttrDefaultFG,NumOfColumns);
1393     memset(&(AttrBuffBG[TmpPtr]),AttrDefaultBG,NumOfColumns);
1394     TmpPtr = NextLinePtr(TmpPtr);
1395     }
1396     BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1);
1397 maya 3227 }
1398    
1399     void BuffDrawLine(TCharAttr Attr, int Direction, int C)
1400     { // IO-8256 terminal
1401 maya 3393 LONG Ptr;
1402     int i, X, Y;
1403 maya 3227
1404 maya 3393 if (C==0) {
1405     return;
1406     }
1407     Attr.Attr |= AttrSpecial;
1408 maya 3227
1409 maya 3393 switch (Direction) {
1410     case 3:
1411     case 4:
1412     if (Direction==3) {
1413     if (CursorY==0) {
1414     return;
1415     }
1416     Y = CursorY-1;
1417     }
1418     else {
1419     if (CursorY==NumOfLines-1-StatusLine) {
1420     return;
1421     }
1422     Y = CursorY+1;
1423     }
1424     if (CursorX+C > NumOfColumns) {
1425     C = NumOfColumns-CursorX;
1426     }
1427     Ptr = GetLinePtr(PageStart+Y);
1428     memset(&(CodeBuff[Ptr+CursorX]),'q',C);
1429 doda 8445 #if UNICODE_INTERNAL_BUFF
1430     memsetW(&(CodeBuffW[Ptr+CursorX]),'q',C);
1431     #endif
1432 maya 3393 memset(&(AttrBuff[Ptr+CursorX]),Attr.Attr,C);
1433     memset(&(AttrBuff2[Ptr+CursorX]),Attr.Attr2,C);
1434     memset(&(AttrBuffFG[Ptr+CursorX]),Attr.Fore,C);
1435     memset(&(AttrBuffBG[Ptr+CursorX]),Attr.Back,C);
1436     BuffUpdateRect(CursorX,Y,CursorX+C-1,Y);
1437     break;
1438     case 5:
1439     case 6:
1440     if (Direction==5) {
1441     if (CursorX==0) {
1442     return;
1443     }
1444     X = CursorX - 1;
1445     }
1446     else {
1447     if (CursorX==NumOfColumns-1) {
1448     X = CursorX-1;
1449     }
1450     else {
1451     X = CursorX+1;
1452     }
1453     }
1454     Ptr = GetLinePtr(PageStart+CursorY);
1455     if (CursorY+C > NumOfLines-StatusLine) {
1456     C = NumOfLines-StatusLine-CursorY;
1457     }
1458     for (i=1; i<=C; i++) {
1459     CodeBuff[Ptr+X] = 'x';
1460 doda 8445 #if UNICODE_INTERNAL_BUFF
1461     BuffSetChar(&CodeBuffW[Ptr+X], 0x20, 'H');
1462     #endif
1463 maya 3393 AttrBuff[Ptr+X] = Attr.Attr;
1464     AttrBuff2[Ptr+X] = Attr.Attr2;
1465     AttrBuffFG[Ptr+X] = Attr.Fore;
1466     AttrBuffBG[Ptr+X] = Attr.Back;
1467     Ptr = NextLinePtr(Ptr);
1468     }
1469     BuffUpdateRect(X,CursorY,X,CursorY+C-1);
1470     break;
1471     }
1472 maya 3227 }
1473    
1474     void BuffEraseBox
1475     (int XStart, int YStart, int XEnd, int YEnd)
1476     {
1477 maya 3393 int C, i;
1478     LONG Ptr;
1479 maya 3227
1480 maya 3393 if (XEnd>NumOfColumns-1) {
1481     XEnd = NumOfColumns-1;
1482     }
1483     if (YEnd>NumOfLines-1-StatusLine) {
1484     YEnd = NumOfLines-1-StatusLine;
1485     }
1486     if (XStart>XEnd) {
1487     return;
1488     }
1489     if (YStart>YEnd) {
1490     return;
1491     }
1492     C = XEnd-XStart+1;
1493     Ptr = GetLinePtr(PageStart+YStart);
1494     for (i=YStart; i<=YEnd; i++) {
1495     if ((XStart>0) &&
1496     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
1497     CodeBuff[Ptr+XStart-1] = 0x20;
1498 doda 8445 #if UNICODE_INTERNAL_BUFF
1499     BuffSetChar(&CodeBuffW[Ptr+XStart-1], 0x20, 'H');
1500     #endif
1501 maya 3393 AttrBuff[Ptr+XStart-1] = CurCharAttr.Attr;
1502     AttrBuff2[Ptr+XStart-1] = CurCharAttr.Attr2;
1503     AttrBuffFG[Ptr+XStart-1] = CurCharAttr.Fore;
1504     AttrBuffBG[Ptr+XStart-1] = CurCharAttr.Back;
1505     }
1506     if ((XStart+C<NumOfColumns) &&
1507     ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0)) {
1508     CodeBuff[Ptr+XStart+C] = 0x20;
1509 doda 8445 #if UNICODE_INTERNAL_BUFF
1510     BuffSetChar(&CodeBuffW[Ptr+XStart+C], 0x20, 'H');
1511     #endif
1512 maya 3393 AttrBuff[Ptr+XStart+C] = CurCharAttr.Attr;
1513     AttrBuff2[Ptr+XStart+C] = CurCharAttr.Attr2;
1514     AttrBuffFG[Ptr+XStart+C] = CurCharAttr.Fore;
1515     AttrBuffBG[Ptr+XStart+C] = CurCharAttr.Back;
1516     }
1517     memset(&(CodeBuff[Ptr+XStart]),0x20,C);
1518 doda 8445 #if UNICODE_INTERNAL_BUFF
1519     memsetW(&(CodeBuffW[Ptr+XStart]),0x20,C);
1520     #endif
1521 maya 3393 memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C);
1522 doda 4070 memset(&(AttrBuff2[Ptr+XStart]),CurCharAttr.Attr2 & Attr2ColorMask, C);
1523 maya 3393 memset(&(AttrBuffFG[Ptr+XStart]),CurCharAttr.Fore,C);
1524     memset(&(AttrBuffBG[Ptr+XStart]),CurCharAttr.Back,C);
1525     Ptr = NextLinePtr(Ptr);
1526     }
1527     BuffUpdateRect(XStart,YStart,XEnd,YEnd);
1528 maya 3227 }
1529    
1530 doda 5090 void BuffFillBox(char ch, int XStart, int YStart, int XEnd, int YEnd)
1531     {
1532     int Cols, i;
1533     LONG Ptr;
1534    
1535     if (XEnd>NumOfColumns-1) {
1536     XEnd = NumOfColumns-1;
1537     }
1538     if (YEnd>NumOfLines-1-StatusLine) {
1539     YEnd = NumOfLines-1-StatusLine;
1540     }
1541     if (XStart>XEnd) {
1542     return;
1543     }
1544     if (YStart>YEnd) {
1545     return;
1546     }
1547     Cols = XEnd-XStart+1;
1548     Ptr = GetLinePtr(PageStart+YStart);
1549     for (i=YStart; i<=YEnd; i++) {
1550     if ((XStart>0) &&
1551     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
1552     CodeBuff[Ptr+XStart-1] = 0x20;
1553 doda 8445 #if UNICODE_INTERNAL_BUFF
1554     BuffSetChar(&CodeLineW[Ptr + XStart - 1], 0x20, 'H');
1555     #endif
1556 doda 5090 AttrBuff[Ptr+XStart-1] ^= AttrKanji;
1557     }
1558     if ((XStart+Cols<NumOfColumns) &&
1559     ((AttrBuff[Ptr+XStart+Cols-1] & AttrKanji) != 0)) {
1560     CodeBuff[Ptr+XStart+Cols] = 0x20;
1561 doda 8445 #if UNICODE_INTERNAL_BUFF
1562     BuffSetChar(&CodeLineW[Ptr + XStart + Cols], 0x20, 'H');
1563     #endif
1564 doda 5090 }
1565     memset(&(CodeBuff[Ptr+XStart]), ch, Cols);
1566 doda 8445 #if UNICODE_INTERNAL_BUFF
1567     BuffSetChar(&CodeLineW[Ptr + XStart], 0x20, 'H');
1568     #endif
1569 doda 5090 memset(&(AttrBuff[Ptr+XStart]), CurCharAttr.Attr, Cols);
1570 doda 5092 memset(&(AttrBuff2[Ptr+XStart]), CurCharAttr.Attr2, Cols);
1571 doda 5090 memset(&(AttrBuffFG[Ptr+XStart]), CurCharAttr.Fore, Cols);
1572     memset(&(AttrBuffBG[Ptr+XStart]), CurCharAttr.Back, Cols);
1573     Ptr = NextLinePtr(Ptr);
1574     }
1575     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1576     }
1577    
1578 doda 6174 //
1579     // TODO: 1 origin �������������� 0 origin ������
1580     //
1581 doda 5089 void BuffCopyBox(
1582     int SrcXStart, int SrcYStart, int SrcXEnd, int SrcYEnd, int SrcPage,
1583     int DstX, int DstY, int DstPage)
1584     {
1585     int i, C, L;
1586     LONG SPtr, DPtr;
1587    
1588     SrcXStart--;
1589     SrcYStart--;
1590     SrcXEnd--;
1591     SrcYEnd--;
1592     SrcPage--;
1593     DstX--;
1594     DstY--;
1595     DstPage--;
1596    
1597     if (SrcXEnd > NumOfColumns - 1) {
1598     SrcXEnd = NumOfColumns-1;
1599     }
1600     if (SrcYEnd > NumOfLines-1-StatusLine) {
1601     SrcYEnd = NumOfColumns-1;
1602     }
1603     if (SrcXStart > SrcXEnd ||
1604     SrcYStart > SrcYEnd ||
1605     DstX > NumOfColumns-1 ||
1606     DstY > NumOfLines-1-StatusLine) {
1607     return;
1608     }
1609    
1610     C = SrcXEnd - SrcXStart + 1;
1611     if (DstX + C > NumOfColumns) {
1612     C = NumOfColumns - DstX;
1613     }
1614     L = SrcYEnd - SrcYStart + 1;
1615     if (DstY + C > NumOfColumns) {
1616     C = NumOfColumns - DstX;
1617     }
1618    
1619     if (SrcXStart > DstX) {
1620     SPtr = GetLinePtr(PageStart+SrcYStart);
1621     DPtr = GetLinePtr(PageStart+DstY);
1622     for (i=0; i<L; i++) {
1623     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1624 doda 8445 #if UNICODE_INTERNAL_BUFF
1625     memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1626     #endif
1627 doda 5089 memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1628     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1629     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1630     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1631     SPtr = NextLinePtr(SPtr);
1632     DPtr = NextLinePtr(DPtr);
1633     }
1634     }
1635     else if (SrcXStart < DstX) {
1636     SPtr = GetLinePtr(PageStart+SrcYEnd);
1637     DPtr = GetLinePtr(PageStart+DstY+L-1);
1638     for (i=L; i>0; i--) {
1639     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1640 doda 8445 #if UNICODE_INTERNAL_BUFF
1641     memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1642     #endif
1643 doda 5089 memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1644     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1645     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1646     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1647     SPtr = PrevLinePtr(SPtr);
1648     DPtr = PrevLinePtr(DPtr);
1649     }
1650     }
1651     else if (SrcYStart != DstY) {
1652     SPtr = GetLinePtr(PageStart+SrcYStart);
1653     DPtr = GetLinePtr(PageStart+DstY);
1654     for (i=0; i<L; i++) {
1655     memmove(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1656 doda 8445 #if UNICODE_INTERNAL_BUFF
1657     memmoveW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1658     #endif
1659 doda 5089 memmove(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1660     memmove(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1661     memmove(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1662     memmove(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1663     SPtr = NextLinePtr(SPtr);
1664     DPtr = NextLinePtr(DPtr);
1665     }
1666     }
1667     BuffUpdateRect(DstX,DstY,DstX+C-1,DstY+L-1);
1668     }
1669    
1670 doda 5095 void BuffChangeAttrBox(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1671     {
1672     int C, i, j;
1673     LONG Ptr;
1674    
1675     if (XEnd>NumOfColumns-1) {
1676     XEnd = NumOfColumns-1;
1677     }
1678     if (YEnd>NumOfLines-1-StatusLine) {
1679     YEnd = NumOfLines-1-StatusLine;
1680     }
1681     if (XStart>XEnd || YStart>YEnd) {
1682     return;
1683     }
1684     C = XEnd-XStart+1;
1685     Ptr = GetLinePtr(PageStart+YStart);
1686    
1687     if (mask) { // DECCARA
1688     for (i=YStart; i<=YEnd; i++) {
1689     j = Ptr+XStart-1;
1690     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1691     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1692 doda 7085 AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1693 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[j] = attr->Fore; }
1694     if (mask->Attr2 & Attr2Back) { AttrBuffBG[j] = attr->Back; }
1695 doda 5095 }
1696 doda 7083 while (++j < Ptr+XStart+C) {
1697 doda 5095 AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1698     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1699 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[j] = attr->Fore; }
1700     if (mask->Attr2 & Attr2Back) { AttrBuffBG[j] = attr->Back; }
1701 doda 5095 }
1702     if (XStart+C<NumOfColumns && (AttrBuff[j-1] & AttrKanji)) {
1703     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1704     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1705 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[j] = attr->Fore; }
1706     if (mask->Attr2 & Attr2Back) { AttrBuffBG[j] = attr->Back; }
1707 doda 5095 }
1708     Ptr = NextLinePtr(Ptr);
1709     }
1710     }
1711     else { // DECRARA
1712     for (i=YStart; i<=YEnd; i++) {
1713     j = Ptr+XStart-1;
1714     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1715 doda 7083 AttrBuff[j] ^= attr->Attr;
1716 doda 5095 }
1717 doda 7083 while (++j < Ptr+XStart+C) {
1718     AttrBuff[j] ^= attr->Attr;
1719 doda 5095 }
1720     if (XStart+C<NumOfColumns && (AttrBuff[j-1] & AttrKanji)) {
1721     AttrBuff[j] ^= attr->Attr;
1722     }
1723     Ptr = NextLinePtr(Ptr);
1724     }
1725     }
1726     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1727     }
1728    
1729 doda 7086 void BuffChangeAttrStream(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1730     {
1731     int i, j, endp;
1732     LONG Ptr;
1733    
1734     if (XEnd>NumOfColumns-1) {
1735     XEnd = NumOfColumns-1;
1736     }
1737     if (YEnd>NumOfLines-1-StatusLine) {
1738     YEnd = NumOfLines-1-StatusLine;
1739     }
1740     if (XStart>XEnd || YStart>YEnd) {
1741     return;
1742     }
1743    
1744     Ptr = GetLinePtr(PageStart+YStart);
1745    
1746     if (mask) { // DECCARA
1747     if (YStart == YEnd) {
1748     i = Ptr + XStart - 1;
1749     endp = Ptr + XEnd + 1;
1750    
1751     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1752     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1753     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1754 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1755     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1756 doda 7086 }
1757     while (++i < endp) {
1758     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1759     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1760 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1761     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1762 doda 7086 }
1763     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1764     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1765     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1766 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1767     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1768 doda 7086 }
1769     }
1770     else {
1771     i = Ptr + XStart - 1;
1772     endp = Ptr + NumOfColumns;
1773    
1774     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1775     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1776     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1777 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1778     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1779 doda 7086 }
1780     while (++i < endp) {
1781     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1782     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1783 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1784     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1785 doda 7086 }
1786    
1787     for (j=0; j < YEnd-YStart-1; j++) {
1788     Ptr = NextLinePtr(Ptr);
1789     i = Ptr;
1790     endp = Ptr + NumOfColumns;
1791    
1792     while (i < endp) {
1793     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1794     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1795 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1796     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1797 doda 7086 i++;
1798     }
1799     }
1800    
1801     Ptr = NextLinePtr(Ptr);
1802     i = Ptr;
1803     endp = Ptr + XEnd + 1;
1804    
1805     while (i < endp) {
1806     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1807     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1808 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1809     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1810 doda 7086 i++;
1811     }
1812     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1813     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1814     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1815 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1816     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1817 doda 7086 }
1818     }
1819     }
1820     else { // DECRARA
1821     if (YStart == YEnd) {
1822     i = Ptr + XStart - 1;
1823     endp = Ptr + XEnd + 1;
1824    
1825     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1826     AttrBuff[i] ^= attr->Attr;
1827     }
1828     while (++i < endp) {
1829     AttrBuff[i] ^= attr->Attr;
1830     }
1831     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1832     AttrBuff[i] ^= attr->Attr;
1833     }
1834     }
1835     else {
1836     i = Ptr + XStart - 1;
1837     endp = Ptr + NumOfColumns;
1838    
1839     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1840     AttrBuff[i] ^= attr->Attr;
1841     }
1842     while (++i < endp) {
1843     AttrBuff[i] ^= attr->Attr;
1844     }
1845    
1846     for (j=0; j < YEnd-YStart-1; j++) {
1847     Ptr = NextLinePtr(Ptr);
1848     i = Ptr;
1849     endp = Ptr + NumOfColumns;
1850    
1851     while (i < endp) {
1852     AttrBuff[i] ^= attr->Attr;
1853     i++;
1854     }
1855     }
1856    
1857     Ptr = NextLinePtr(Ptr);
1858     i = Ptr;
1859     endp = Ptr + XEnd + 1;
1860    
1861     while (i < endp) {
1862     AttrBuff[i] ^= attr->Attr;
1863     i++;
1864     }
1865     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1866     AttrBuff[i] ^= attr->Attr;
1867     }
1868     Ptr = NextLinePtr(Ptr);
1869     }
1870     }
1871     BuffUpdateRect(0, YStart, NumOfColumns-1, YEnd);
1872     }
1873    
1874 doda 8445 static int LeftHalfOfDBCS(LONG Line, int CharPtr)
1875 maya 3227 // If CharPtr is on the right half of a DBCS character,
1876     // return pointer to the left half
1877     // Line: points to a line in CodeBuff
1878     // CharPtr: points to a char
1879     // return: points to the left half of the DBCS
1880     {
1881 maya 3393 if ((CharPtr>0) &&
1882     ((AttrBuff[Line+CharPtr-1] & AttrKanji) != 0)) {
1883     CharPtr--;
1884     }
1885     return CharPtr;
1886 maya 3227 }
1887    
1888 doda 8445 static int MoveCharPtr(LONG Line, int *x, int dx)
1889 maya 3227 // move character pointer x by dx character unit
1890     // in the line specified by Line
1891     // Line: points to a line in CodeBuff
1892     // x: points to a character in the line
1893     // dx: moving distance in character unit (-: left, +: right)
1894 maya 3393 // One DBCS character is counted as one character.
1895 maya 3227 // The pointer stops at the beginning or the end of line.
1896     // Output
1897     // x: new pointer. x points to a SBCS character or
1898     // the left half of a DBCS character.
1899     // return: actual moving distance in character unit
1900     {
1901 maya 3393 int i;
1902 maya 3227
1903 maya 3393 *x = LeftHalfOfDBCS(Line,*x);
1904     i = 0;
1905     while (dx!=0) {
1906     if (dx>0) { // move right
1907     if ((AttrBuff[Line+*x] & AttrKanji) != 0) {
1908     if (*x<NumOfColumns-2) {
1909     i++;
1910     *x = *x + 2;
1911     }
1912     }
1913     else if (*x<NumOfColumns-1) {
1914     i++;
1915     (*x)++;
1916     }
1917     dx--;
1918     }
1919     else { // move left
1920     if (*x>0) {
1921     i--;
1922     (*x)--;
1923     }
1924     *x = LeftHalfOfDBCS(Line,*x);
1925     dx++;
1926     }
1927 maya 3227 }
1928 maya 3393 return i;
1929 maya 3227 }
1930    
1931 doda 8445 /**
1932     * (�N���b�v�{�[�h�p��)������������
1933     * @param[in] sx,sy,ex,ey �I������
1934     * @param[in] box_select TRUE=���^(���`)�I��
1935     * FALSE=�s�I��
1936     * @param[out] _str_len ��������(�����[L'\0'������)
1937     * NULL����������������
1938     * @return ������
1939     * �g�p���� free() ��������
1940     */
1941     #if UNICODE_INTERNAL_BUFF
1942     static wchar_t *BuffGetStringForCB(int sx, int sy, int ex, int ey, BOOL box_select, size_t *_str_len)
1943     {
1944     wchar_t *str_w;
1945     size_t str_size; // �m�������T�C�Y
1946     size_t k;
1947     LONG TmpPtr;
1948     int IStart, IEnd;
1949     int x, y;
1950     BOOL LineContinued;
1951    
1952     str_size = NumOfColumns * (ey - sy + 1);
1953     str_w = malloc(sizeof(wchar_t) * str_size);
1954    
1955     LockBuffer();
1956    
1957     str_w[0] = 0;
1958     TmpPtr = GetLinePtr(sy);
1959     k = 0;
1960     for (y = sy; y<=ey ; y++) {
1961     if (box_select) {
1962     IStart = SelectStart.x;
1963     IEnd = SelectEnd.x-1;
1964     }
1965     else {
1966     IStart = 0;
1967     IEnd = NumOfColumns-1;
1968     if (y== sy) {
1969     IStart = sx;
1970     }
1971     if (y== ey) {
1972     IEnd = ex -1;
1973     }
1974     }
1975    
1976     // �����s����������?
1977     LineContinued = FALSE;
1978     if (!box_select) {
1979     // �s�I������������
1980     if (ts.EnableContinuedLineCopy && y!= ey ) {
1981     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1982     if ((AttrBuff[NextTmpPtr] & AttrLineContinued) != 0) {
1983     LineContinued = TRUE;
1984     }
1985     }
1986     }
1987    
1988     if (!LineContinued) {
1989     while ((IEnd>0)) {
1990     // �R�s�[�s�v��������
1991     const buff_char_t *b = &CodeBuffW[TmpPtr + IEnd];
1992     if (b->u32 == 0x20) {
1993     MoveCharPtr(TmpPtr,&IEnd,-1); // �����l����
1994     }
1995     else {
1996     break;
1997     }
1998     }
1999     }
2000    
2001     x = IStart;
2002     while (x <= IEnd) {
2003     const buff_char_t *b = &CodeBuffW[TmpPtr + x];
2004     if (b->u32 != 0) {
2005     str_w[k++] = b->wc2[0];
2006     if (b->wc2[1] != 0) {
2007     str_w[k++] = b->wc2[1];
2008     }
2009     if (k + 2 >= str_size) {
2010     str_size *= 2;
2011     str_w = realloc(str_w, sizeof(wchar_t) * str_size);
2012     }
2013     {
2014     int i;
2015     // �R���r�l�[�V����
2016     if (k + b->CombinationCharCount16 >= str_size) {
2017     str_size += + b->CombinationCharCount16;
2018     str_w = realloc(str_w, sizeof(wchar_t) * str_size);
2019     }
2020     for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
2021     str_w[k++] = b->pCombinationChars16[i];
2022     }
2023     }
2024     }
2025     x++;
2026     }
2027    
2028     if (y < ey) {
2029     // ���s��������(�������s���O������)
2030     if (!LineContinued) {
2031     str_w[k++] = 0x0d;
2032     str_w[k++] = 0x0a;
2033     }
2034     }
2035    
2036     TmpPtr = NextLinePtr(TmpPtr);
2037     }
2038     str_w[k++] = 0;
2039    
2040     UnlockBuffer();
2041    
2042     if (_str_len != NULL) {
2043     *_str_len = k;
2044     }
2045     return str_w;
2046     }
2047     #endif
2048    
2049     /**
2050     * (x,y) ��1������ str��������������
2051     * *�� 1������������wchar_t�����\������������
2052     *
2053     * @param y PageStart + CursorY
2054     * @param str 1����(wchar_t��)
2055     * @param len ��������
2056     * @retval 0=�}�b�`����������
2057     * �}�b�`������������
2058     */
2059     #if UNICODE_INTERNAL_BUFF
2060     static size_t MatchOneString(int x, int y, const wchar_t *str, size_t len)
2061     {
2062     int match_pos = 0;
2063     int TmpPtr = GetLinePtr(y);
2064     const buff_char_t *b = &CodeBuffW[TmpPtr + x];
2065     if (b->wc2[1] == 0) {
2066     // �T���Q�[�g�y�A��������
2067     if (str[match_pos] != b->wc2[0]) {
2068     return 0;
2069     }
2070     match_pos++;
2071     len--;
2072     } else {
2073     // �T���Q�[�g�y�A
2074     if (len < 2) {
2075     return 0;
2076     }
2077     if (str[match_pos+0] != b->wc2[0] ||
2078     str[match_pos+1] != b->wc2[1]) {
2079     return 0;
2080     }
2081     match_pos+=2;
2082     len-=2;
2083     }
2084     if (b->CombinationCharCount16 > 0) {
2085     // �R���r�l�[�V����
2086     int i;
2087     if (len < b->CombinationCharCount16) {
2088     return 0;
2089     }
2090     for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
2091     if (str[match_pos++] != b->pCombinationChars16[i]) {
2092     return 0;
2093     }
2094     }
2095     len -= b->CombinationCharCount16;
2096     }
2097     return match_pos;
2098     }
2099     #endif
2100    
2101     /**
2102     * (x,y)���� str��������������
2103     *
2104     * @param x �}�C�i�X�����A�����s������������
2105     * @param y PageStart + CursorY
2106     * @param LineCntinued TRUE=�s���p�����l������
2107     * @retval TRUE �}�b�`����
2108     * @retval FALSE �}�b�`����������
2109     */
2110     #if UNICODE_INTERNAL_BUFF
2111     static BOOL MatchString(int x, int y, const wchar_t *str, BOOL LineContinued)
2112     {
2113     BOOL result;
2114     int TmpPtr = GetLinePtr(y);
2115     size_t len = wcslen(str);
2116     if (len == 0) {
2117     return FALSE;
2118     }
2119     while(x < 0) {
2120     if (LineContinued && (AttrBuff[TmpPtr+0] & AttrLineContinued) == 0) {
2121     // �s���p�������������l�� & �p������������
2122     x = 0; // �s������������
2123     break;
2124     }
2125     TmpPtr = PrevLinePtr(TmpPtr);
2126     x += NumOfColumns;
2127     y--;
2128     }
2129     while(x > NumOfColumns) {
2130     if (LineContinued && (AttrBuff[TmpPtr+NumOfColumns-1] & AttrLineContinued) == 0) {
2131     // �s���p�������������l�� & �p������������
2132     x = 0; // �s������������
2133     break;
2134     }
2135     TmpPtr = NextLinePtr(TmpPtr);
2136     x -= NumOfColumns;
2137     }
2138    
2139     for(;;) {
2140     // 1����������������
2141     size_t match_len = MatchOneString(x, y, str, len);
2142     if (match_len == 0) {
2143     result = FALSE;
2144     break;
2145     }
2146     len -= match_len;
2147     if (len == 0) {
2148     // �S���������I������
2149     result = TRUE;
2150     break;
2151     }
2152     str += match_len;
2153    
2154     // ��������
2155     x++;
2156     if (x == NumOfColumns) {
2157     if (LineContinued && (AttrBuff[TmpPtr+NumOfColumns-1] & AttrLineContinued) != 0) {
2158     // �����s��
2159     x = 0;
2160     TmpPtr = NextLinePtr(TmpPtr);
2161     y++;
2162     } else {
2163     // �s��
2164     result = FALSE;
2165     break;
2166     }
2167     }
2168     }
2169    
2170     return result;
2171     }
2172     #endif
2173    
2174     /**
2175     * (sx,sy)����(ex,ey)������ str ���}�b�`�����������T����
2176     * ���u������
2177     *
2178     * @param sy,ex PageStart + CursorY
2179     * @param[out] x �}�b�`�������u
2180     * @param[out] y �}�b�`�������u
2181     * @retval TRUE �}�b�`����
2182     */
2183     #if UNICODE_INTERNAL_BUFF
2184     static BOOL BuffGetMatchPosFromString(
2185     int sx, int sy, int ex, int ey, const wchar_t *str,
2186     int *match_x, int *match_y)
2187     {
2188     int IStart, IEnd;
2189     int x, y;
2190