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 7083 - (hide annotations) (download) (as text)
Thu Mar 29 14:58:16 2018 UTC (6 years ago) by doda
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 100651 byte(s)
DECCARA / DECRARA の対象領域が間違っているのを修正 #38168

対象領域の先頭が漢字の 2 バイト目だった(正確には前の文字が
漢字の 1 バイト目だった)時に 1 バイト目も対象領域に含めるよう
処理を行っていたが、対象領域を広げる必要が無い時にカウンタを
進め忘れていた為、常に一つ前のセルも対象領域に含めてしまっていた。
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     static int StrChangeStart, StrChangeCount;
92    
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     AttrBuff[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1208     AttrBuffFG[j] = attr->Fore;
1209     AttrBuffBG[j] = attr->Back;
1210     }
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     AttrBuffFG[j] = attr->Fore;
1215     AttrBuffBG[j] = attr->Back;
1216     }
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     AttrBuffFG[j] = attr->Fore;
1221     AttrBuffBG[j] = attr->Back;
1222     }
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 maya 3227 int LeftHalfOfDBCS(LONG Line, int CharPtr)
1245     // If CharPtr is on the right half of a DBCS character,
1246     // return pointer to the left half
1247     // Line: points to a line in CodeBuff
1248     // CharPtr: points to a char
1249     // return: points to the left half of the DBCS
1250     {
1251 maya 3393 if ((CharPtr>0) &&
1252     ((AttrBuff[Line+CharPtr-1] & AttrKanji) != 0)) {
1253     CharPtr--;
1254     }
1255     return CharPtr;
1256 maya 3227 }
1257    
1258     int MoveCharPtr(LONG Line, int *x, int dx)
1259     // move character pointer x by dx character unit
1260     // in the line specified by Line
1261     // Line: points to a line in CodeBuff
1262     // x: points to a character in the line
1263     // dx: moving distance in character unit (-: left, +: right)
1264 maya 3393 // One DBCS character is counted as one character.
1265 maya 3227 // The pointer stops at the beginning or the end of line.
1266     // Output
1267     // x: new pointer. x points to a SBCS character or
1268     // the left half of a DBCS character.
1269     // return: actual moving distance in character unit
1270     {
1271 maya 3393 int i;
1272 maya 3227
1273 maya 3393 *x = LeftHalfOfDBCS(Line,*x);
1274     i = 0;
1275     while (dx!=0) {
1276     if (dx>0) { // move right
1277     if ((AttrBuff[Line+*x] & AttrKanji) != 0) {
1278     if (*x<NumOfColumns-2) {
1279     i++;
1280     *x = *x + 2;
1281     }
1282     }
1283     else if (*x<NumOfColumns-1) {
1284     i++;
1285     (*x)++;
1286     }
1287     dx--;
1288     }
1289     else { // move left
1290     if (*x>0) {
1291     i--;
1292     (*x)--;
1293     }
1294     *x = LeftHalfOfDBCS(Line,*x);
1295     dx++;
1296     }
1297 maya 3227 }
1298 maya 3393 return i;
1299 maya 3227 }
1300    
1301     void BuffCBCopy(BOOL Table)
1302     // copy selected text to clipboard
1303     {
1304 maya 3393 LONG MemSize;
1305     PCHAR CBPtr;
1306     LONG TmpPtr;
1307     int i, j, k, IStart, IEnd;
1308     BOOL Sp, FirstChar;
1309     BYTE b;
1310     BOOL LineContinued, PrevLineContinued;
1311 doda 6803
1312 maya 3393 LineContinued = FALSE;
1313 maya 3227
1314 maya 3393 if (TalkStatus==IdTalkCB) {
1315     return;
1316     }
1317     if (! Selected) {
1318     return;
1319     }
1320 maya 3227
1321     // --- open clipboard and get CB memory
1322 maya 3393 if (BoxSelect) {
1323     MemSize = (SelectEnd.x-SelectStart.x+3)*
1324     (SelectEnd.y-SelectStart.y+1) + 1;
1325     }
1326     else {
1327     MemSize = (SelectEnd.y-SelectStart.y)*
1328     (NumOfColumns+2) +
1329     SelectEnd.x - SelectStart.x + 1;
1330     }
1331     CBPtr = CBOpen(MemSize);
1332     if (CBPtr==NULL) {
1333     return;
1334     }
1335 maya 3227
1336     // --- copy selected text to CB memory
1337 maya 3393 LockBuffer();
1338 maya 3227
1339 maya 3393 CBPtr[0] = 0;
1340     TmpPtr = GetLinePtr(SelectStart.y);
1341     k = 0;
1342     for (j = SelectStart.y ; j<=SelectEnd.y ; j++) {
1343     if (BoxSelect) {
1344     IStart = SelectStart.x;
1345     IEnd = SelectEnd.x-1;
1346     }
1347     else {
1348     IStart = 0;
1349     IEnd = NumOfColumns-1;
1350     if (j==SelectStart.y) {
1351     IStart = SelectStart.x;
1352     }
1353     if (j==SelectEnd.y) {
1354     IEnd = SelectEnd.x-1;
1355     }
1356     }
1357     i = LeftHalfOfDBCS(TmpPtr,IStart);
1358     if (i!=IStart) {
1359     if (j==SelectStart.y) {
1360     IStart = i;
1361     }
1362     else {
1363     IStart = i + 2;
1364     }
1365     }
1366 maya 3227
1367 maya 3393 // exclude right-side space characters
1368     IEnd = LeftHalfOfDBCS(TmpPtr,IEnd);
1369     PrevLineContinued = LineContinued;
1370     LineContinued = FALSE;
1371     if (ts.EnableContinuedLineCopy && j!=SelectEnd.y && !BoxSelect) {
1372     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1373     if ((AttrBuff[NextTmpPtr] & AttrLineContinued) != 0) {
1374     LineContinued = TRUE;
1375     }
1376     if (IEnd == NumOfColumns-1 &&
1377     (AttrBuff[TmpPtr + IEnd] & AttrLineContinued) != 0) {
1378     MoveCharPtr(TmpPtr,&IEnd,-1);
1379     }
1380     }
1381     if (!LineContinued)
1382     while ((IEnd>0) && (CodeBuff[TmpPtr+IEnd]==0x20)) {
1383     MoveCharPtr(TmpPtr,&IEnd,-1);
1384     }
1385     if ((IEnd==0) && (CodeBuff[TmpPtr]==0x20)) {
1386     IEnd = -1;
1387     }
1388     else if ((AttrBuff[TmpPtr+IEnd] & AttrKanji) != 0) { /* DBCS first byte? */
1389     IEnd++;
1390     }
1391 maya 3227
1392 maya 3393 Sp = FALSE;
1393     FirstChar = TRUE;
1394     i = IStart;
1395     while (i <= IEnd) {
1396     b = CodeBuff[TmpPtr+i];
1397     i++;
1398     if (! Sp) {
1399     if ((Table) && (b<=0x20)) {
1400     Sp = TRUE;
1401     b = 0x09;
1402     }
1403     if ((b!=0x09) || (! FirstChar) || PrevLineContinued) {
1404     FirstChar = FALSE;
1405     CBPtr[k] = b;
1406     k++;
1407     }
1408     }
1409     else {
1410     if (b>0x20) {
1411     Sp = FALSE;
1412     FirstChar = FALSE;
1413     CBPtr[k] = b;
1414     k++;
1415     }
1416     }
1417     }
1418 maya 3227
1419 maya 3393 if (!LineContinued)
1420     if (j < SelectEnd.y) {
1421     CBPtr[k] = 0x0d;
1422     k++;
1423     CBPtr[k] = 0x0a;
1424     k++;
1425     }
1426 maya 3227
1427 maya 3393 TmpPtr = NextLinePtr(TmpPtr);
1428     }
1429     CBPtr[k] = 0;
1430     LineContinued = FALSE;
1431     if (ts.EnableContinuedLineCopy && j!=SelectEnd.y && !BoxSelect && j<BuffEnd-1) {
1432     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1433     if ((AttrBuff[NextTmpPtr] & AttrLineContinued) != 0) {
1434     LineContinued = TRUE;
1435     }
1436     if (IEnd == NumOfColumns-1 &&
1437     (AttrBuff[TmpPtr + IEnd] & AttrLineContinued) != 0) {
1438     MoveCharPtr(TmpPtr,&IEnd,-1);
1439     }
1440     }
1441     if (!LineContinued)
1442     UnlockBuffer();
1443 maya 3227
1444     // --- send CB memory to clipboard
1445 maya 3393 CBClose();
1446     return;
1447 maya 3227 }
1448    
1449     void BuffPrint(BOOL ScrollRegion)
1450     // Print screen or selected text
1451     {
1452 maya 3393 int Id;
1453     POINT PrintStart, PrintEnd;
1454     TCharAttr CurAttr, TempAttr;
1455     int i, j, count;
1456     int IStart, IEnd;
1457     LONG TmpPtr;
1458 maya 3227
1459 maya 3393 TempAttr = DefCharAttr;
1460 maya 3227
1461 maya 3393 if (ScrollRegion) {
1462     Id = VTPrintInit(IdPrnScrollRegion);
1463     }
1464     else if (Selected) {
1465     Id = VTPrintInit(IdPrnScreen | IdPrnSelectedText);
1466     }
1467     else {
1468     Id = VTPrintInit(IdPrnScreen);
1469     }
1470     if (Id==IdPrnCancel) {
1471     return;
1472     }
1473 maya 3227
1474 maya 3393 /* set print region */
1475     if (Id==IdPrnSelectedText) {
1476     /* print selected region */
1477     PrintStart = SelectStart;
1478     PrintEnd = SelectEnd;
1479     }
1480     else if (Id==IdPrnScrollRegion) {
1481     /* print scroll region */
1482     PrintStart.x = 0;
1483     PrintStart.y = PageStart + CursorTop;
1484     PrintEnd.x = NumOfColumns;
1485     PrintEnd.y = PageStart + CursorBottom;
1486     }
1487     else {
1488     /* print current screen */
1489     PrintStart.x = 0;
1490     PrintStart.y = PageStart;
1491     PrintEnd.x = NumOfColumns;
1492     PrintEnd.y = PageStart + NumOfLines - 1;
1493     }
1494     if (PrintEnd.y > BuffEnd-1) {
1495     PrintEnd.y = BuffEnd-1;
1496     }
1497 maya 3227
1498 maya 3393 LockBuffer();
1499 maya 3227
1500 maya 3393 TmpPtr = GetLinePtr(PrintStart.y);
1501     for (j = PrintStart.y ; j <= PrintEnd.y ; j++) {
1502     if (j==PrintStart.y) {
1503     IStart = PrintStart.x;
1504     }
1505     else {
1506     IStart = 0;
1507     }
1508     if (j == PrintEnd.y) {
1509     IEnd = PrintEnd.x - 1;
1510     }
1511     else {
1512     IEnd = NumOfColumns - 1;
1513     }
1514 maya 3227
1515 maya 3393 while ((IEnd>=IStart) &&
1516     (CodeBuff[TmpPtr+IEnd]==0x20) &&
1517     (AttrBuff[TmpPtr+IEnd]==AttrDefault) &&
1518     (AttrBuff2[TmpPtr+IEnd]==AttrDefault)) {
1519     IEnd--;
1520     }
1521 maya 3227
1522 maya 3393 i = IStart;
1523     while (i <= IEnd) {
1524     CurAttr.Attr = AttrBuff[TmpPtr+i] & ~ AttrKanji;
1525     CurAttr.Attr2 = AttrBuff2[TmpPtr+i];
1526     CurAttr.Fore = AttrBuffFG[TmpPtr+i];
1527     CurAttr.Back = AttrBuffBG[TmpPtr+i];
1528 maya 3227
1529 maya 3393 count = 1;
1530     while ((i+count <= IEnd) &&
1531     (CurAttr.Attr == (AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
1532     (CurAttr.Attr2 == AttrBuff2[TmpPtr+i+count]) &&
1533     (CurAttr.Fore == AttrBuffFG[TmpPtr+i+count]) &&
1534     (CurAttr.Back == AttrBuffBG[TmpPtr+i+count]) ||
1535     (i+count<NumOfColumns) &&
1536     ((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0)) {
1537     count++;
1538     }
1539 maya 3227
1540 maya 3393 if (TCharAttrCmp(CurAttr, TempAttr) != 0) {
1541     PrnSetAttr(CurAttr);
1542     TempAttr = CurAttr;
1543     }
1544     PrnOutText(&(CodeBuff[TmpPtr+i]),count);
1545     i = i+count;
1546     }
1547     PrnNewLine();
1548     TmpPtr = NextLinePtr(TmpPtr);
1549     }
1550 maya 3227
1551 maya 3393 UnlockBuffer();
1552     VTPrintEnd();
1553 maya 3227 }
1554    
1555     void BuffDumpCurrentLine(BYTE TERM)
1556     // Dumps current line to the file (for path through printing)
1557     // HFile: file handle
1558     // TERM: terminator character
1559     // = LF or VT or FF
1560     {
1561 maya 3393 int i, j;
1562 maya 3227
1563 maya 3393 i = NumOfColumns;
1564     while ((i>0) && (CodeLine[i-1]==0x20)) {
1565     i--;
1566     }
1567     for (j=0; j<i; j++) {
1568     WriteToPrnFile(CodeLine[j],FALSE);
1569     }
1570     WriteToPrnFile(0,TRUE);
1571     if ((TERM>=LF) && (TERM<=FF)) {
1572     WriteToPrnFile(0x0d,FALSE);
1573     WriteToPrnFile(TERM,TRUE);
1574     }
1575 maya 3227 }
1576    
1577    
1578     /* begin - ishizaki */
1579     static void markURL(int x)
1580     {
1581     #ifdef URL_EMPHASIS
1582 doda 5428 LONG PrevCharPtr;
1583     CHAR PrevCharAttr, PrevCharCode;
1584 doda 5278
1585 yutakapon 3414 // RFC3986(Uniform Resource Identifier (URI): Generic Syntax)����������
1586 maya 3227 // by sakura editor 1.5.2.1: etc_uty.cpp
1587     static const char url_char[] = {
1588     /* +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F */
1589 doda 5426 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* +00: */
1590     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* +10: */
1591     0, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, /* +20: " !"#$%&'()*+,-./" */
1592     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, /* +30: "0123456789:;<=>?" */
1593     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* +40: "@ABCDEFGHIJKLMNO" */
1594     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1, /* +50: "PQRSTUVWXYZ[\]^_" */
1595     0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* +60: "`abcdefghijklmno" */
1596     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, /* +70: "pqrstuvwxyz{|}~ " */
1597     /* 0 : not url char
1598     * -1 : url char
1599     * other: url head char --> url_table array number + 1
1600     */
1601 maya 3227 };
1602 yutakapon 3614 static char *prefix[] = {
1603     "https://",
1604     "http://",
1605     "sftp://",
1606     "tftp://",
1607     "news://",
1608     "ftp://",
1609     "mms://",
1610     NULL
1611     };
1612 maya 3227 unsigned char ch = CodeLine[x];
1613    
1614 doda 6435 if (ts.EnableClickableUrl == FALSE &&
1615 yutakapon 3615 (ts.ColorFlag & CF_URLCOLOR) == 0)
1616 maya 3227 return;
1617    
1618     // ���O���s�����A�������������B
1619     if (x == 0) {
1620 doda 5428 PrevCharPtr = PrevLinePtr(LinePtr) + NumOfColumns-1;
1621     PrevCharCode = CodeBuff[PrevCharPtr];
1622     PrevCharAttr = AttrBuff[PrevCharPtr];
1623 doda 5438 if ((PrevCharAttr & AttrURL) && !(AttrLine[0]&(AttrKanji|AttrSpecial)) && !(ch & 0x80) && url_char[ch]) {
1624     if ((AttrLine[0] & AttrLineContinued) || (ts.JoinSplitURL &&
1625     (PrevCharCode == ts.JoinSplitURLIgnoreEOLChar || ts.JoinSplitURLIgnoreEOLChar == '\0' ))) {
1626 doda 6435 AttrLine[0] |= AttrURL;
1627 doda 5433 }
1628 maya 3227 }
1629     return;
1630     }
1631    
1632     if ((x-1>=0) && (AttrLine[x-1] & AttrURL) &&
1633 doda 5438 !(AttrLine[x] & (AttrKanji|AttrSpecial)) &&
1634     ((!(ch & 0x80) && url_char[ch]) || (x == NumOfColumns - 1 && ch == ts.JoinSplitURLIgnoreEOLChar))) {
1635 doda 6435 AttrLine[x] |= AttrURL;
1636 maya 3227 return;
1637     }
1638    
1639     if ((x-2>=0) && !strncmp(&CodeLine[x-2], "://", 3)) {
1640 maya 3417 int i, len = -1;
1641 yutakapon 3608 RECT rc;
1642     int CaretX, CaretY;
1643 yutakapon 3614 char **p = prefix;
1644 yutakapon 3608
1645 yutakapon 3614 while (*p) {
1646     len = strlen(*p) - 1;
1647     if ((x-len>=0) && !strncmp(&CodeLine[x-len], *p, len)) {
1648     for (i = 0; i <= len; i++) {
1649 doda 6435 AttrLine[x-i] |= AttrURL;
1650 yutakapon 3614 }
1651     break;
1652     }
1653     p++;
1654 maya 3227 }
1655 yutakapon 3608
1656     /* �n�C�p�[�����N���F�������X���A�������������o�������A�o�b�t�@���k���� URL ������
1657     * �t���������������W�b�N�����������A�F���������`���������������������B
1658     * ���X���������A�n�C�p�[�����N�����������^�C�~���O���A�����s�����`���w�����o���������A
1659     * ���A���^�C�����F�`�������������B
1660     * (2009.8.26 yutaka)
1661     */
1662     CaretX = (0-WinOrgX)*FontWidth;
1663     CaretY = (CursorY-WinOrgY)*FontHeight;
1664     rc.left = CaretX;
1665     rc.top = CaretY;
1666     rc.right = CaretX + NumOfColumns * FontWidth;
1667     rc.bottom = CaretY + FontHeight;
1668     InvalidateRect(HVTWin, &rc, FALSE);
1669 maya 3227 }
1670     #endif
1671     }
1672     /* end - ishizaki */
1673    
1674     void BuffPutChar(BYTE b, TCharAttr Attr, BOOL Insert)
1675     // Put a character in the buffer at the current position
1676     // b: character
1677     // Attr: attributes
1678     // Insert: Insert flag
1679     {
1680 doda 5324 int XStart, LineEnd, MoveLen;
1681 doda 5371 int extr = 0;
1682 maya 3227
1683 maya 3393 if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
1684     Attr.Attr |= AttrLineContinued;
1685     }
1686 doda 3312
1687 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1688 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1689     if (! Insert) {
1690     EraseKanji(0); /* if cursor on left half... */
1691     }
1692     }
1693 maya 3227
1694 maya 3393 if (Insert) {
1695 doda 5324 if (CursorX > CursorRightM)
1696     LineEnd = NumOfColumns - 1;
1697     else
1698     LineEnd = CursorRightM;
1699    
1700 doda 5371 if (LineEnd < NumOfColumns - 1 && (AttrLine[LineEnd] & AttrKanji)) {
1701     CodeLine[LineEnd] = 0x20;
1702     AttrLine[LineEnd] &= ~AttrKanji;
1703     CodeLine[LineEnd+1] = 0x20;
1704     AttrLine[LineEnd+1] &= ~AttrKanji;
1705     extr = 1;
1706     }
1707    
1708 doda 5324 MoveLen = LineEnd - CursorX;
1709     if (MoveLen > 0) {
1710     memmove(&CodeLine[CursorX+1], &CodeLine[CursorX], MoveLen);
1711     memmove(&AttrLine[CursorX+1], &AttrLine[CursorX], MoveLen);
1712     memmove(&AttrLine2[CursorX+1], &AttrLine2[CursorX], MoveLen);
1713     memmove(&AttrLineFG[CursorX+1], &AttrLineFG[CursorX], MoveLen);
1714     memmove(&AttrLineBG[CursorX+1], &AttrLineBG[CursorX], MoveLen);
1715     }
1716 maya 3393 CodeLine[CursorX] = b;
1717     AttrLine[CursorX] = Attr.Attr;
1718     AttrLine2[CursorX] = Attr.Attr2;
1719     AttrLineFG[CursorX] = Attr.Fore;
1720     AttrLineBG[CursorX] = Attr.Back;
1721     /* last char in current line is kanji first? */
1722 doda 5324 if ((AttrLine[LineEnd] & AttrKanji) != 0) {
1723 maya 3393 /* then delete it */
1724 doda 5324 CodeLine[LineEnd] = 0x20;
1725     AttrLine[LineEnd] = CurCharAttr.Attr;
1726     AttrLine2[LineEnd] = CurCharAttr.Attr2;
1727     AttrLineFG[LineEnd] = CurCharAttr.Fore;
1728     AttrLineBG[LineEnd] = CurCharAttr.Back;
1729 maya 3393 }
1730     /* begin - ishizaki */
1731     markURL(CursorX+1);
1732     markURL(CursorX);
1733     /* end - ishizaki */
1734 maya 3227
1735 maya 3393 if (StrChangeCount==0) {
1736     XStart = CursorX;
1737     }
1738     else {
1739     XStart = StrChangeStart;
1740     }
1741     StrChangeCount = 0;
1742 doda 5371 BuffUpdateRect(XStart, CursorY, LineEnd+extr, CursorY);
1743 maya 3393 }
1744     else {
1745     CodeLine[CursorX] = b;
1746     AttrLine[CursorX] = Attr.Attr;
1747     AttrLine2[CursorX] = Attr.Attr2;
1748     AttrLineFG[CursorX] = Attr.Fore;
1749     AttrLineBG[CursorX] = Attr.Back;
1750     /* begin - ishizaki */
1751     markURL(CursorX);
1752     /* end - ishizaki */
1753 maya 3227
1754 maya 3393 if (StrChangeCount==0) {
1755     StrChangeStart = CursorX;
1756     }
1757     StrChangeCount++;
1758     }
1759 maya 3227 }
1760    
1761     void BuffPutKanji(WORD w, TCharAttr Attr, BOOL Insert)
1762     // Put a kanji character in the buffer at the current position
1763     // b: character
1764     // Attr: attributes
1765     // Insert: Insert flag
1766     {
1767 doda 5324 int XStart, LineEnd, MoveLen;
1768 doda 5371 int extr = 0;
1769 maya 3227
1770 maya 3393 if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
1771     Attr.Attr |= AttrLineContinued;
1772     }
1773 doda 3312
1774 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1775 maya 3227
1776 maya 3393 if (Insert) {
1777 doda 5324 if (CursorX > CursorRightM)
1778     LineEnd = NumOfColumns - 1;
1779     else
1780     LineEnd = CursorRightM;
1781 maya 3227
1782 doda 5371 if (LineEnd < NumOfColumns - 1 && (AttrLine[LineEnd] & AttrKanji)) {
1783     CodeLine[LineEnd] = 0x20;
1784     AttrLine[LineEnd] &= ~AttrKanji;
1785     CodeLine[LineEnd+1] = 0x20;
1786     AttrLine[LineEnd+1] &= ~AttrKanji;
1787     extr = 1;
1788     }
1789    
1790 doda 5324 MoveLen = LineEnd - CursorX - 1;
1791     if (MoveLen > 0) {
1792     memmove(&CodeLine[CursorX+2], &CodeLine[CursorX], MoveLen);
1793     memmove(&AttrLine[CursorX+2], &AttrLine[CursorX], MoveLen);
1794     memmove(&AttrLine2[CursorX+2], &AttrLine2[CursorX], MoveLen);
1795     memmove(&AttrLineFG[CursorX+2], &AttrLineFG[CursorX], MoveLen);
1796     memmove(&AttrLineBG[CursorX+2], &AttrLineBG[CursorX], MoveLen);
1797     }
1798    
1799 maya 3393 CodeLine[CursorX] = HIBYTE(w);
1800     AttrLine[CursorX] = Attr.Attr | AttrKanji; /* DBCS first byte */
1801     AttrLine2[CursorX] = Attr.Attr2;
1802     AttrLineFG[CursorX] = Attr.Fore;
1803     AttrLineBG[CursorX] = Attr.Back;
1804 doda 5324 if (CursorX < LineEnd) {
1805 maya 3393 CodeLine[CursorX+1] = LOBYTE(w);
1806     AttrLine[CursorX+1] = Attr.Attr;
1807     AttrLine2[CursorX+1] = Attr.Attr2;
1808     AttrLineFG[CursorX+1] = Attr.Fore;
1809     AttrLineBG[CursorX+1] = Attr.Back;
1810     }
1811     /* begin - ishizaki */
1812     markURL(CursorX);
1813     markURL(CursorX+1);
1814     /* end - ishizaki */
1815 maya 3227
1816 maya 3393 /* last char in current line is kanji first? */
1817 doda 5324 if ((AttrLine[LineEnd] & AttrKanji) != 0) {
1818 maya 3393 /* then delete it */
1819 doda 5324 CodeLine[LineEnd] = 0x20;
1820     AttrLine[LineEnd] = CurCharAttr.Attr;
1821     AttrLine2[LineEnd] = CurCharAttr.Attr2;
1822     AttrLineFG[LineEnd] = CurCharAttr.Fore;
1823     AttrLineBG[LineEnd] = CurCharAttr.Back;
1824 maya 3393 }
1825 maya 3227
1826 maya 3393 if (StrChangeCount==0) {
1827     XStart = CursorX;
1828     }
1829     else {
1830     XStart = StrChangeStart;
1831     }
1832     StrChangeCount = 0;
1833 doda 5371 BuffUpdateRect(XStart, CursorY, LineEnd+extr, CursorY);
1834 maya 3393 }
1835     else {
1836     CodeLine[CursorX] = HIBYTE(w);
1837     AttrLine[CursorX] = Attr.Attr | AttrKanji; /* DBCS first byte */
1838     AttrLine2[CursorX] = Attr.Attr2;
1839     AttrLineFG[CursorX] = Attr.Fore;
1840     AttrLineBG[CursorX] = Attr.Back;
1841     if (CursorX < NumOfColumns-1) {
1842     CodeLine[CursorX+1] = LOBYTE(w);
1843     AttrLine[CursorX+1] = Attr.Attr;
1844     AttrLine2[CursorX+1] = Attr.Attr2;
1845     AttrLineFG[CursorX+1] = Attr.Fore;
1846     AttrLineBG[CursorX+1] = Attr.Back;
1847     }
1848     /* begin - ishizaki */
1849     markURL(CursorX);
1850     markURL(CursorX+1);
1851     /* end - ishizaki */
1852 maya 3227
1853 maya 3393 if (StrChangeCount==0) {
1854     StrChangeStart = CursorX;
1855     }
1856     StrChangeCount = StrChangeCount + 2;
1857     }
1858 maya 3227 }
1859    
1860     BOOL CheckSelect(int x, int y)
1861     // subroutine called by BuffUpdateRect
1862     {
1863 maya 3393 LONG L, L1, L2;
1864 maya 3227
1865 maya 3393 if (BoxSelect) {
1866     return (Selected &&
1867     ((SelectStart.x<=x) && (x<SelectEnd.x) ||
1868     (SelectEnd.x<=x) && (x<SelectStart.x)) &&
1869     ((SelectStart.y<=y) && (y<=SelectEnd.y) ||
1870     (SelectEnd.y<=y) && (y<=SelectStart.y)));
1871     }
1872     else {
1873     L = MAKELONG(x,y);
1874     L1 = MAKELONG(SelectStart.x,SelectStart.y);
1875     L2 = MAKELONG(SelectEnd.x,SelectEnd.y);
1876 maya 3227
1877 maya 3393 return (Selected &&
1878     ((L1<=L) && (L<L2) || (L2<=L) && (L<L1)));
1879     }
1880 maya 3227 }
1881    
1882     void BuffUpdateRect
1883     (int XStart, int YStart, int XEnd, int YEnd)
1884     // Display text in a rectangular region in the screen
1885     // XStart: x position of the upper-left corner (screen cordinate)
1886     // YStart: y position
1887     // XEnd: x position of the lower-right corner (last character)
1888     // YEnd: y position
1889     {
1890 maya 3393 int i, j, count;
1891     int IStart, IEnd;
1892     int X, Y;
1893     LONG TmpPtr;
1894     TCharAttr CurAttr, TempAttr;
1895     BOOL CurSel, TempSel, Caret;
1896 maya 3227
1897 maya 3393 if (XStart >= WinOrgX+WinWidth) {
1898     return;
1899     }
1900     if (YStart >= WinOrgY+WinHeight) {
1901     return;
1902     }
1903     if (XEnd < WinOrgX) {
1904     return;
1905     }
1906     if (YEnd < WinOrgY) {
1907     return;
1908     }
1909 maya 3227
1910 maya 3393 if (XStart < WinOrgX) {
1911     XStart = WinOrgX;
1912     }
1913     if (YStart < WinOrgY) {
1914     YStart = WinOrgY;
1915     }
1916     if (XEnd >= WinOrgX+WinWidth) {
1917     XEnd = WinOrgX+WinWidth-1;
1918     }
1919     if (YEnd >= WinOrgY+WinHeight) {
1920     YEnd = WinOrgY+WinHeight-1;
1921     }
1922 maya 3227
1923 maya 3393 TempAttr = DefCharAttr;
1924     TempSel = FALSE;
1925 maya 3227
1926 maya 3393 Caret = IsCaretOn();
1927     if (Caret) {
1928     CaretOff();
1929     }
1930 maya 3227
1931 maya 3393 DispSetupDC(DefCharAttr, TempSel);
1932 maya 3227
1933 maya 3393 Y = (YStart-WinOrgY)*FontHeight;
1934     TmpPtr = GetLinePtr(PageStart+YStart);
1935     for (j = YStart+PageStart ; j <= YEnd+PageStart ; j++) {
1936     IStart = XStart;
1937     IEnd = XEnd;
1938 maya 3227
1939 maya 3393 IStart = LeftHalfOfDBCS(TmpPtr,IStart);
1940 maya 3227
1941 maya 3393 X = (IStart-WinOrgX)*FontWidth;
1942 maya 3227
1943 maya 3393 i = IStart;
1944     do {
1945     CurAttr.Attr = AttrBuff[TmpPtr+i] & ~ AttrKanji;
1946     CurAttr.Attr2 = AttrBuff2[TmpPtr+i];
1947     CurAttr.Fore = AttrBuffFG[TmpPtr+i];
1948     CurAttr.Back = AttrBuffBG[TmpPtr+i];
1949     CurSel = CheckSelect(i,j);
1950     count = 1;
1951     while ( (i+count <= IEnd) &&
1952     (CurAttr.Attr == (AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
1953     (CurAttr.Attr2==AttrBuff2[TmpPtr+i+count]) &&
1954     (CurAttr.Fore==AttrBuffFG[TmpPtr+i+count]) &&
1955     (CurAttr.Back==AttrBuffBG[TmpPtr+i+count]) &&
1956     (CurSel==CheckSelect(i+count,j)) ||
1957     (i+count<NumOfColumns) &&
1958     ((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0) ) {
1959     count++;
1960     }
1961 maya 3227
1962 maya 3393 if (TCharAttrCmp(CurAttr, TempAttr) != 0 || (CurSel != TempSel)) {
1963     DispSetupDC(CurAttr, CurSel);
1964     TempAttr = CurAttr;
1965     TempSel = CurSel;
1966     }
1967     DispStr(&CodeBuff[TmpPtr+i],count,Y, &X);
1968     i = i+count;
1969     }
1970     while (i<=IEnd);
1971     Y = Y + FontHeight;
1972     TmpPtr = NextLinePtr(TmpPtr);
1973     }
1974     if (Caret) {
1975     CaretOn();
1976     }
1977 maya 3227 }
1978    
1979     void UpdateStr()
1980     // Display not-yet-displayed string
1981     {
1982 maya 3393 int X, Y;
1983     TCharAttr TempAttr;
1984 yutakapon 3656 int pos, len;
1985 maya 3227
1986 maya 3393 if (StrChangeCount==0) {
1987     return;
1988     }
1989     X = StrChangeStart;
1990     Y = CursorY;
1991     if (! IsLineVisible(&X, &Y)) {
1992     StrChangeCount = 0;
1993     return;
1994     }
1995 maya 3227
1996 maya 3393 TempAttr.Attr = AttrLine[StrChangeStart];
1997     TempAttr.Attr2 = AttrLine2[StrChangeStart];
1998     TempAttr.Fore = AttrLineFG[StrChangeStart];
1999     TempAttr.Back = AttrLineBG[StrChangeStart];
2000 yutakapon 3656
2001     /* ���������`���������������n�������uURL�\�����������v�����������A
2002     * ���Y�F���s�������y�C���g�������������������B
2003     * (2009.10.24 yutaka)
2004     */
2005 doda 3659 if (TempAttr.Attr & AttrURL) {
2006 yutakapon 3656 /* �J�n���u�������������� AttrURL �����J�E���g���� */
2007     len = 0;
2008     for (pos = 0 ; pos < StrChangeCount ; pos++) {
2009     if (TempAttr.Attr != AttrLine[StrChangeStart + pos])
2010     break;
2011     len++;
2012     }
2013     DispSetupDC(TempAttr, FALSE);
2014     DispStr(&CodeLine[StrChangeStart], len, Y, &X);
2015    
2016     /* �c�������������������A���������`�����s���B*/
2017     if (len < StrChangeCount) {
2018     TempAttr.Attr = AttrLine[StrChangeStart + pos];
2019     TempAttr.Attr2 = AttrLine2[StrChangeStart + pos];
2020     TempAttr.Fore = AttrLineFG[StrChangeStart + pos];
2021     TempAttr.Back = AttrLineBG[StrChangeStart + pos];
2022    
2023     DispSetupDC(TempAttr, FALSE);
2024     DispStr(&CodeLine[StrChangeStart + pos], (StrChangeCount - len), Y, &X);
2025     }
2026     } else {
2027     DispSetupDC(TempAttr, FALSE);
2028     DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
2029     }
2030    
2031 maya 3393 StrChangeCount = 0;
2032 maya 3227 }
2033    
2034     #if 0
2035     void UpdateStrUnicode(void)
2036     // Display not-yet-displayed string
2037     {
2038     int X, Y;
2039     TCharAttr TempAttr;
2040    
2041     if (StrChangeCount==0) return;
2042     X = StrChangeStart;
2043     Y = CursorY;
2044     if (! IsLineVisible(&X, &Y))
2045     {
2046     StrChangeCount = 0;
2047     return;
2048     }
2049    
2050     TempAttr.Attr = AttrLine[StrChangeStart];
2051     TempAttr.Attr2 = AttrLine2[StrChangeStart];
2052     TempAttr.Fore = AttrLineFG[StrChangeStart];
2053     TempAttr.Back = AttrLineBG[StrChangeStart];
2054     DispSetupDC(TempAttr, FALSE);
2055     DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
2056     StrChangeCount = 0;
2057     }
2058     #endif
2059    
2060     void MoveCursor(int Xnew, int Ynew)
2061     {
2062 maya 3393 UpdateStr();
2063 maya 3227
2064 maya 3393 if (CursorY!=Ynew) {
2065     NewLine(PageStart+Ynew);
2066     }
2067 maya 3227
2068 maya 3393 CursorX = Xnew;
2069     CursorY = Ynew;
2070     Wrap = FALSE;
2071 maya 3227
2072 maya 3393 /* �����s�����������X�N���[������*/
2073 doda 4469 if (ts.AutoScrollOnlyInBottomLine == 0 || WinOrgY == 0) {
2074 maya 3393 DispScrollToCursor(CursorX, CursorY);
2075     }
2076 maya 3227 }
2077    
2078     void MoveRight()
2079     /* move cursor right, but dont update screen.
2080     this procedure must be called from DispChar&DispKanji only */
2081     {
2082 maya 3393 CursorX++;
2083     /* �����s�����������X�N���[������ */
2084 doda 4469 if (ts.AutoScrollOnlyInBottomLine == 0 || WinOrgY == 0) {
2085 maya 3393 DispScrollToCursor(CursorX, CursorY);
2086     }
2087 maya 3227 }
2088    
2089     void BuffSetCaretWidth()
2090     {
2091 maya 3393 BOOL DW;
2092 maya 3227
2093 maya 3393 /* check whether cursor on a DBCS character */
2094     DW = (((BYTE)(AttrLine[CursorX]) & AttrKanji) != 0);
2095     DispSetCaretWidth(DW);
2096 maya 3227 }
2097    
2098     void ScrollUp1Line()
2099     {
2100 doda 5324 int i, linelen;
2101 doda 5371 int extl=0, extr=0;
2102 maya 3393 LONG SrcPtr, DestPtr;
2103 maya 3227
2104 maya 3393 if ((CursorTop<=CursorY) && (CursorY<=CursorBottom)) {
2105     UpdateStr();
2106 maya 3227
2107 doda 5371 if (CursorLeftM > 0)
2108     extl = 1;
2109     if (CursorRightM < NumOfColumns-1)
2110     extr = 1;
2111     if (extl || extr)
2112     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorTop), CursorBottom-CursorTop+1);
2113    
2114 doda 5324 linelen = CursorRightM - CursorLeftM + 1;
2115     DestPtr = GetLinePtr(PageStart+CursorBottom) + CursorLeftM;
2116 maya 3393 for (i = CursorBottom-1 ; i >= CursorTop ; i--) {
2117     SrcPtr = PrevLinePtr(DestPtr);
2118 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
2119     memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
2120     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
2121     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
2122     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
2123 maya 3393 DestPtr = SrcPtr;
2124     }
2125 doda 5324 memset(&(CodeBuff[SrcPtr]), 0x20, linelen);
2126     memset(&(AttrBuff[SrcPtr]), AttrDefault, linelen);
2127     memset(&(AttrBuff2[SrcPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
2128     memset(&(AttrBuffFG[SrcPtr]), CurCharAttr.Fore, linelen);
2129     memset(&(AttrBuffBG[SrcPtr]), CurCharAttr.Back, linelen);
2130 maya 3227
2131 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1)
2132 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorTop, CursorRightM+extr, CursorBottom);
2133 doda 5324 else
2134     DispScrollNLines(CursorTop, CursorBottom, -1);
2135 maya 3393 }
2136 maya 3227 }
2137    
2138     void BuffScrollNLines(int n)
2139     {
2140 doda 5324 int i, linelen;
2141 doda 5371 int extl=0, extr=0;
2142 maya 3393 LONG SrcPtr, DestPtr;
2143 maya 3227
2144 maya 3393 if (n<1) {
2145     return;
2146     }
2147     UpdateStr();
2148 maya 3227
2149 doda 5324 if (CursorLeftM == 0 && CursorRightM == NumOfColumns-1 && CursorTop == 0) {
2150     if (CursorBottom == NumOfLines-1) {
2151 maya 3393 WinOrgY = WinOrgY-n;
2152 doda 5324 /* �����s�����������X�N���[������ */
2153     if (ts.AutoScrollOnlyInBottomLine != 0 && NewOrgY != 0) {
2154     NewOrgY = WinOrgY;
2155     }
2156 maya 3393 BuffScroll(n,CursorBottom);
2157     DispCountScroll(n);
2158 doda 5324 return;
2159 maya 3393 }
2160 doda 5324 else if (CursorY <= CursorBottom) {
2161     /* �����s�����������X�N���[������ */
2162     if (ts.AutoScrollOnlyInBottomLine != 0 && NewOrgY != 0) {
2163     /* �X�N���[�������������������� */
2164     WinOrgY = WinOrgY-n;
2165     NewOrgY = WinOrgY;
2166     BuffScroll(n,CursorBottom);
2167     DispCountScroll(n);
2168     } else {
2169     BuffScroll(n,CursorBottom);
2170     DispScrollNLines(WinOrgY,CursorBottom,n);
2171     }
2172     return;
2173     }
2174 maya 3393 }
2175 doda 5324
2176     if ((CursorTop<=CursorY) && (CursorY<=CursorBottom)) {
2177 doda 5371 if (CursorLeftM > 0)
2178     extl = 1;
2179     if (CursorRightM < NumOfColumns-1)
2180     extr = 1;
2181     if (extl || extr)
2182     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorTop), CursorBottom-CursorTop+1);
2183    
2184 doda 5324 linelen = CursorRightM - CursorLeftM + 1;
2185     DestPtr = GetLinePtr(PageStart+CursorTop) + (LONG)CursorLeftM;
2186 maya 3393 if (n<CursorBottom-CursorTop+1) {
2187 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorTop+n) + (LONG)CursorLeftM;
2188 maya 3393 for (i = CursorTop+