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 10323 - (hide annotations) (download) (as text)
Mon Oct 17 15:19:33 2022 UTC (17 months, 3 weeks ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 137443 byte(s)
文字のセル数が増加したとき、描画されない場合があったので修正

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