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