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 6806 - (hide annotations) (download) (as text)
Thu Jun 15 00:37:01 2017 UTC (6 years, 9 months ago) by doda
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 100675 byte(s)
TeraTerm Project としてのライセンス表記を追加

とりあえず Tera Term 本体分。
TeraTerm Project としての copyright 表記の年部分はコミットログを確認して書いたつもりだけど、ミスってたらすみません。

TODO: 過去に取り込んだパッチに関する著作権表記の追加
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3     * (C) 2004-2017 TeraTerm Project
4     * All rights reserved.
5     *
6     * Redistribution and use in source and binary forms, with or without modification,
7     * are permitted provided that the following conditions are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright notice,
10     * this list of conditions and the following disclaimer.
11     * 2. Redistributions in binary form must reproduce the above copyright notice,
12     * this list of conditions and the following disclaimer in the documentation
13     * and/or other materials provided with the distribution.
14     * 3. The name of the author may not be used to endorse or promote products derived
15     * from this software without specific prior written permission.
16     *
17     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18     * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21     * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
22     * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
25     * OF SUCH DAMAGE.
26     */
27 maya 3227
28     /* TERATERM.EXE, scroll buffer routines */
29    
30     #include "teraterm.h"
31     #include "tttypes.h"
32     #include <string.h>
33 yutakapon 4707 #include <stdio.h>
34 maya 3227
35     #include "ttwinman.h"
36     #include "teraprn.h"
37     #include "vtdisp.h"
38     #include "clipboar.h"
39     #include "telnet.h"
40     #include "ttplug.h" /* TTPLUG */
41    
42     #include "buffer.h"
43    
44     // URL�����������i�������p�b�` 2005/4/2�j
45     #define URL_EMPHASIS 1
46    
47     #define BuffXMax TermWidthMax
48     //#define BuffYMax 100000
49     //#define BuffSizeMax 8000000
50     // �X�N���[���o�b�t�@�����������g�� (2004.11.28 yutaka)
51     #define BuffYMax 500000
52     #define BuffSizeMax (BuffYMax * 80)
53    
54     // status line
55 doda 6435 int StatusLine; //0: none 1: shown
56 doda 5324 /* top, bottom, left & right margin */
57     int CursorTop, CursorBottom, CursorLeftM, CursorRightM;
58 maya 3227 BOOL Selected;
59     BOOL Wrap;
60    
61     static WORD TabStops[256];
62     static int NTabStops;
63    
64     static WORD BuffLock = 0;
65     static HANDLE HCodeBuff = 0;
66     static HANDLE HAttrBuff = 0;
67     static HANDLE HAttrBuff2 = 0;
68     static HANDLE HAttrBuffFG = 0;
69     static HANDLE HAttrBuffBG = 0;
70    
71     static PCHAR CodeBuff; /* Character code buffer */
72     static PCHAR AttrBuff; /* Attribute buffer */
73     static PCHAR AttrBuff2; /* Color attr buffer */
74     static PCHAR AttrBuffFG; /* Foreground color attr buffer */
75     static PCHAR AttrBuffBG; /* Background color attr buffer */
76     static PCHAR CodeLine;
77     static PCHAR AttrLine;
78     static PCHAR AttrLine2;
79     static PCHAR AttrLineFG;
80     static PCHAR AttrLineBG;
81     static LONG LinePtr;
82     static LONG BufferSize;
83     static int NumOfLinesInBuff;
84     static int BuffStartAbs, BuffEndAbs;
85     static POINT SelectStart, SelectEnd, SelectEndOld;
86     static BOOL BoxSelect;
87     static POINT DblClkStart, DblClkEnd;
88    
89     static int StrChangeStart, StrChangeCount;
90    
91     static BOOL SeveralPageSelect; // add (2005.5.15 yutaka)
92    
93     static TCharAttr CurCharAttr;
94    
95 doda 3743 HANDLE SaveBuff = NULL;
96     int SaveBuffX;
97     int SaveBuffY;
98    
99 maya 3227 LONG GetLinePtr(int Line)
100     {
101 maya 3393 LONG Ptr;
102 maya 3227
103 maya 3393 Ptr = (LONG)(BuffStartAbs + Line) * (LONG)(NumOfColumns);
104     while (Ptr>=BufferSize) {
105     Ptr = Ptr - BufferSize;
106     }
107     return Ptr;
108 maya 3227 }
109    
110     LONG NextLinePtr(LONG Ptr)
111     {
112 maya 3393 Ptr = Ptr + (LONG)NumOfColumns;
113     if (Ptr >= BufferSize) {
114     Ptr = Ptr - BufferSize;
115     }
116     return Ptr;
117 maya 3227 }
118    
119     LONG PrevLinePtr(LONG Ptr)
120     {
121 maya 3393 Ptr = Ptr - (LONG)NumOfColumns;
122     if (Ptr < 0) {
123     Ptr = Ptr + BufferSize;
124     }
125     return Ptr;
126 maya 3227 }
127    
128     BOOL ChangeBuffer(int Nx, int Ny)
129     {
130 maya 3393 HANDLE HCodeNew, HAttrNew, HAttr2New, HAttrFGNew, HAttrBGNew;
131     LONG NewSize;
132     int NxCopy, NyCopy, i;
133     PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG;
134     LONG SrcPtr, DestPtr;
135     WORD LockOld;
136 maya 3227
137 maya 3393 if (Nx > BuffXMax) {
138     Nx = BuffXMax;
139     }
140     if (ts.ScrollBuffMax > BuffYMax) {
141     ts.ScrollBuffMax = BuffYMax;
142     }
143     if (Ny > ts.ScrollBuffMax) {
144     Ny = ts.ScrollBuffMax;
145     }
146 maya 3227
147 maya 3393 if ( (LONG)Nx * (LONG)Ny > BuffSizeMax ) {
148     Ny = BuffSizeMax / Nx;
149     }
150 maya 3227
151 maya 3393 NewSize = (LONG)Nx * (LONG)Ny;
152 maya 3227
153 doda 3686 HCodeNew = NULL;
154     HAttrNew = NULL;
155     HAttr2New = NULL;
156     HAttrFGNew = NULL;
157     HAttrBGNew = NULL;
158 maya 3227
159 doda 3686 if ((HCodeNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (CodeDest=GlobalLock(HCodeNew)) == NULL) {
160     goto allocate_error;
161 maya 3393 }
162 doda 3686 if ((HAttrNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (AttrDest=GlobalLock(HAttrNew)) == NULL) {
163     goto allocate_error;
164 maya 3393 }
165 doda 3686 if ((HAttr2New=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (AttrDest2=GlobalLock(HAttr2New)) == NULL) {
166     goto allocate_error;
167 maya 3393 }
168 doda 3686 if ((HAttrFGNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (AttrDestFG=GlobalLock(HAttrFGNew)) == NULL) {
169     goto allocate_error;
170 maya 3393 }
171 doda 3686 if ((HAttrBGNew=GlobalAlloc(GMEM_MOVEABLE, NewSize)) == NULL || (AttrDestBG=GlobalLock(HAttrBGNew)) == NULL) {
172     goto allocate_error;
173 maya 3393 }
174 maya 3227
175 maya 3393 memset(&CodeDest[0], 0x20, NewSize);
176     memset(&AttrDest[0], AttrDefault, NewSize);
177     memset(&AttrDest2[0], AttrDefault, NewSize);
178     memset(&AttrDestFG[0], AttrDefaultFG, NewSize);
179     memset(&AttrDestBG[0], AttrDefaultBG, NewSize);
180     if ( HCodeBuff!=0 ) {
181     if ( NumOfColumns > Nx ) {
182     NxCopy = Nx;
183     }
184     else {
185     NxCopy = NumOfColumns;
186     }
187 maya 3227
188 maya 3393 if ( BuffEnd > Ny ) {
189     NyCopy = Ny;
190     }
191     else {
192     NyCopy = BuffEnd;
193     }
194     LockOld = BuffLock;
195     LockBuffer();
196     SrcPtr = GetLinePtr(BuffEnd-NyCopy);
197     DestPtr = 0;
198     for (i = 1 ; i <= NyCopy ; i++) {
199     memcpy(&CodeDest[DestPtr],&CodeBuff[SrcPtr],NxCopy);
200     memcpy(&AttrDest[DestPtr],&AttrBuff[SrcPtr],NxCopy);
201     memcpy(&AttrDest2[DestPtr],&AttrBuff2[SrcPtr],NxCopy);
202     memcpy(&AttrDestFG[DestPtr],&AttrBuffFG[SrcPtr],NxCopy);
203     memcpy(&AttrDestBG[DestPtr],&AttrBuffBG[SrcPtr],NxCopy);
204 doda 3766 if (AttrDest[DestPtr+NxCopy-1] & AttrKanji) {
205     CodeDest[DestPtr+NxCopy-1] = ' ';
206     AttrDest[DestPtr+NxCopy-1] ^= AttrKanji;
207     }
208 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
209     DestPtr = DestPtr + (LONG)Nx;
210     }
211     FreeBuffer();
212     }
213     else {
214     LockOld = 0;
215     NyCopy = NumOfLines;
216     Selected = FALSE;
217     }
218 maya 3227
219 maya 3393 if (Selected) {
220     SelectStart.y = SelectStart.y - BuffEnd + NyCopy;
221     SelectEnd.y = SelectEnd.y - BuffEnd + NyCopy;
222     if (SelectStart.y < 0) {
223     SelectStart.y = 0;
224     SelectStart.x = 0;
225     }
226     if (SelectEnd.y<0) {
227     SelectEnd.x = 0;
228     SelectEnd.y = 0;
229     }
230 maya 3227
231 maya 3393 Selected = (SelectEnd.y > SelectStart.y) ||
232     ((SelectEnd.y=SelectStart.y) &&
233     (SelectEnd.x > SelectStart.x));
234     }
235 maya 3227
236 maya 3393 HCodeBuff = HCodeNew;
237     HAttrBuff = HAttrNew;
238     HAttrBuff2 = HAttr2New;
239     HAttrBuffFG = HAttrFGNew;
240     HAttrBuffBG = HAttrBGNew;
241     BufferSize = NewSize;
242     NumOfLinesInBuff = Ny;
243     BuffStartAbs = 0;
244     BuffEnd = NyCopy;
245 maya 3227
246 maya 3393 if (BuffEnd==NumOfLinesInBuff) {
247     BuffEndAbs = 0;
248     }
249     else {
250     BuffEndAbs = BuffEnd;
251     }
252 maya 3227
253 maya 3393 PageStart = BuffEnd - NumOfLines;
254    
255     LinePtr = 0;
256     if (LockOld>0) {
257     CodeBuff = (PCHAR)GlobalLock(HCodeBuff);
258     AttrBuff = (PCHAR)GlobalLock(HAttrBuff);
259     AttrBuff2 = (PCHAR)GlobalLock(HAttrBuff2);
260     AttrBuffFG = (PCHAR)GlobalLock(HAttrBuffFG);
261     AttrBuffBG = (PCHAR)GlobalLock(HAttrBuffBG);
262     CodeLine = CodeBuff;
263     AttrLine = AttrBuff;
264     AttrLine2 = AttrBuff2;
265     AttrLineFG = AttrBuffFG;
266     AttrLineBG = AttrBuffBG;
267     }
268     else {
269     GlobalUnlock(HCodeNew);
270     GlobalUnlock(HAttrNew);
271 doda 3621 GlobalUnlock(HAttr2New);
272     GlobalUnlock(HAttrFGNew);
273     GlobalUnlock(HAttrBGNew);
274 maya 3393 }
275     BuffLock = LockOld;
276    
277     return TRUE;
278 doda 3686
279     allocate_error:
280     if (CodeDest) GlobalUnlock(HCodeNew);
281     if (AttrDest) GlobalUnlock(HAttrNew);
282     if (AttrDest2) GlobalUnlock(HAttr2New);
283     if (AttrDestFG) GlobalUnlock(HAttrFGNew);
284     if (AttrDestBG) GlobalUnlock(HAttrBGNew);
285     if (HCodeNew) GlobalFree(HCodeNew);
286     if (HAttrNew) GlobalFree(HAttrNew);
287     if (HAttr2New) GlobalFree(HAttr2New);
288     if (HAttrFGNew) GlobalFree(HAttrFGNew);
289     if (HAttrBGNew) GlobalFree(HAttrBGNew);
290     return FALSE;
291 maya 3227 }
292    
293     void InitBuffer()
294     {
295 maya 3393 int Ny;
296 maya 3227
297 maya 3393 /* setup terminal */
298     NumOfColumns = ts.TerminalWidth;
299     NumOfLines = ts.TerminalHeight;
300 maya 3227
301 doda 6785 if (NumOfColumns <= 0)
302     NumOfColumns = 80;
303     else if (NumOfColumns > TermWidthMax)
304     NumOfColumns = TermWidthMax;
305    
306     if (NumOfLines <= 0)
307     NumOfLines = 24;
308     else if (NumOfLines > TermHeightMax)
309     NumOfLines = TermHeightMax;
310    
311 maya 3393 /* setup window */
312     if (ts.EnableScrollBuff>0) {
313     if (ts.ScrollBuffSize < NumOfLines) {
314     ts.ScrollBuffSize = NumOfLines;
315     }
316     Ny = ts.ScrollBuffSize;
317     }
318     else {
319     Ny = NumOfLines;
320     }
321 maya 3227
322 maya 3393 if (! ChangeBuffer(NumOfColumns,Ny)) {
323     PostQuitMessage(0);
324     }
325 maya 3227
326 maya 3393 if (ts.EnableScrollBuff>0) {
327     ts.ScrollBuffSize = NumOfLinesInBuff;
328     }
329 maya 3227
330 maya 3393 StatusLine = 0;
331 maya 3227 }
332    
333     void NewLine(int Line)
334     {
335 maya 3393 LinePtr = GetLinePtr(Line);
336     CodeLine = &CodeBuff[LinePtr];
337     AttrLine = &AttrBuff[LinePtr];
338     AttrLine2 = &AttrBuff2[LinePtr];
339     AttrLineFG = &AttrBuffFG[LinePtr];
340     AttrLineBG = &AttrBuffBG[LinePtr];
341 maya 3227 }
342    
343     void LockBuffer()
344     {
345 maya 3393 BuffLock++;
346     if (BuffLock>1) {
347     return;
348     }
349     CodeBuff = (PCHAR)GlobalLock(HCodeBuff);
350     AttrBuff = (PCHAR)GlobalLock(HAttrBuff);
351     AttrBuff2 = (PCHAR)GlobalLock(HAttrBuff2);
352     AttrBuffFG = (PCHAR)GlobalLock(HAttrBuffFG);
353     AttrBuffBG = (PCHAR)GlobalLock(HAttrBuffBG);
354     NewLine(PageStart+CursorY);
355 maya 3227 }
356    
357     void UnlockBuffer()
358     {
359 maya 3393 if (BuffLock==0) {
360     return;
361     }
362     BuffLock--;
363     if (BuffLock>0) {
364     return;
365     }
366     if (HCodeBuff!=NULL) {
367     GlobalUnlock(HCodeBuff);
368     }
369     if (HAttrBuff!=NULL) {
370     GlobalUnlock(HAttrBuff);
371     }
372     if (HAttrBuff2!=NULL) {
373     GlobalUnlock(HAttrBuff2);
374     }
375     if (HAttrBuffFG!=NULL) {
376     GlobalUnlock(HAttrBuffFG);
377     }
378     if (HAttrBuffBG!=NULL) {
379     GlobalUnlock(HAttrBuffBG);
380     }
381 maya 3227 }
382    
383     void FreeBuffer()
384     {
385 maya 3393 BuffLock = 1;
386     UnlockBuffer();
387     if (HCodeBuff!=NULL) {
388     GlobalFree(HCodeBuff);
389     HCodeBuff = NULL;
390     }
391     if (HAttrBuff!=NULL) {
392     GlobalFree(HAttrBuff);
393     HAttrBuff = NULL;
394     }
395     if (HAttrBuff2!=NULL) {
396     GlobalFree(HAttrBuff2);
397     HAttrBuff2 = NULL;
398     }
399     if (HAttrBuffFG!=NULL) {
400     GlobalFree(HAttrBuffFG);
401     HAttrBuffFG = NULL;
402     }
403     if (HAttrBuffBG!=NULL) {
404     GlobalFree(HAttrBuffBG);
405     HAttrBuffBG = NULL;
406     }
407 maya 3227 }
408    
409     void BuffAllSelect()
410     {
411     SelectStart.x = 0;
412     SelectStart.y = 0;
413     SelectEnd.x = 0;
414     SelectEnd.y = BuffEnd;
415     // SelectEnd.x = NumOfColumns;
416     // SelectEnd.y = BuffEnd - 1;
417     }
418    
419     void BuffScreenSelect()
420     {
421     int X, Y;
422     DispConvWinToScreen(0, 0, &X, &Y, NULL);
423     SelectStart.x = X;
424     SelectStart.y = Y + PageStart;
425     SelectEnd.x = 0;
426     SelectEnd.y = SelectStart.y + NumOfLines;
427     // SelectEnd.x = X + NumOfColumns;
428     // SelectEnd.y = Y + PageStart + NumOfLines - 1;
429     }
430    
431     void BuffCancelSelection()
432     {
433     SelectStart.x = 0;
434     SelectStart.y = 0;
435     SelectEnd.x = 0;
436     SelectEnd.y = 0;
437     }
438    
439     void BuffReset()
440     // Reset buffer status. don't update real display
441     // called by ResetTerminal()
442     {
443 maya 3393 int i;
444 maya 3227
445 maya 3393 /* Cursor */
446     NewLine(PageStart);
447     WinOrgX = 0;
448     WinOrgY = 0;
449     NewOrgX = 0;
450     NewOrgY = 0;
451 maya 3227
452 maya 3393 /* Top/bottom margin */
453     CursorTop = 0;
454     CursorBottom = NumOfLines-1;
455 doda 5324 CursorLeftM = 0;
456     CursorRightM = NumOfColumns-1;
457 maya 3227
458 maya 3393 /* Tab stops */
459     NTabStops = (NumOfColumns-1) >> 3;
460     for (i=1 ; i<=NTabStops ; i++) {
461     TabStops[i-1] = i*8;
462     }
463 maya 3227
464 maya 3393 /* Initialize text selection region */
465     SelectStart.x = 0;
466     SelectStart.y = 0;
467     SelectEnd = SelectStart;
468     SelectEndOld = SelectStart;
469     Selected = FALSE;
470 maya 3227
471 maya 3393 StrChangeCount = 0;
472     Wrap = FALSE;
473     StatusLine = 0;
474 maya 3227
475 maya 3393 SeveralPageSelect = FALSE; // yutaka
476 doda 3745
477     /* Alternate Screen Buffer */
478     BuffDiscardSavedScreen();
479 maya 3227 }
480    
481     void BuffScroll(int Count, int Bottom)
482     {
483 maya 3393 int i, n;
484     LONG SrcPtr, DestPtr;
485     int BuffEndOld;
486 maya 3227
487 maya 3393 if (Count>NumOfLinesInBuff) {
488     Count = NumOfLinesInBuff;
489     }
490 maya 3227
491 maya 3393 DestPtr = GetLinePtr(PageStart+NumOfLines-1+Count);
492     n = Count;
493     if (Bottom<NumOfLines-1) {
494     SrcPtr = GetLinePtr(PageStart+NumOfLines-1);
495     for (i=NumOfLines-1; i>=Bottom+1; i--) {
496     memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
497     memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
498     memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
499     memcpy(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
500     memcpy(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
501     memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
502     memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
503 doda 4070 memset(&(AttrBuff2[SrcPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
504 maya 3393 memset(&(AttrBuffFG[SrcPtr]),CurCharAttr.Fore,NumOfColumns);
505     memset(&(AttrBuffBG[SrcPtr]),CurCharAttr.Back,NumOfColumns);
506     SrcPtr = PrevLinePtr(SrcPtr);
507     DestPtr = PrevLinePtr(DestPtr);
508     n--;
509     }
510     }
511     for (i = 1 ; i <= n ; i++) {
512     memset(&CodeBuff[DestPtr],0x20,NumOfColumns);
513     memset(&AttrBuff[DestPtr],AttrDefault,NumOfColumns);
514 doda 4070 memset(&AttrBuff2[DestPtr],CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
515 maya 3393 memset(&AttrBuffFG[DestPtr],CurCharAttr.Fore,NumOfColumns);
516     memset(&AttrBuffBG[DestPtr],CurCharAttr.Back,NumOfColumns);
517     DestPtr = PrevLinePtr(DestPtr);
518     }
519 maya 3227
520 maya 3393 BuffEndAbs = BuffEndAbs + Count;
521     if (BuffEndAbs >= NumOfLinesInBuff) {
522     BuffEndAbs = BuffEndAbs - NumOfLinesInBuff;
523     }
524     BuffEndOld = BuffEnd;
525     BuffEnd = BuffEnd + Count;
526     if (BuffEnd >= NumOfLinesInBuff) {
527     BuffEnd = NumOfLinesInBuff;
528     BuffStartAbs = BuffEndAbs;
529     }
530     PageStart = BuffEnd-NumOfLines;
531 maya 3227
532 maya 3393 if (Selected) {
533     SelectStart.y = SelectStart.y - Count + BuffEnd - BuffEndOld;
534     SelectEnd.y = SelectEnd.y - Count + BuffEnd - BuffEndOld;
535     if ( SelectStart.y<0 ) {
536     SelectStart.x = 0;
537     SelectStart.y = 0;
538     }
539     if ( SelectEnd.y<0 ) {
540     SelectEnd.x = 0;
541     SelectEnd.y = 0;
542     }
543     Selected = (SelectEnd.y > SelectStart.y) ||
544     ((SelectEnd.y==SelectStart.y) &&
545     (SelectEnd.x > SelectStart.x));
546     }
547 maya 3227
548 maya 3393 NewLine(PageStart+CursorY);
549 maya 3227 }
550    
551     void NextLine()
552     {
553 maya 3393 LinePtr = NextLinePtr(LinePtr);
554     CodeLine = &CodeBuff[LinePtr];
555     AttrLine = &AttrBuff[LinePtr];
556     AttrLine2 = &AttrBuff2[LinePtr];
557     AttrLineFG = &AttrBuffFG[LinePtr];
558     AttrLineBG = &AttrBuffBG[LinePtr];
559 maya 3227 }
560    
561     void PrevLine()
562     {
563 maya 3393 LinePtr = PrevLinePtr(LinePtr);
564     CodeLine = &CodeBuff[LinePtr];
565     AttrLine = &AttrBuff[LinePtr];
566     AttrLine2 = &AttrBuff2[LinePtr];
567     AttrLineFG = &AttrBuffFG[LinePtr];
568     AttrLineBG = &AttrBuffBG[LinePtr];
569 maya 3227 }
570    
571     void EraseKanji(int LR)
572     {
573     // If cursor is on left/right half of a Kanji, erase it.
574     // LR: left(0)/right(1) flag
575    
576 maya 3393 if ((CursorX-LR>=0) &&
577     ((AttrLine[CursorX-LR] & AttrKanji) != 0)) {
578     CodeLine[CursorX-LR] = 0x20;
579     AttrLine[CursorX-LR] = CurCharAttr.Attr;
580     AttrLine2[CursorX-LR] = CurCharAttr.Attr2;
581     AttrLineFG[CursorX-LR] = CurCharAttr.Fore;
582     AttrLineBG[CursorX-LR] = CurCharAttr.Back;
583     if (CursorX-LR+1 < NumOfColumns) {
584     CodeLine[CursorX-LR+1] = 0x20;
585     AttrLine[CursorX-LR+1] = CurCharAttr.Attr;
586     AttrLine2[CursorX-LR+1] = CurCharAttr.Attr2;
587     AttrLineFG[CursorX-LR+1] = CurCharAttr.Fore;
588     AttrLineBG[CursorX-LR+1] = CurCharAttr.Back;
589     }
590     }
591 maya 3227 }
592    
593 doda 5371 void EraseKanjiOnLRMargin(LONG ptr, int count)
594     {
595     int i;
596     LONG pos;
597    
598     if (count < 1)
599     return;
600    
601     for (i=0; i<count; i++) {
602     pos = ptr + CursorLeftM-1;
603     if (CursorLeftM>0 && (AttrBuff[pos] & AttrKanji)) {
604     CodeBuff[pos] = 0x20;
605     AttrBuff[pos] &= ~AttrKanji;
606     pos++;
607     CodeBuff[pos] = 0x20;
608     AttrBuff[pos] &= ~AttrKanji;
609     }
610     pos = ptr + CursorRightM;
611     if (CursorRightM < NumOfColumns-1 && (AttrBuff[pos] & AttrKanji)) {
612     CodeBuff[pos] = 0x20;
613     AttrBuff[pos] &= ~AttrKanji;
614     pos++;
615     CodeBuff[pos] = 0x20;
616     AttrBuff[pos] &= ~AttrKanji;
617     }
618     ptr = NextLinePtr(ptr);
619     }
620     }
621    
622 maya 3227 void BuffInsertSpace(int Count)
623     // Insert space characters at the current position
624     // Count: Number of characters to be inserted
625     {
626 doda 5326 int MoveLen;
627 doda 5371 int extr=0;
628 doda 5324
629 doda 5326 if (CursorX < CursorLeftM || CursorX > CursorRightM)
630     return;
631    
632 maya 3393 NewLine(PageStart+CursorY);
633 maya 3227
634 doda 5324 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8)
635 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
636 maya 3227
637 doda 5371 if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) {
638     CodeLine[CursorRightM+1] = 0x20;
639     AttrLine[CursorRightM+1] &= ~AttrKanji;
640     extr = 1;
641     }
642    
643 doda 5326 if (Count > CursorRightM + 1 - CursorX)
644     Count = CursorRightM + 1 - CursorX;
645 doda 5324
646 doda 5326 MoveLen = CursorRightM + 1 - CursorX - Count;
647 doda 5324
648     if (MoveLen > 0) {
649     memmove(&(CodeLine[CursorX+Count]), &(CodeLine[CursorX]), MoveLen);
650     memmove(&(AttrLine[CursorX+Count]), &(AttrLine[CursorX]), MoveLen);
651     memmove(&(AttrLine2[CursorX+Count]), &(AttrLine2[CursorX]), MoveLen);
652     memmove(&(AttrLineFG[CursorX+Count]), &(AttrLineFG[CursorX]), MoveLen);
653     memmove(&(AttrLineBG[CursorX+Count]), &(AttrLineBG[CursorX]), MoveLen);
654 maya 3393 }
655 doda 5324 memset(&(CodeLine[CursorX]), 0x20, Count);
656     memset(&(AttrLine[CursorX]), AttrDefault, Count);
657     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
658     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
659     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
660 maya 3393 /* last char in current line is kanji first? */
661 doda 5326 if ((AttrLine[CursorRightM] & AttrKanji) != 0) {
662 maya 3393 /* then delete it */
663 doda 5326 CodeLine[CursorRightM] = 0x20;
664 doda 5371 AttrLine[CursorRightM] &= ~AttrKanji;
665 maya 3393 }
666 doda 5371 BuffUpdateRect(CursorX, CursorY, CursorRightM+extr, CursorY);
667 maya 3227 }
668    
669     void BuffEraseCurToEnd()
670     // Erase characters from cursor to the end of screen
671     {
672 maya 3393 LONG TmpPtr;
673     int offset;
674     int i, YEnd;
675 maya 3227
676 maya 3393 NewLine(PageStart+CursorY);
677 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
678 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
679     }
680     offset = CursorX;
681     TmpPtr = GetLinePtr(PageStart+CursorY);
682     YEnd = NumOfLines-1;
683 doda 5324 if (StatusLine && !isCursorOnStatusLine) {
684 maya 3393 YEnd--;
685     }
686     for (i = CursorY ; i <= YEnd ; i++) {
687     memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset);
688     memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset);
689 doda 4070 memset(&(AttrBuff2[TmpPtr+offset]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset);
690 maya 3393 memset(&(AttrBuffFG[TmpPtr+offset]),CurCharAttr.Fore,NumOfColumns-offset);
691     memset(&(AttrBuffBG[TmpPtr+offset]),CurCharAttr.Back,NumOfColumns-offset);
692     offset = 0;
693     TmpPtr = NextLinePtr(TmpPtr);
694     }
695     /* update window */
696     DispEraseCurToEnd(YEnd);
697 maya 3227 }
698    
699     void BuffEraseHomeToCur()
700     // Erase characters from home to cursor
701     {
702 maya 3393 LONG TmpPtr;
703     int offset;
704     int i, YHome;
705 maya 3227
706 maya 3393 NewLine(PageStart+CursorY);
707 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
708 maya 3393 EraseKanji(0); /* if cursor is on left half of a kanji, erase the kanji */
709     }
710     offset = NumOfColumns;
711 doda 5324 if (isCursorOnStatusLine) {
712 maya 3393 YHome = CursorY;
713     }
714     else {
715     YHome = 0;
716     }
717     TmpPtr = GetLinePtr(PageStart+YHome);
718     for (i = YHome ; i <= CursorY ; i++) {
719     if (i==CursorY) {
720     offset = CursorX+1;
721     }
722     memset(&(CodeBuff[TmpPtr]),0x20,offset);
723     memset(&(AttrBuff[TmpPtr]),AttrDefault,offset);
724 doda 4070 memset(&(AttrBuff2[TmpPtr]),CurCharAttr.Attr2 & Attr2ColorMask, offset);
725 maya 3393 memset(&(AttrBuffFG[TmpPtr]),CurCharAttr.Fore,offset);
726     memset(&(AttrBuffBG[TmpPtr]),CurCharAttr.Back,offset);
727     TmpPtr = NextLinePtr(TmpPtr);
728     }
729 maya 3227
730 maya 3393 /* update window */
731     DispEraseHomeToCur(YHome);
732 maya 3227 }
733    
734     void BuffInsertLines(int Count, int YEnd)
735     // Insert lines at current position
736     // Count: number of lines to be inserted
737     // YEnd: bottom line number of scroll region (screen coordinate)
738     {
739 doda 5324 int i, linelen;
740 doda 5371 int extl=0, extr=0;
741 maya 3393 LONG SrcPtr, DestPtr;
742 maya 3227
743 maya 3393 BuffUpdateScroll();
744 maya 3227
745 doda 5371 if (CursorLeftM > 0)
746     extl = 1;
747     if (CursorRightM < NumOfColumns-1)
748     extr = 1;
749     if (extl || extr)
750     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
751    
752 doda 5324 SrcPtr = GetLinePtr(PageStart+YEnd-Count) + CursorLeftM;
753     DestPtr = GetLinePtr(PageStart+YEnd) + CursorLeftM;
754     linelen = CursorRightM - CursorLeftM + 1;
755 maya 3393 for (i= YEnd-Count ; i>=CursorY ; i--) {
756 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
757     memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
758     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
759     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
760     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
761 maya 3393 SrcPtr = PrevLinePtr(SrcPtr);
762     DestPtr = PrevLinePtr(DestPtr);
763     }
764     for (i = 1 ; i <= Count ; i++) {
765 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
766     memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
767     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
768     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
769     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
770 maya 3393 DestPtr = PrevLinePtr(DestPtr);
771     }
772 maya 3227
773 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || !DispInsertLines(Count, YEnd)) {
774 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
775 maya 3393 }
776 maya 3227 }
777    
778     void BuffEraseCharsInLine(int XStart, int Count)
779     // erase characters in the current line
780     // XStart: start position of erasing
781     // Count: number of characters to be erased
782     {
783 maya 3393 BOOL LineContinued=FALSE;
784 doda 3312
785 maya 3393 if (ts.EnableContinuedLineCopy && XStart == 0 && (AttrLine[0] & AttrLineContinued)) {
786     LineContinued = TRUE;
787     }
788 doda 3312
789 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
790 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
791     }
792 maya 3227
793 maya 3393 NewLine(PageStart+CursorY);
794     memset(&(CodeLine[XStart]),0x20,Count);
795     memset(&(AttrLine[XStart]),AttrDefault,Count);
796 doda 4070 memset(&(AttrLine2[XStart]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
797 maya 3393 memset(&(AttrLineFG[XStart]),CurCharAttr.Fore,Count);
798     memset(&(AttrLineBG[XStart]),CurCharAttr.Back,Count);
799 maya 3227
800 maya 3393 if (ts.EnableContinuedLineCopy) {
801     if (LineContinued) {
802     BuffLineContinued(TRUE);
803     }
804    
805     if (XStart + Count >= NumOfColumns) {
806     AttrBuff[NextLinePtr(LinePtr)] &= ~AttrLineContinued;
807     }
808     }
809 doda 3312
810 maya 3393 DispEraseCharsInLine(XStart, Count);
811 maya 3227 }
812    
813     void BuffDeleteLines(int Count, int YEnd)
814     // Delete lines from current line
815     // Count: number of lines to be deleted
816     // YEnd: bottom line number of scroll region (screen coordinate)
817     {
818 doda 5324 int i, linelen;
819 doda 5371 int extl=0, extr=0;
820 maya 3393 LONG SrcPtr, DestPtr;
821 maya 3227
822 maya 3393 BuffUpdateScroll();
823 maya 3227
824 doda 5371 if (CursorLeftM > 0)
825     extl = 1;
826     if (CursorRightM < NumOfColumns-1)
827     extr = 1;
828     if (extl || extr)
829     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
830    
831 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorY+Count) + (LONG)CursorLeftM;
832     DestPtr = GetLinePtr(PageStart+CursorY) + (LONG)CursorLeftM;
833     linelen = CursorRightM - CursorLeftM + 1;
834 maya 3393 for (i=CursorY ; i<= YEnd-Count ; i++) {
835 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
836     memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
837     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
838     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
839     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
840 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
841     DestPtr = NextLinePtr(DestPtr);
842     }
843     for (i = YEnd+1-Count ; i<=YEnd ; i++) {
844 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
845     memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
846     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
847     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
848     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
849 maya 3393 DestPtr = NextLinePtr(DestPtr);
850     }
851 maya 3227
852 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || ! DispDeleteLines(Count,YEnd)) {
853 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
854 maya 3393 }
855 maya 3227 }
856    
857     void BuffDeleteChars(int Count)
858     // Delete characters in current line from cursor
859     // Count: number of characters to be deleted
860     {
861 doda 5325 int MoveLen;
862 doda 5371 int extr=0;
863 doda 5325
864     if (CursorX < CursorLeftM || CursorX > CursorRightM)
865     return;
866    
867 maya 3393 NewLine(PageStart+CursorY);
868 maya 3227
869 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
870 maya 3393 EraseKanji(0); /* if cursor is on left harf of a kanji, erase the kanji */
871     EraseKanji(1); /* if cursor on right half... */
872     }
873 maya 3227
874 doda 5371 if (CursorRightM < NumOfColumns-1 && (AttrLine[CursorRightM] & AttrKanji)) {
875     CodeLine[CursorRightM] = 0x20;
876     AttrLine[CursorRightM] &= ~AttrKanji;
877     CodeLine[CursorRightM+1] = 0x20;
878     AttrLine[CursorRightM+1] &= ~AttrKanji;
879     extr = 1;
880     }
881    
882 doda 5325 if (Count > CursorRightM + 1 - CursorX)
883     Count = CursorRightM + 1 - CursorX;
884    
885     MoveLen = CursorRightM + 1 - CursorX - Count;
886    
887     if (MoveLen > 0) {
888     memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX+Count]), MoveLen);
889     memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX+Count]), MoveLen);
890     memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX+Count]), MoveLen);
891     memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX+Count]), MoveLen);
892     memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX+Count]), MoveLen);
893 maya 3393 }
894 doda 5325 memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count);
895     memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count);
896     memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
897     memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count);
898     memset(&(AttrLineBG[CursorX + MoveLen]), CurCharAttr.Back, Count);
899 maya 3227
900 doda 5371 BuffUpdateRect(CursorX, CursorY, CursorRightM+extr, CursorY);
901 maya 3227 }
902    
903     void BuffEraseChars(int Count)
904     // Erase characters in current line from cursor
905     // Count: number of characters to be deleted
906     {
907 maya 3393 NewLine(PageStart+CursorY);
908 maya 3227
909 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
910 maya 3393 EraseKanji(0); /* if cursor is on left harf of a kanji, erase the kanji */
911     EraseKanji(1); /* if cursor on right half... */
912     }
913 maya 3227
914 maya 3393 if (Count > NumOfColumns-CursorX) {
915     Count = NumOfColumns-CursorX;
916     }
917     memset(&(CodeLine[CursorX]),0x20,Count);
918     memset(&(AttrLine[CursorX]),AttrDefault,Count);
919 doda 4070 memset(&(AttrLine2[CursorX]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
920 maya 3393 memset(&(AttrLineFG[CursorX]),CurCharAttr.Fore,Count);
921     memset(&(AttrLineBG[CursorX]),CurCharAttr.Back,Count);
922 maya 3227
923 maya 3393 /* update window */
924     DispEraseCharsInLine(CursorX,Count);
925 maya 3227 }
926    
927     void BuffFillWithE()
928     // Fill screen with 'E' characters
929     {
930 maya 3393 LONG TmpPtr;
931     int i;
932 maya 3227
933 maya 3393 TmpPtr = GetLinePtr(PageStart);
934     for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) {
935     memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns);
936     memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns);
937     memset(&(AttrBuff2[TmpPtr]),AttrDefault,NumOfColumns);
938     memset(&(AttrBuffFG[TmpPtr]),AttrDefaultFG,NumOfColumns);
939     memset(&(AttrBuffBG[TmpPtr]),AttrDefaultBG,NumOfColumns);
940     TmpPtr = NextLinePtr(TmpPtr);
941     }
942     BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1);
943 maya 3227 }
944    
945     void BuffDrawLine(TCharAttr Attr, int Direction, int C)
946     { // IO-8256 terminal
947 maya 3393 LONG Ptr;
948     int i, X, Y;
949 maya 3227
950 maya 3393 if (C==0) {
951     return;
952     }
953     Attr.Attr |= AttrSpecial;
954 maya 3227
955 maya 3393 switch (Direction) {
956     case 3:
957     case 4:
958     if (Direction==3) {
959     if (CursorY==0) {
960     return;
961     }
962     Y = CursorY-1;
963     }
964     else {
965     if (CursorY==NumOfLines-1-StatusLine) {
966     return;
967     }
968     Y = CursorY+1;
969     }
970     if (CursorX+C > NumOfColumns) {
971     C = NumOfColumns-CursorX;
972     }
973     Ptr = GetLinePtr(PageStart+Y);
974     memset(&(CodeBuff[Ptr+CursorX]),'q',C);
975     memset(&(AttrBuff[Ptr+CursorX]),Attr.Attr,C);
976     memset(&(AttrBuff2[Ptr+CursorX]),Attr.Attr2,C);
977     memset(&(AttrBuffFG[Ptr+CursorX]),Attr.Fore,C);
978     memset(&(AttrBuffBG[Ptr+CursorX]),Attr.Back,C);
979     BuffUpdateRect(CursorX,Y,CursorX+C-1,Y);
980     break;
981     case 5:
982     case 6:
983     if (Direction==5) {
984     if (CursorX==0) {
985     return;
986     }
987     X = CursorX - 1;
988     }
989     else {
990     if (CursorX==NumOfColumns-1) {
991     X = CursorX-1;
992     }
993     else {
994     X = CursorX+1;
995     }
996     }
997     Ptr = GetLinePtr(PageStart+CursorY);
998     if (CursorY+C > NumOfLines-StatusLine) {
999     C = NumOfLines-StatusLine-CursorY;
1000     }
1001     for (i=1; i<=C; i++) {
1002     CodeBuff[Ptr+X] = 'x';
1003     AttrBuff[Ptr+X] = Attr.Attr;
1004     AttrBuff2[Ptr+X] = Attr.Attr2;
1005     AttrBuffFG[Ptr+X] = Attr.Fore;
1006     AttrBuffBG[Ptr+X] = Attr.Back;
1007     Ptr = NextLinePtr(Ptr);
1008     }
1009     BuffUpdateRect(X,CursorY,X,CursorY+C-1);
1010     break;
1011     }
1012 maya 3227 }
1013    
1014     void BuffEraseBox
1015     (int XStart, int YStart, int XEnd, int YEnd)
1016     {
1017 maya 3393 int C, i;
1018     LONG Ptr;
1019 maya 3227
1020 maya 3393 if (XEnd>NumOfColumns-1) {
1021     XEnd = NumOfColumns-1;
1022     }
1023     if (YEnd>NumOfLines-1-StatusLine) {
1024     YEnd = NumOfLines-1-StatusLine;
1025     }
1026     if (XStart>XEnd) {
1027     return;
1028     }
1029     if (YStart>YEnd) {
1030     return;
1031     }
1032     C = XEnd-XStart+1;
1033     Ptr = GetLinePtr(PageStart+YStart);
1034     for (i=YStart; i<=YEnd; i++) {
1035     if ((XStart>0) &&
1036     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
1037     CodeBuff[Ptr+XStart-1] = 0x20;
1038     AttrBuff[Ptr+XStart-1] = CurCharAttr.Attr;
1039     AttrBuff2[Ptr+XStart-1] = CurCharAttr.Attr2;
1040     AttrBuffFG[Ptr+XStart-1] = CurCharAttr.Fore;
1041     AttrBuffBG[Ptr+XStart-1] = CurCharAttr.Back;
1042     }
1043     if ((XStart+C<NumOfColumns) &&
1044     ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0)) {
1045     CodeBuff[Ptr+XStart+C] = 0x20;
1046     AttrBuff[Ptr+XStart+C] = CurCharAttr.Attr;
1047     AttrBuff2[Ptr+XStart+C] = CurCharAttr.Attr2;
1048     AttrBuffFG[Ptr+XStart+C] = CurCharAttr.Fore;
1049     AttrBuffBG[Ptr+XStart+C] = CurCharAttr.Back;
1050     }
1051     memset(&(CodeBuff[Ptr+XStart]),0x20,C);
1052     memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C);
1053 doda 4070 memset(&(AttrBuff2[Ptr+XStart]),CurCharAttr.Attr2 & Attr2ColorMask, C);
1054 maya 3393 memset(&(AttrBuffFG[Ptr+XStart]),CurCharAttr.Fore,C);
1055     memset(&(AttrBuffBG[Ptr+XStart]),CurCharAttr.Back,C);
1056     Ptr = NextLinePtr(Ptr);
1057     }
1058     BuffUpdateRect(XStart,YStart,XEnd,YEnd);
1059 maya 3227 }
1060    
1061 doda 5090 void BuffFillBox(char ch, int XStart, int YStart, int XEnd, int YEnd)
1062     {
1063     int Cols, i;
1064     LONG Ptr;
1065    
1066     if (XEnd>NumOfColumns-1) {
1067     XEnd = NumOfColumns-1;
1068     }
1069     if (YEnd>NumOfLines-1-StatusLine) {
1070     YEnd = NumOfLines-1-StatusLine;
1071     }
1072     if (XStart>XEnd) {
1073     return;
1074     }
1075     if (YStart>YEnd) {
1076     return;
1077     }
1078     Cols = XEnd-XStart+1;
1079     Ptr = GetLinePtr(PageStart+YStart);
1080     for (i=YStart; i<=YEnd; i++) {
1081     if ((XStart>0) &&
1082     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
1083     CodeBuff[Ptr+XStart-1] = 0x20;
1084     AttrBuff[Ptr+XStart-1] ^= AttrKanji;
1085     }
1086     if ((XStart+Cols<NumOfColumns) &&
1087     ((AttrBuff[Ptr+XStart+Cols-1] & AttrKanji) != 0)) {
1088     CodeBuff[Ptr+XStart+Cols] = 0x20;
1089     }
1090     memset(&(CodeBuff[Ptr+XStart]), ch, Cols);
1091     memset(&(AttrBuff[Ptr+XStart]), CurCharAttr.Attr, Cols);
1092 doda 5092 memset(&(AttrBuff2[Ptr+XStart]), CurCharAttr.Attr2, Cols);
1093 doda 5090 memset(&(AttrBuffFG[Ptr+XStart]), CurCharAttr.Fore, Cols);
1094     memset(&(AttrBuffBG[Ptr+XStart]), CurCharAttr.Back, Cols);
1095     Ptr = NextLinePtr(Ptr);
1096     }
1097     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1098     }
1099    
1100 doda 6174 //
1101     // TODO: 1 origin �������������� 0 origin ������
1102     //
1103 doda 5089 void BuffCopyBox(
1104     int SrcXStart, int SrcYStart, int SrcXEnd, int SrcYEnd, int SrcPage,
1105     int DstX, int DstY, int DstPage)
1106     {
1107     int i, C, L;
1108     LONG SPtr, DPtr;
1109    
1110     SrcXStart--;
1111     SrcYStart--;
1112     SrcXEnd--;
1113     SrcYEnd--;
1114     SrcPage--;
1115     DstX--;
1116     DstY--;
1117     DstPage--;
1118    
1119     if (SrcXEnd > NumOfColumns - 1) {
1120     SrcXEnd = NumOfColumns-1;
1121     }
1122     if (SrcYEnd > NumOfLines-1-StatusLine) {
1123     SrcYEnd = NumOfColumns-1;
1124     }
1125     if (SrcXStart > SrcXEnd ||
1126     SrcYStart > SrcYEnd ||
1127     DstX > NumOfColumns-1 ||
1128     DstY > NumOfLines-1-StatusLine) {
1129     return;
1130     }
1131    
1132     C = SrcXEnd - SrcXStart + 1;
1133     if (DstX + C > NumOfColumns) {
1134     C = NumOfColumns - DstX;
1135     }
1136     L = SrcYEnd - SrcYStart + 1;
1137     if (DstY + C > NumOfColumns) {
1138     C = NumOfColumns - DstX;
1139     }
1140    
1141     if (SrcXStart > DstX) {
1142     SPtr = GetLinePtr(PageStart+SrcYStart);
1143     DPtr = GetLinePtr(PageStart+DstY);
1144     for (i=0; i<L; i++) {
1145     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1146     memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1147     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1148     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1149     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1150     SPtr = NextLinePtr(SPtr);
1151     DPtr = NextLinePtr(DPtr);
1152     }
1153     }
1154     else if (SrcXStart < DstX) {
1155     SPtr = GetLinePtr(PageStart+SrcYEnd);
1156     DPtr = GetLinePtr(PageStart+DstY+L-1);
1157     for (i=L; i>0; i--) {
1158     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1159     memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1160     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1161     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1162     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1163     SPtr = PrevLinePtr(SPtr);
1164     DPtr = PrevLinePtr(DPtr);
1165     }
1166     }
1167     else if (SrcYStart != DstY) {
1168     SPtr = GetLinePtr(PageStart+SrcYStart);
1169     DPtr = GetLinePtr(PageStart+DstY);
1170     for (i=0; i<L; i++) {
1171     memmove(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1172     memmove(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1173     memmove(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1174     memmove(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1175     memmove(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1176     SPtr = NextLinePtr(SPtr);
1177     DPtr = NextLinePtr(DPtr);
1178     }
1179     }
1180     BuffUpdateRect(DstX,DstY,DstX+C-1,DstY+L-1);
1181     }
1182    
1183 doda 5095 void BuffChangeAttrBox(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1184     {
1185     int C, i, j;
1186     LONG Ptr;
1187    
1188     if (XEnd>NumOfColumns-1) {
1189     XEnd = NumOfColumns-1;
1190     }
1191     if (YEnd>NumOfLines-1-StatusLine) {
1192     YEnd = NumOfLines-1-StatusLine;
1193     }
1194     if (XStart>XEnd || YStart>YEnd) {
1195     return;
1196     }
1197     C = XEnd-XStart+1;
1198     Ptr = GetLinePtr(PageStart+YStart);
1199    
1200     if (mask) { // DECCARA
1201     for (i=YStart; i<=YEnd; i++) {
1202     j = Ptr+XStart-1;
1203     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1204     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1205     AttrBuff[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1206     AttrBuffFG[j] = attr->Fore;
1207     AttrBuffBG[j] = attr->Back;
1208     j++;
1209     }
1210     while (j < Ptr+XStart+C) {
1211     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1212     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1213     AttrBuffFG[j] = attr->Fore;
1214     AttrBuffBG[j] = attr->Back;
1215     j++;
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     AttrBuff[j++] ^= attr->Attr;
1231     }
1232     while (j < Ptr+XStart+C) {
1233     AttrBuff[j++] ^= attr->Attr;
1234     }
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+n ; i<=CursorBottom ; i++) {
2189 doda 5324 memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
2190