Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 8739 - (hide annotations) (download) (as text)
Sun Apr 26 14:33:45 2020 UTC (3 years, 11 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 166149 byte(s)
現在行を示すグローバル変数を削除

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