Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10760 - (hide annotations) (download) (as text)
Mon Jun 12 15:20:40 2023 UTC (9 months, 4 weeks ago) by zmatsuo
File MIME type: text/x-csrc
File size: 138766 byte(s)
各モジュール間APIをUnicode版のみを使用するようにした

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