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 10331 - (hide annotations) (download) (as text)
Sun Oct 23 15:15:59 2022 UTC (17 months, 2 weeks ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 137882 byte(s)
unicode_test.h への依存を減らした

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