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