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 8745 - (hide annotations) (download) (as text)
Sun Apr 26 14:34:49 2020 UTC (3 years, 11 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 162524 byte(s)
ANSI文字の処理を修正

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