Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5325 - (hide annotations) (download) (as text)
Mon Jun 17 17:47:08 2013 UTC (10 years, 9 months ago) by doda
File MIME type: text/x-csrc
File size: 94508 byte(s)
DCH の 左右マージン対応

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