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

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