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