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 8400 - (hide annotations) (download) (as text)
Fri Nov 22 15:25:44 2019 UTC (4 years, 4 months ago) by doda
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 105768 byte(s)
マウスでのドラッグを行った時間が短い場合にドラッグとみなさないようにした。

Ticket: #39591

問題:
  ウィンドウをアクティブにする為に VT ウィンドウをクリックした時、マウスが
  少し動いた事でドラッグした事になり選択内容が消える事が有る。

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