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 8744 - (hide annotations) (download) (as text)
Sun Apr 26 14:34:39 2020 UTC (3 years, 11 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 161473 byte(s)
CodeBuff 削除

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