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 5326 - (hide annotations) (download) (as text)
Mon Jun 17 17:54:32 2013 UTC (10 years, 9 months ago) by doda
File MIME type: text/x-csrc
File size: 94524 byte(s)
左右マージン外では ICH で何も行わないようにした。(VT525の動作に合わせた)

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 5326 int MoveLen;
565 doda 5324
566 doda 5326 if (CursorX < CursorLeftM || CursorX > CursorRightM)
567     return;
568    
569 maya 3393 NewLine(PageStart+CursorY);
570 maya 3227
571 doda 5324 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8)
572 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
573 maya 3227
574 doda 5326 if (Count > CursorRightM + 1 - CursorX)
575     Count = CursorRightM + 1 - CursorX;
576 doda 5324
577 doda 5326 MoveLen = CursorRightM + 1 - CursorX - Count;
578 doda 5324
579     if (MoveLen > 0) {
580     memmove(&(CodeLine[CursorX+Count]), &(CodeLine[CursorX]), MoveLen);
581     memmove(&(AttrLine[CursorX+Count]), &(AttrLine[CursorX]), MoveLen);
582     memmove(&(AttrLine2[CursorX+Count]), &(AttrLine2[CursorX]), MoveLen);
583     memmove(&(AttrLineFG[CursorX+Count]), &(AttrLineFG[CursorX]), MoveLen);
584     memmove(&(AttrLineBG[CursorX+Count]), &(AttrLineBG[CursorX]), MoveLen);
585 maya 3393 }
586 doda 5324 memset(&(CodeLine[CursorX]), 0x20, Count);
587     memset(&(AttrLine[CursorX]), AttrDefault, Count);
588     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
589     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
590     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
591 maya 3393 /* last char in current line is kanji first? */
592 doda 5326 if ((AttrLine[CursorRightM] & AttrKanji) != 0) {
593 maya 3393 /* then delete it */
594 doda 5326 CodeLine[CursorRightM] = 0x20;
595     AttrLine[CursorRightM] = AttrDefault;
596     AttrLine2[CursorRightM] = CurCharAttr.Attr2;
597     AttrLineFG[CursorRightM] = CurCharAttr.Fore;
598     AttrLineBG[CursorRightM] = CurCharAttr.Back;
599 maya 3393 }
600 doda 5326 BuffUpdateRect(CursorX, CursorY, CursorRightM, CursorY);
601 maya 3227 }
602    
603     void BuffEraseCurToEnd()
604     // Erase characters from cursor to the end of screen
605     {
606 maya 3393 LONG TmpPtr;
607     int offset;
608     int i, YEnd;
609 maya 3227
610 maya 3393 NewLine(PageStart+CursorY);
611 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
612 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
613     }
614     offset = CursorX;
615     TmpPtr = GetLinePtr(PageStart+CursorY);
616     YEnd = NumOfLines-1;
617 doda 5324 if (StatusLine && !isCursorOnStatusLine) {
618 maya 3393 YEnd--;
619     }
620     for (i = CursorY ; i <= YEnd ; i++) {
621     memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset);
622     memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset);
623 doda 4070 memset(&(AttrBuff2[TmpPtr+offset]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset);
624 maya 3393 memset(&(AttrBuffFG[TmpPtr+offset]),CurCharAttr.Fore,NumOfColumns-offset);
625     memset(&(AttrBuffBG[TmpPtr+offset]),CurCharAttr.Back,NumOfColumns-offset);
626     offset = 0;
627     TmpPtr = NextLinePtr(TmpPtr);
628     }
629     /* update window */
630     DispEraseCurToEnd(YEnd);
631 maya 3227 }
632    
633     void BuffEraseHomeToCur()
634     // Erase characters from home to cursor
635     {
636 maya 3393 LONG TmpPtr;
637     int offset;
638     int i, YHome;
639 maya 3227
640 maya 3393 NewLine(PageStart+CursorY);
641 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
642 maya 3393 EraseKanji(0); /* if cursor is on left half of a kanji, erase the kanji */
643     }
644     offset = NumOfColumns;
645 doda 5324 if (isCursorOnStatusLine) {
646 maya 3393 YHome = CursorY;
647     }
648     else {
649     YHome = 0;
650     }
651     TmpPtr = GetLinePtr(PageStart+YHome);
652     for (i = YHome ; i <= CursorY ; i++) {
653     if (i==CursorY) {
654     offset = CursorX+1;
655     }
656     memset(&(CodeBuff[TmpPtr]),0x20,offset);
657     memset(&(AttrBuff[TmpPtr]),AttrDefault,offset);
658 doda 4070 memset(&(AttrBuff2[TmpPtr]),CurCharAttr.Attr2 & Attr2ColorMask, offset);
659 maya 3393 memset(&(AttrBuffFG[TmpPtr]),CurCharAttr.Fore,offset);
660     memset(&(AttrBuffBG[TmpPtr]),CurCharAttr.Back,offset);
661     TmpPtr = NextLinePtr(TmpPtr);
662     }
663 maya 3227
664 maya 3393 /* update window */
665     DispEraseHomeToCur(YHome);
666 maya 3227 }
667    
668     void BuffInsertLines(int Count, int YEnd)
669     // Insert lines at current position
670     // Count: number of lines to be inserted
671     // YEnd: bottom line number of scroll region (screen coordinate)
672     {
673 doda 5324 int i, linelen;
674 maya 3393 LONG SrcPtr, DestPtr;
675 maya 3227
676 maya 3393 BuffUpdateScroll();
677 maya 3227
678 doda 5324 SrcPtr = GetLinePtr(PageStart+YEnd-Count) + CursorLeftM;
679     DestPtr = GetLinePtr(PageStart+YEnd) + CursorLeftM;
680     linelen = CursorRightM - CursorLeftM + 1;
681 maya 3393 for (i= YEnd-Count ; i>=CursorY ; i--) {
682 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
683     memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
684     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
685     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
686     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
687 maya 3393 SrcPtr = PrevLinePtr(SrcPtr);
688     DestPtr = PrevLinePtr(DestPtr);
689     }
690     for (i = 1 ; i <= Count ; i++) {
691 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
692     memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
693     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
694     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
695     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
696 maya 3393 DestPtr = PrevLinePtr(DestPtr);
697     }
698 maya 3227
699 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || !DispInsertLines(Count, YEnd)) {
700     BuffUpdateRect(CursorLeftM, CursorY, CursorRightM, YEnd);
701 maya 3393 }
702 maya 3227 }
703    
704     void BuffEraseCharsInLine(int XStart, int Count)
705     // erase characters in the current line
706     // XStart: start position of erasing
707     // Count: number of characters to be erased
708     {
709 doda 3312 #ifndef NO_COPYLINE_FIX
710 maya 3393 BOOL LineContinued=FALSE;
711 doda 3312
712 maya 3393 if (ts.EnableContinuedLineCopy && XStart == 0 && (AttrLine[0] & AttrLineContinued)) {
713     LineContinued = TRUE;
714     }
715 doda 3312 #endif /* NO_COPYLINE_FIX */
716    
717 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
718 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
719     }
720 maya 3227
721 maya 3393 NewLine(PageStart+CursorY);
722     memset(&(CodeLine[XStart]),0x20,Count);
723     memset(&(AttrLine[XStart]),AttrDefault,Count);
724 doda 4070 memset(&(AttrLine2[XStart]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
725 maya 3393 memset(&(AttrLineFG[XStart]),CurCharAttr.Fore,Count);
726     memset(&(AttrLineBG[XStart]),CurCharAttr.Back,Count);
727 maya 3227
728 doda 3312 #ifndef NO_COPYLINE_FIX
729 maya 3393 if (ts.EnableContinuedLineCopy) {
730     if (LineContinued) {
731     BuffLineContinued(TRUE);
732     }
733    
734     if (XStart + Count >= NumOfColumns) {
735     AttrBuff[NextLinePtr(LinePtr)] &= ~AttrLineContinued;
736     }
737     }
738 doda 3312 #endif /* NO_COPYLINE_FIX */
739    
740 maya 3393 DispEraseCharsInLine(XStart, Count);
741 maya 3227 }
742    
743     void BuffDeleteLines(int Count, int YEnd)
744     // Delete lines from current line
745     // Count: number of lines to be deleted
746     // YEnd: bottom line number of scroll region (screen coordinate)
747     {
748 doda 5324 int i, linelen;
749 maya 3393 LONG SrcPtr, DestPtr;
750 maya 3227
751 maya 3393 BuffUpdateScroll();
752 maya 3227
753 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorY+Count) + (LONG)CursorLeftM;
754     DestPtr = GetLinePtr(PageStart+CursorY) + (LONG)CursorLeftM;
755     linelen = CursorRightM - CursorLeftM + 1;
756 maya 3393 for (i=CursorY ; i<= YEnd-Count ; i++) {
757 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
758     memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
759     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
760     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
761     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
762 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
763     DestPtr = NextLinePtr(DestPtr);
764     }
765     for (i = YEnd+1-Count ; i<=YEnd ; i++) {
766 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
767     memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
768     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
769     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
770     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
771 maya 3393 DestPtr = NextLinePtr(DestPtr);
772     }
773 maya 3227
774 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || ! DispDeleteLines(Count,YEnd)) {
775     BuffUpdateRect(CursorLeftM, CursorY, CursorRightM, YEnd);
776 maya 3393 }
777 maya 3227 }
778    
779     void BuffDeleteChars(int Count)
780     // Delete characters in current line from cursor
781     // Count: number of characters to be deleted
782     {
783 doda 5325 int MoveLen;
784    
785     if (CursorX < CursorLeftM || CursorX > CursorRightM)
786     return;
787    
788 maya 3393 NewLine(PageStart+CursorY);
789 maya 3227
790 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
791 maya 3393 EraseKanji(0); /* if cursor is on left harf of a kanji, erase the kanji */
792     EraseKanji(1); /* if cursor on right half... */
793     }
794 maya 3227
795 doda 5325 if (Count > CursorRightM + 1 - CursorX)
796     Count = CursorRightM + 1 - CursorX;
797    
798     MoveLen = CursorRightM + 1 - CursorX - Count;
799    
800     if (MoveLen > 0) {
801     memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX+Count]), MoveLen);
802     memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX+Count]), MoveLen);
803     memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX+Count]), MoveLen);
804     memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX+Count]), MoveLen);
805     memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX+Count]), MoveLen);
806 maya 3393 }
807 doda 5325 memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count);
808     memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count);
809     memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
810     memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count);
811     memset(&(AttrLineBG[CursorX + MoveLen]), CurCharAttr.Back, Count);
812 maya 3227
813 doda 5325 BuffUpdateRect(CursorX, CursorY, CursorRightM, CursorY);
814 maya 3227 }
815    
816     void BuffEraseChars(int Count)
817     // Erase characters in current line from cursor
818     // Count: number of characters to be deleted
819     {
820 maya 3393 NewLine(PageStart+CursorY);
821 maya 3227
822 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
823 maya 3393 EraseKanji(0); /* if cursor is on left harf of a kanji, erase the kanji */
824     EraseKanji(1); /* if cursor on right half... */
825     }
826 maya 3227
827 maya 3393 if (Count > NumOfColumns-CursorX) {
828     Count = NumOfColumns-CursorX;
829     }
830     memset(&(CodeLine[CursorX]),0x20,Count);
831     memset(&(AttrLine[CursorX]),AttrDefault,Count);
832 doda 4070 memset(&(AttrLine2[CursorX]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
833 maya 3393 memset(&(AttrLineFG[CursorX]),CurCharAttr.Fore,Count);
834     memset(&(AttrLineBG[CursorX]),CurCharAttr.Back,Count);
835 maya 3227
836 maya 3393 /* update window */
837     DispEraseCharsInLine(CursorX,Count);
838 maya 3227 }
839    
840     void BuffFillWithE()
841     // Fill screen with 'E' characters
842     {
843 maya 3393 LONG TmpPtr;
844     int i;
845 maya 3227
846 maya 3393 TmpPtr = GetLinePtr(PageStart);
847     for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) {
848     memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns);
849     memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns);
850     memset(&(AttrBuff2[TmpPtr]),AttrDefault,NumOfColumns);
851     memset(&(AttrBuffFG[TmpPtr]),AttrDefaultFG,NumOfColumns);
852     memset(&(AttrBuffBG[TmpPtr]),AttrDefaultBG,NumOfColumns);
853     TmpPtr = NextLinePtr(TmpPtr);
854     }
855     BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1);
856 maya 3227 }
857    
858     void BuffDrawLine(TCharAttr Attr, int Direction, int C)
859     { // IO-8256 terminal
860 maya 3393 LONG Ptr;
861     int i, X, Y;
862 maya 3227
863 maya 3393 if (C==0) {
864     return;
865     }
866     Attr.Attr |= AttrSpecial;
867 maya 3227
868 maya 3393 switch (Direction) {
869     case 3:
870     case 4:
871     if (Direction==3) {
872     if (CursorY==0) {
873     return;
874     }
875     Y = CursorY-1;
876     }
877     else {
878     if (CursorY==NumOfLines-1-StatusLine) {
879     return;
880     }
881     Y = CursorY+1;
882     }
883     if (CursorX+C > NumOfColumns) {
884     C = NumOfColumns-CursorX;
885     }
886     Ptr = GetLinePtr(PageStart+Y);
887     memset(&(CodeBuff[Ptr+CursorX]),'q',C);
888     memset(&(AttrBuff[Ptr+CursorX]),Attr.Attr,C);
889     memset(&(AttrBuff2[Ptr+CursorX]),Attr.Attr2,C);
890     memset(&(AttrBuffFG[Ptr+CursorX]),Attr.Fore,C);
891     memset(&(AttrBuffBG[Ptr+CursorX]),Attr.Back,C);
892     BuffUpdateRect(CursorX,Y,CursorX+C-1,Y);
893     break;
894     case 5:
895     case 6:
896     if (Direction==5) {
897     if (CursorX==0) {
898     return;
899     }
900     X = CursorX - 1;
901     }
902     else {
903     if (CursorX==NumOfColumns-1) {
904     X = CursorX-1;
905     }
906     else {
907     X = CursorX+1;
908     }
909     }
910     Ptr = GetLinePtr(PageStart+CursorY);
911     if (CursorY+C > NumOfLines-StatusLine) {
912     C = NumOfLines-StatusLine-CursorY;
913     }
914     for (i=1; i<=C; i++) {
915     CodeBuff[Ptr+X] = 'x';
916     AttrBuff[Ptr+X] = Attr.Attr;
917     AttrBuff2[Ptr+X] = Attr.Attr2;
918     AttrBuffFG[Ptr+X] = Attr.Fore;
919     AttrBuffBG[Ptr+X] = Attr.Back;
920     Ptr = NextLinePtr(Ptr);
921     }
922     BuffUpdateRect(X,CursorY,X,CursorY+C-1);
923     break;
924     }
925 maya 3227 }
926    
927     void BuffEraseBox
928     (int XStart, int YStart, int XEnd, int YEnd)
929     {
930 maya 3393 int C, i;
931     LONG Ptr;
932 maya 3227
933 maya 3393 if (XEnd>NumOfColumns-1) {
934     XEnd = NumOfColumns-1;
935     }
936     if (YEnd>NumOfLines-1-StatusLine) {
937     YEnd = NumOfLines-1-StatusLine;
938     }
939     if (XStart>XEnd) {
940     return;
941     }
942     if (YStart>YEnd) {
943     return;
944     }
945     C = XEnd-XStart+1;
946     Ptr = GetLinePtr(PageStart+YStart);
947     for (i=YStart; i<=YEnd; i++) {
948     if ((XStart>0) &&
949     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
950     CodeBuff[Ptr+XStart-1] = 0x20;
951     AttrBuff[Ptr+XStart-1] = CurCharAttr.Attr;
952     AttrBuff2[Ptr+XStart-1] = CurCharAttr.Attr2;
953     AttrBuffFG[Ptr+XStart-1] = CurCharAttr.Fore;
954     AttrBuffBG[Ptr+XStart-1] = CurCharAttr.Back;
955     }
956     if ((XStart+C<NumOfColumns) &&
957     ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0)) {
958     CodeBuff[Ptr+XStart+C] = 0x20;
959     AttrBuff[Ptr+XStart+C] = CurCharAttr.Attr;
960     AttrBuff2[Ptr+XStart+C] = CurCharAttr.Attr2;
961     AttrBuffFG[Ptr+XStart+C] = CurCharAttr.Fore;
962     AttrBuffBG[Ptr+XStart+C] = CurCharAttr.Back;
963     }
964     memset(&(CodeBuff[Ptr+XStart]),0x20,C);
965     memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C);
966 doda 4070 memset(&(AttrBuff2[Ptr+XStart]),CurCharAttr.Attr2 & Attr2ColorMask, C);
967 maya 3393 memset(&(AttrBuffFG[Ptr+XStart]),CurCharAttr.Fore,C);
968     memset(&(AttrBuffBG[Ptr+XStart]),CurCharAttr.Back,C);
969     Ptr = NextLinePtr(Ptr);
970     }
971     BuffUpdateRect(XStart,YStart,XEnd,YEnd);
972 maya 3227 }
973    
974 doda 5090 void BuffFillBox(char ch, int XStart, int YStart, int XEnd, int YEnd)
975     {
976     int Cols, i;
977     LONG Ptr;
978    
979     if (XEnd>NumOfColumns-1) {
980     XEnd = NumOfColumns-1;
981     }
982     if (YEnd>NumOfLines-1-StatusLine) {
983     YEnd = NumOfLines-1-StatusLine;
984     }
985     if (XStart>XEnd) {
986     return;
987     }
988     if (YStart>YEnd) {
989     return;
990     }
991     Cols = XEnd-XStart+1;
992     Ptr = GetLinePtr(PageStart+YStart);
993     for (i=YStart; i<=YEnd; i++) {
994     if ((XStart>0) &&
995     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
996     CodeBuff[Ptr+XStart-1] = 0x20;
997     AttrBuff[Ptr+XStart-1] ^= AttrKanji;
998     }
999     if ((XStart+Cols<NumOfColumns) &&
1000     ((AttrBuff[Ptr+XStart+Cols-1] & AttrKanji) != 0)) {
1001     CodeBuff[Ptr+XStart+Cols] = 0x20;
1002     }
1003     memset(&(CodeBuff[Ptr+XStart]), ch, Cols);
1004     memset(&(AttrBuff[Ptr+XStart]), CurCharAttr.Attr, Cols);
1005 doda 5092 memset(&(AttrBuff2[Ptr+XStart]), CurCharAttr.Attr2, Cols);
1006 doda 5090 memset(&(AttrBuffFG[Ptr+XStart]), CurCharAttr.Fore, Cols);
1007     memset(&(AttrBuffBG[Ptr+XStart]), CurCharAttr.Back, Cols);
1008     Ptr = NextLinePtr(Ptr);
1009     }
1010     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1011     }
1012    
1013 doda 5089 void BuffCopyBox(
1014     int SrcXStart, int SrcYStart, int SrcXEnd, int SrcYEnd, int SrcPage,
1015     int DstX, int DstY, int DstPage)
1016     {
1017     int i, C, L;
1018     LONG SPtr, DPtr;
1019    
1020     SrcXStart--;
1021     SrcYStart--;
1022     SrcXEnd--;
1023     SrcYEnd--;
1024     SrcPage--;
1025     DstX--;
1026     DstY--;
1027     DstPage--;
1028    
1029     if (SrcXEnd > NumOfColumns - 1) {
1030     SrcXEnd = NumOfColumns-1;
1031     }
1032     if (SrcYEnd > NumOfLines-1-StatusLine) {
1033     SrcYEnd = NumOfColumns-1;
1034     }
1035     if (SrcXStart > SrcXEnd ||
1036     SrcYStart > SrcYEnd ||
1037     DstX > NumOfColumns-1 ||
1038     DstY > NumOfLines-1-StatusLine) {
1039     return;
1040     }
1041    
1042     C = SrcXEnd - SrcXStart + 1;
1043     if (DstX + C > NumOfColumns) {
1044     C = NumOfColumns - DstX;
1045     }
1046     L = SrcYEnd - SrcYStart + 1;
1047     if (DstY + C > NumOfColumns) {
1048     C = NumOfColumns - DstX;
1049     }
1050    
1051     if (SrcXStart > DstX) {
1052     SPtr = GetLinePtr(PageStart+SrcYStart);
1053     DPtr = GetLinePtr(PageStart+DstY);
1054     for (i=0; i<L; i++) {
1055     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1056     memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1057     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1058     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1059     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1060     SPtr = NextLinePtr(SPtr);
1061     DPtr = NextLinePtr(DPtr);
1062     }
1063     }
1064     else if (SrcXStart < DstX) {
1065     SPtr = GetLinePtr(PageStart+SrcYEnd);
1066     DPtr = GetLinePtr(PageStart+DstY+L-1);
1067     for (i=L; i>0; i--) {
1068     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1069     memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1070     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1071     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1072     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1073     SPtr = PrevLinePtr(SPtr);
1074     DPtr = PrevLinePtr(DPtr);
1075     }
1076     }
1077     else if (SrcYStart != DstY) {
1078     SPtr = GetLinePtr(PageStart+SrcYStart);
1079     DPtr = GetLinePtr(PageStart+DstY);
1080     for (i=0; i<L; i++) {
1081     memmove(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1082     memmove(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1083     memmove(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1084     memmove(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1085     memmove(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1086     SPtr = NextLinePtr(SPtr);
1087     DPtr = NextLinePtr(DPtr);
1088     }
1089     }
1090     BuffUpdateRect(DstX,DstY,DstX+C-1,DstY+L-1);
1091     }
1092    
1093 doda 5095 void BuffChangeAttrBox(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1094     {
1095     int C, i, j;
1096     LONG Ptr;
1097    
1098     if (XEnd>NumOfColumns-1) {
1099     XEnd = NumOfColumns-1;
1100     }
1101     if (YEnd>NumOfLines-1-StatusLine) {
1102     YEnd = NumOfLines-1-StatusLine;
1103     }
1104     if (XStart>XEnd || YStart>YEnd) {
1105     return;
1106     }
1107     C = XEnd-XStart+1;
1108     Ptr = GetLinePtr(PageStart+YStart);
1109    
1110     if (mask) { // DECCARA
1111     for (i=YStart; i<=YEnd; i++) {
1112     j = Ptr+XStart-1;
1113     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1114     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1115     AttrBuff[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1116     AttrBuffFG[j] = attr->Fore;
1117     AttrBuffBG[j] = attr->Back;
1118     j++;
1119     }
1120     while (j < Ptr+XStart+C) {
1121     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1122     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1123     AttrBuffFG[j] = attr->Fore;
1124     AttrBuffBG[j] = attr->Back;
1125     j++;
1126     }
1127     if (XStart+C<NumOfColumns && (AttrBuff[j-1] & AttrKanji)) {
1128     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1129     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1130     AttrBuffFG[j] = attr->Fore;
1131     AttrBuffBG[j] = attr->Back;
1132     }
1133     Ptr = NextLinePtr(Ptr);
1134     }
1135     }
1136     else { // DECRARA
1137     for (i=YStart; i<=YEnd; i++) {
1138     j = Ptr+XStart-1;
1139     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1140     AttrBuff[j++] ^= attr->Attr;
1141     }
1142     while (j < Ptr+XStart+C) {
1143     AttrBuff[j++] ^= attr->Attr;
1144     }
1145     if (XStart+C<NumOfColumns && (AttrBuff[j-1] & AttrKanji)) {
1146     AttrBuff[j] ^= attr->Attr;
1147     }
1148     Ptr = NextLinePtr(Ptr);
1149     }
1150     }
1151     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1152     }
1153    
1154 maya 3227 int LeftHalfOfDBCS(LONG Line, int CharPtr)
1155     // If CharPtr is on the right half of a DBCS character,
1156     // return pointer to the left half
1157     // Line: points to a line in CodeBuff
1158     // CharPtr: points to a char
1159     // return: points to the left half of the DBCS
1160     {
1161 maya 3393 if ((CharPtr>0) &&
1162     ((AttrBuff[Line+CharPtr-1] & AttrKanji) != 0)) {
1163     CharPtr--;
1164     }
1165     return CharPtr;
1166 maya 3227 }
1167    
1168     int MoveCharPtr(LONG Line, int *x, int dx)
1169     // move character pointer x by dx character unit
1170     // in the line specified by Line
1171     // Line: points to a line in CodeBuff
1172     // x: points to a character in the line
1173     // dx: moving distance in character unit (-: left, +: right)
1174 maya 3393 // One DBCS character is counted as one character.
1175 maya 3227 // The pointer stops at the beginning or the end of line.
1176     // Output
1177     // x: new pointer. x points to a SBCS character or
1178     // the left half of a DBCS character.
1179     // return: actual moving distance in character unit
1180     {
1181 maya 3393 int i;
1182 maya 3227
1183 maya 3393 *x = LeftHalfOfDBCS(Line,*x);
1184     i = 0;
1185     while (dx!=0) {
1186     if (dx>0) { // move right
1187     if ((AttrBuff[Line+*x] & AttrKanji) != 0) {
1188     if (*x<NumOfColumns-2) {
1189     i++;
1190     *x = *x + 2;
1191     }
1192     }
1193     else if (*x<NumOfColumns-1) {
1194     i++;
1195     (*x)++;
1196     }
1197     dx--;
1198     }
1199     else { // move left
1200     if (*x>0) {
1201     i--;
1202     (*x)--;
1203     }
1204     *x = LeftHalfOfDBCS(Line,*x);
1205     dx++;
1206     }
1207 maya 3227 }
1208 maya 3393 return i;
1209 maya 3227 }
1210    
1211     void BuffCBCopy(BOOL Table)
1212     // copy selected text to clipboard
1213     {
1214 maya 3393 LONG MemSize;
1215     PCHAR CBPtr;
1216     LONG TmpPtr;
1217     int i, j, k, IStart, IEnd;
1218     BOOL Sp, FirstChar;
1219     BYTE b;
1220 maya 3227 #ifndef NO_COPYLINE_FIX
1221 maya 3393 BOOL LineContinued, PrevLineContinued;
1222     LineContinued = FALSE;
1223 maya 3227 #endif /* NO_COPYLINE_FIX */
1224    
1225 maya 3393 if (TalkStatus==IdTalkCB) {
1226     return;
1227     }
1228     if (! Selected) {
1229     return;
1230     }
1231 maya 3227
1232     // --- open clipboard and get CB memory
1233 maya 3393 if (BoxSelect) {
1234     MemSize = (SelectEnd.x-SelectStart.x+3)*
1235     (SelectEnd.y-SelectStart.y+1) + 1;
1236     }
1237     else {
1238     MemSize = (SelectEnd.y-SelectStart.y)*
1239     (NumOfColumns+2) +
1240     SelectEnd.x - SelectStart.x + 1;
1241     }
1242     CBPtr = CBOpen(MemSize);
1243     if (CBPtr==NULL) {
1244     return;
1245     }
1246 maya 3227
1247     // --- copy selected text to CB memory
1248 maya 3393 LockBuffer();
1249 maya 3227
1250 maya 3393 CBPtr[0] = 0;
1251     TmpPtr = GetLinePtr(SelectStart.y);
1252     k = 0;
1253     for (j = SelectStart.y ; j<=SelectEnd.y ; j++) {
1254     if (BoxSelect) {
1255     IStart = SelectStart.x;
1256     IEnd = SelectEnd.x-1;
1257     }
1258     else {
1259     IStart = 0;
1260     IEnd = NumOfColumns-1;
1261     if (j==SelectStart.y) {
1262     IStart = SelectStart.x;
1263     }
1264     if (j==SelectEnd.y) {
1265     IEnd = SelectEnd.x-1;
1266     }
1267     }
1268     i = LeftHalfOfDBCS(TmpPtr,IStart);
1269     if (i!=IStart) {
1270     if (j==SelectStart.y) {
1271     IStart = i;
1272     }
1273     else {
1274     IStart = i + 2;
1275     }
1276     }
1277 maya 3227
1278 maya 3393 // exclude right-side space characters
1279     IEnd = LeftHalfOfDBCS(TmpPtr,IEnd);
1280 maya 3227 #ifndef NO_COPYLINE_FIX
1281 maya 3393 PrevLineContinued = LineContinued;
1282     LineContinued = FALSE;
1283     if (ts.EnableContinuedLineCopy && j!=SelectEnd.y && !BoxSelect) {
1284     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1285     if ((AttrBuff[NextTmpPtr] & AttrLineContinued) != 0) {
1286     LineContinued = TRUE;
1287     }
1288     if (IEnd == NumOfColumns-1 &&
1289     (AttrBuff[TmpPtr + IEnd] & AttrLineContinued) != 0) {
1290     MoveCharPtr(TmpPtr,&IEnd,-1);
1291     }
1292     }
1293     if (!LineContinued)
1294 maya 3227 #endif /* NO_COPYLINE_FIX */
1295 maya 3393 while ((IEnd>0) && (CodeBuff[TmpPtr+IEnd]==0x20)) {
1296     MoveCharPtr(TmpPtr,&IEnd,-1);
1297     }
1298     if ((IEnd==0) && (CodeBuff[TmpPtr]==0x20)) {
1299     IEnd = -1;
1300     }
1301     else if ((AttrBuff[TmpPtr+IEnd] & AttrKanji) != 0) { /* DBCS first byte? */
1302     IEnd++;
1303     }
1304 maya 3227
1305 maya 3393 Sp = FALSE;
1306     FirstChar = TRUE;
1307     i = IStart;
1308     while (i <= IEnd) {
1309     b = CodeBuff[TmpPtr+i];
1310     i++;
1311     if (! Sp) {
1312     if ((Table) && (b<=0x20)) {
1313     Sp = TRUE;
1314     b = 0x09;
1315     }
1316 maya 3227 #ifndef NO_COPYLINE_FIX
1317 maya 3393 if ((b!=0x09) || (! FirstChar) || PrevLineContinued) {
1318 maya 3227 #else
1319 maya 3393 if ((b!=0x09) || (! FirstChar)) {
1320 maya 3227 #endif
1321 maya 3393 FirstChar = FALSE;
1322     CBPtr[k] = b;
1323     k++;
1324     }
1325     }
1326     else {
1327     if (b>0x20) {
1328     Sp = FALSE;
1329     FirstChar = FALSE;
1330     CBPtr[k] = b;
1331     k++;
1332     }
1333     }
1334     }
1335 maya 3227
1336     #ifndef NO_COPYLINE_FIX
1337 maya 3393 if (!LineContinued)
1338 maya 3227 #endif /* NO_COPYLINE_FIX */
1339 maya 3393 if (j < SelectEnd.y) {
1340     CBPtr[k] = 0x0d;
1341     k++;
1342     CBPtr[k] = 0x0a;
1343     k++;
1344     }
1345 maya 3227
1346 maya 3393 TmpPtr = NextLinePtr(TmpPtr);
1347     }
1348     CBPtr[k] = 0;
1349 maya 3227 #ifndef NO_COPYLINE_FIX
1350 maya 3393 LineContinued = FALSE;
1351     if (ts.EnableContinuedLineCopy && j!=SelectEnd.y && !BoxSelect && j<BuffEnd-1) {
1352     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1353     if ((AttrBuff[NextTmpPtr] & AttrLineContinued) != 0) {
1354     LineContinued = TRUE;
1355     }
1356     if (IEnd == NumOfColumns-1 &&
1357     (AttrBuff[TmpPtr + IEnd] & AttrLineContinued) != 0) {
1358     MoveCharPtr(TmpPtr,&IEnd,-1);
1359     }
1360     }
1361     if (!LineContinued)
1362 maya 3227 #endif /* NO_COPYLINE_FIX */
1363 maya 3393 UnlockBuffer();
1364 maya 3227
1365     // --- send CB memory to clipboard
1366 maya 3393 CBClose();
1367     return;
1368 maya 3227 }
1369    
1370     void BuffPrint(BOOL ScrollRegion)
1371     // Print screen or selected text
1372     {
1373 maya 3393 int Id;
1374     POINT PrintStart, PrintEnd;
1375     TCharAttr CurAttr, TempAttr;
1376     int i, j, count;
1377     int IStart, IEnd;
1378     LONG TmpPtr;
1379 maya 3227
1380 maya 3393 TempAttr = DefCharAttr;
1381 maya 3227
1382 maya 3393 if (ScrollRegion) {
1383     Id = VTPrintInit(IdPrnScrollRegion);
1384     }
1385     else if (Selected) {
1386     Id = VTPrintInit(IdPrnScreen | IdPrnSelectedText);
1387     }
1388     else {
1389     Id = VTPrintInit(IdPrnScreen);
1390     }
1391     if (Id==IdPrnCancel) {
1392     return;
1393     }
1394 maya 3227
1395 maya 3393 /* set print region */
1396     if (Id==IdPrnSelectedText) {
1397     /* print selected region */
1398     PrintStart = SelectStart;
1399     PrintEnd = SelectEnd;
1400     }
1401     else if (Id==IdPrnScrollRegion) {
1402     /* print scroll region */
1403     PrintStart.x = 0;
1404     PrintStart.y = PageStart + CursorTop;
1405     PrintEnd.x = NumOfColumns;
1406     PrintEnd.y = PageStart + CursorBottom;
1407     }
1408     else {
1409     /* print current screen */
1410     PrintStart.x = 0;
1411     PrintStart.y = PageStart;
1412     PrintEnd.x = NumOfColumns;
1413     PrintEnd.y = PageStart + NumOfLines - 1;
1414     }
1415     if (PrintEnd.y > BuffEnd-1) {
1416     PrintEnd.y = BuffEnd-1;
1417     }
1418 maya 3227
1419 maya 3393 LockBuffer();
1420 maya 3227
1421 maya 3393 TmpPtr = GetLinePtr(PrintStart.y);
1422     for (j = PrintStart.y ; j <= PrintEnd.y ; j++) {
1423     if (j==PrintStart.y) {
1424     IStart = PrintStart.x;
1425     }
1426     else {
1427     IStart = 0;
1428     }
1429     if (j == PrintEnd.y) {
1430     IEnd = PrintEnd.x - 1;
1431     }
1432     else {
1433     IEnd = NumOfColumns - 1;
1434     }
1435 maya 3227
1436 maya 3393 while ((IEnd>=IStart) &&
1437     (CodeBuff[TmpPtr+IEnd]==0x20) &&
1438     (AttrBuff[TmpPtr+IEnd]==AttrDefault) &&
1439     (AttrBuff2[TmpPtr+IEnd]==AttrDefault)) {
1440     IEnd--;
1441     }
1442 maya 3227
1443 maya 3393 i = IStart;
1444     while (i <= IEnd) {
1445     CurAttr.Attr = AttrBuff[TmpPtr+i] & ~ AttrKanji;
1446     CurAttr.Attr2 = AttrBuff2[TmpPtr+i];
1447     CurAttr.Fore = AttrBuffFG[TmpPtr+i];
1448     CurAttr.Back = AttrBuffBG[TmpPtr+i];
1449 maya 3227
1450 maya 3393 count = 1;
1451     while ((i+count <= IEnd) &&
1452     (CurAttr.Attr == (AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
1453     (CurAttr.Attr2 == AttrBuff2[TmpPtr+i+count]) &&
1454     (CurAttr.Fore == AttrBuffFG[TmpPtr+i+count]) &&
1455     (CurAttr.Back == AttrBuffBG[TmpPtr+i+count]) ||
1456     (i+count<NumOfColumns) &&
1457     ((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0)) {
1458     count++;
1459     }
1460 maya 3227
1461 maya 3393 if (TCharAttrCmp(CurAttr, TempAttr) != 0) {
1462     PrnSetAttr(CurAttr);
1463     TempAttr = CurAttr;
1464     }
1465     PrnOutText(&(CodeBuff[TmpPtr+i]),count);
1466     i = i+count;
1467     }
1468     PrnNewLine();
1469     TmpPtr = NextLinePtr(TmpPtr);
1470     }
1471 maya 3227
1472 maya 3393 UnlockBuffer();
1473     VTPrintEnd();
1474 maya 3227 }
1475    
1476     void BuffDumpCurrentLine(BYTE TERM)
1477     // Dumps current line to the file (for path through printing)
1478     // HFile: file handle
1479     // TERM: terminator character
1480     // = LF or VT or FF
1481     {
1482 maya 3393 int i, j;
1483 maya 3227
1484 maya 3393 i = NumOfColumns;
1485     while ((i>0) && (CodeLine[i-1]==0x20)) {
1486     i--;
1487     }
1488     for (j=0; j<i; j++) {
1489     WriteToPrnFile(CodeLine[j],FALSE);
1490     }
1491     WriteToPrnFile(0,TRUE);
1492     if ((TERM>=LF) && (TERM<=FF)) {
1493     WriteToPrnFile(0x0d,FALSE);
1494     WriteToPrnFile(TERM,TRUE);
1495     }
1496 maya 3227 }
1497    
1498    
1499     /* begin - ishizaki */
1500     static void markURL(int x)
1501     {
1502     #ifdef URL_EMPHASIS
1503 doda 5278 CHAR PrevCharAttr;
1504    
1505 yutakapon 3414 // RFC3986(Uniform Resource Identifier (URI): Generic Syntax)に準拠する
1506 maya 3227 // by sakura editor 1.5.2.1: etc_uty.cpp
1507     static const char url_char[] = {
1508     /* +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F */
1509     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* +00: */
1510     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* +10: */
1511     0, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, /* +20: " !"#$%&'()*+,-./" */
1512     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, /* +30: "0123456789:;<=>?" */
1513     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* +40: "@ABCDEFGHIJKLMNO" */
1514     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1, /* +50: "PQRSTUVWXYZ[\]^_" */
1515     0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* +60: "`abcdefghijklmno" */
1516 yutakapon 3414 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, /* +70: "pqrstuvwxyz{|}~ " */
1517 maya 3227 /* 0 : not url char
1518     * -1 : url char
1519     * other: url head char --> url_table array number + 1
1520     */
1521     };
1522 yutakapon 3614 static char *prefix[] = {
1523     "https://",
1524     "http://",
1525     "sftp://",
1526     "tftp://",
1527     "news://",
1528     "ftp://",
1529     "mms://",
1530     NULL
1531     };
1532 maya 3227 unsigned char ch = CodeLine[x];
1533    
1534 yutakapon 3615 if (ts.EnableClickableUrl == FALSE &&
1535     (ts.ColorFlag & CF_URLCOLOR) == 0)
1536 maya 3227 return;
1537    
1538     // 直前の行から連結しているか。
1539     // TODO: 1つ前の行の終端文字が URL の一部なら、強制的に現在の行頭文字もURLの一部とみなす。
1540     // (2005.4.3 yutaka)
1541     if (x == 0) {
1542 doda 5278 PrevCharAttr = AttrBuff[PrevLinePtr(LinePtr) + NumOfColumns-1];
1543     if ((PrevCharAttr & AttrURL) && (AttrLine[0] & AttrLineContinued)) {
1544 maya 3227 if (!(ch & 0x80 || url_char[ch]==0)) { // かつURL構成文字なら
1545 doda 5278 AttrLine[0] |= AttrURL;
1546 maya 3227 }
1547     }
1548     return;
1549     }
1550    
1551     if ((x-1>=0) && (AttrLine[x-1] & AttrURL) &&
1552     !(ch & 0x80 || url_char[ch]==0)) {
1553     // !((CodeLine[x] <= ' ') && !(AttrLine[x] & AttrKanji))) {
1554 doda 3642 AttrLine[x] |= AttrURL;
1555 maya 3227 return;
1556     }
1557    
1558     if ((x-2>=0) && !strncmp(&CodeLine[x-2], "://", 3)) {
1559 maya 3417 int i, len = -1;
1560 yutakapon 3608 RECT rc;
1561     int CaretX, CaretY;
1562 yutakapon 3614 char **p = prefix;
1563 yutakapon 3608
1564 yutakapon 3614 while (*p) {
1565     len = strlen(*p) - 1;
1566     if ((x-len>=0) && !strncmp(&CodeLine[x-len], *p, len)) {
1567     for (i = 0; i <= len; i++) {
1568 doda 3642 AttrLine[x-i] |= AttrURL;
1569 yutakapon 3614 }
1570     break;
1571     }
1572     p++;
1573 maya 3227 }
1574 yutakapon 3608
1575     /* ハイパーリンクの色属性変更は、すでに画面へ出力後に、バッファを遡って URL 属性を
1576     * 付け直すというロジックであるため、色が正しく描画されない場合がある。
1577     * 少々強引だが、ハイパーリンクを発見したタイミングで、その行に再描画指示を出すことで、
1578     * リアルタイムな色描画を実現する。
1579     * (2009.8.26 yutaka)
1580     */
1581     CaretX = (0-WinOrgX)*FontWidth;
1582     CaretY = (CursorY-WinOrgY)*FontHeight;
1583     rc.left = CaretX;
1584     rc.top = CaretY;
1585     rc.right = CaretX + NumOfColumns * FontWidth;
1586     rc.bottom = CaretY + FontHeight;
1587     InvalidateRect(HVTWin, &rc, FALSE);
1588 maya 3227 }
1589     #endif
1590     }
1591     /* end - ishizaki */
1592    
1593     void BuffPutChar(BYTE b, TCharAttr Attr, BOOL Insert)
1594     // Put a character in the buffer at the current position
1595     // b: character
1596     // Attr: attributes
1597     // Insert: Insert flag
1598     {
1599 doda 5324 int XStart, LineEnd, MoveLen;
1600 maya 3227
1601 doda 3312 #ifndef NO_COPYLINE_FIX
1602 maya 3393 if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
1603     Attr.Attr |= AttrLineContinued;
1604     }
1605 doda 3312 #endif /* NO_COPYLINE_FIX */
1606    
1607 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1608 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1609     if (! Insert) {
1610     EraseKanji(0); /* if cursor on left half... */
1611     }
1612     }
1613 maya 3227
1614 maya 3393 if (Insert) {
1615 doda 5324 if (CursorX > CursorRightM)
1616     LineEnd = NumOfColumns - 1;
1617     else
1618     LineEnd = CursorRightM;
1619    
1620     MoveLen = LineEnd - CursorX;
1621     if (MoveLen > 0) {
1622     memmove(&CodeLine[CursorX+1], &CodeLine[CursorX], MoveLen);
1623     memmove(&AttrLine[CursorX+1], &AttrLine[CursorX], MoveLen);
1624     memmove(&AttrLine2[CursorX+1], &AttrLine2[CursorX], MoveLen);
1625     memmove(&AttrLineFG[CursorX+1], &AttrLineFG[CursorX], MoveLen);
1626     memmove(&AttrLineBG[CursorX+1], &AttrLineBG[CursorX], MoveLen);
1627     }
1628 maya 3393 CodeLine[CursorX] = b;
1629     AttrLine[CursorX] = Attr.Attr;
1630     AttrLine2[CursorX] = Attr.Attr2;
1631     AttrLineFG[CursorX] = Attr.Fore;
1632     AttrLineBG[CursorX] = Attr.Back;
1633     /* last char in current line is kanji first? */
1634 doda 5324 if ((AttrLine[LineEnd] & AttrKanji) != 0) {
1635 maya 3393 /* then delete it */
1636 doda 5324 CodeLine[LineEnd] = 0x20;
1637     AttrLine[LineEnd] = CurCharAttr.Attr;
1638     AttrLine2[LineEnd] = CurCharAttr.Attr2;
1639     AttrLineFG[LineEnd] = CurCharAttr.Fore;
1640     AttrLineBG[LineEnd] = CurCharAttr.Back;
1641 maya 3393 }
1642     /* begin - ishizaki */
1643     markURL(CursorX+1);
1644     markURL(CursorX);
1645     /* end - ishizaki */
1646 maya 3227
1647 maya 3393 if (StrChangeCount==0) {
1648     XStart = CursorX;
1649     }
1650     else {
1651     XStart = StrChangeStart;
1652     }
1653     StrChangeCount = 0;
1654 doda 5324 BuffUpdateRect(XStart, CursorY, LineEnd, CursorY);
1655 maya 3393 }
1656     else {
1657     CodeLine[CursorX] = b;
1658     AttrLine[CursorX] = Attr.Attr;
1659     AttrLine2[CursorX] = Attr.Attr2;
1660     AttrLineFG[CursorX] = Attr.Fore;
1661     AttrLineBG[CursorX] = Attr.Back;
1662     /* begin - ishizaki */
1663     markURL(CursorX);
1664     /* end - ishizaki */
1665 maya 3227
1666 maya 3393 if (StrChangeCount==0) {
1667     StrChangeStart = CursorX;
1668     }
1669     StrChangeCount++;
1670     }
1671 maya 3227 }
1672    
1673     void BuffPutKanji(WORD w, TCharAttr Attr, BOOL Insert)
1674     // Put a kanji character in the buffer at the current position
1675     // b: character
1676     // Attr: attributes
1677     // Insert: Insert flag
1678     {
1679 doda 5324 int XStart, LineEnd, MoveLen;
1680 maya 3227
1681 doda 3312 #ifndef NO_COPYLINE_FIX
1682 maya 3393 if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
1683     Attr.Attr |= AttrLineContinued;
1684     }
1685 doda 3312 #endif /* NO_COPYLINE_FIX */
1686    
1687 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1688 maya 3227
1689 maya 3393 if (Insert) {
1690 doda 5324 if (CursorX > CursorRightM)
1691     LineEnd = NumOfColumns - 1;
1692     else
1693     LineEnd = CursorRightM;
1694 maya 3227
1695 doda 5324 MoveLen = LineEnd - CursorX - 1;
1696     if (MoveLen > 0) {
1697     memmove(&CodeLine[CursorX+2], &CodeLine[CursorX], MoveLen);
1698     memmove(&AttrLine[CursorX+2], &AttrLine[CursorX], MoveLen);
1699     memmove(&AttrLine2[CursorX+2], &AttrLine2[CursorX], MoveLen);
1700     memmove(&AttrLineFG[CursorX+2], &AttrLineFG[CursorX], MoveLen);
1701     memmove(&AttrLineBG[CursorX+2], &AttrLineBG[CursorX], MoveLen);
1702     }
1703    
1704 maya 3393 CodeLine[CursorX] = HIBYTE(w);
1705     AttrLine[CursorX] = Attr.Attr | AttrKanji; /* DBCS first byte */
1706     AttrLine2[CursorX] = Attr.Attr2;
1707     AttrLineFG[CursorX] = Attr.Fore;
1708     AttrLineBG[CursorX] = Attr.Back;
1709 doda 5324 if (CursorX < LineEnd) {
1710 maya 3393 CodeLine[CursorX+1] = LOBYTE(w);
1711     AttrLine[CursorX+1] = Attr.Attr;
1712     AttrLine2[CursorX+1] = Attr.Attr2;
1713     AttrLineFG[CursorX+1] = Attr.Fore;
1714     AttrLineBG[CursorX+1] = Attr.Back;
1715     }
1716     /* begin - ishizaki */
1717     markURL(CursorX);
1718     markURL(CursorX+1);
1719     /* end - ishizaki */
1720 maya 3227
1721 maya 3393 /* last char in current line is kanji first? */
1722 doda 5324 if ((AttrLine[LineEnd] & AttrKanji) != 0) {
1723 maya 3393 /* then delete it */
1724 doda 5324 CodeLine[LineEnd] = 0x20;
1725     AttrLine[LineEnd] = CurCharAttr.Attr;
1726     AttrLine2[LineEnd] = CurCharAttr.Attr2;
1727     AttrLineFG[LineEnd] = CurCharAttr.Fore;
1728     AttrLineBG[LineEnd] = CurCharAttr.Back;
1729 maya 3393 }
1730 maya 3227
1731 maya 3393 if (StrChangeCount==0) {
1732     XStart = CursorX;
1733     }
1734     else {
1735     XStart = StrChangeStart;
1736     }
1737     StrChangeCount = 0;
1738 doda 5324 BuffUpdateRect(XStart, CursorY, LineEnd, CursorY);
1739 maya 3393 }
1740     else {
1741     CodeLine[CursorX] = HIBYTE(w);
1742     AttrLine[CursorX] = Attr.Attr | AttrKanji; /* DBCS first byte */
1743     AttrLine2[CursorX] = Attr.Attr2;
1744     AttrLineFG[CursorX] = Attr.Fore;
1745     AttrLineBG[CursorX] = Attr.Back;
1746     if (CursorX < NumOfColumns-1) {
1747     CodeLine[CursorX+1] = LOBYTE(w);
1748     AttrLine[CursorX+1] = Attr.Attr;
1749     AttrLine2[CursorX+1] = Attr.Attr2;
1750     AttrLineFG[CursorX+1] = Attr.Fore;
1751     AttrLineBG[CursorX+1] = Attr.Back;
1752     }
1753     /* begin - ishizaki */
1754     markURL(CursorX);
1755     markURL(CursorX+1);
1756     /* end - ishizaki */
1757 maya 3227
1758 maya 3393 if (StrChangeCount==0) {
1759     StrChangeStart = CursorX;
1760     }
1761     StrChangeCount = StrChangeCount + 2;
1762     }
1763 maya 3227 }
1764    
1765     BOOL CheckSelect(int x, int y)
1766     // subroutine called by BuffUpdateRect
1767     {
1768 maya 3393 LONG L, L1, L2;
1769 maya 3227
1770 maya 3393 if (BoxSelect) {
1771     return (Selected &&
1772     ((SelectStart.x<=x) && (x<SelectEnd.x) ||
1773     (SelectEnd.x<=x) && (x<SelectStart.x)) &&
1774     ((SelectStart.y<=y) && (y<=SelectEnd.y) ||
1775     (SelectEnd.y<=y) && (y<=SelectStart.y)));
1776     }
1777     else {
1778     L = MAKELONG(x,y);
1779     L1 = MAKELONG(SelectStart.x,SelectStart.y);
1780     L2 = MAKELONG(SelectEnd.x,SelectEnd.y);
1781 maya 3227
1782 maya 3393 return (Selected &&
1783     ((L1<=L) && (L<L2) || (L2<=L) && (L<L1)));
1784     }
1785 maya 3227 }
1786    
1787     void BuffUpdateRect
1788     (int XStart, int YStart, int XEnd, int YEnd)
1789     // Display text in a rectangular region in the screen
1790     // XStart: x position of the upper-left corner (screen cordinate)
1791     // YStart: y position
1792     // XEnd: x position of the lower-right corner (last character)
1793     // YEnd: y position
1794     {
1795 maya 3393 int i, j, count;
1796     int IStart, IEnd;
1797     int X, Y;
1798     LONG TmpPtr;
1799     TCharAttr CurAttr, TempAttr;
1800     BOOL CurSel, TempSel, Caret;
1801 maya 3227
1802 maya 3393 if (XStart >= WinOrgX+WinWidth) {
1803     return;
1804     }
1805     if (YStart >= WinOrgY+WinHeight) {
1806     return;
1807     }
1808     if (XEnd < WinOrgX) {
1809     return;
1810     }
1811     if (YEnd < WinOrgY) {
1812     return;
1813     }
1814 maya 3227
1815 maya 3393 if (XStart < WinOrgX) {
1816     XStart = WinOrgX;
1817     }
1818     if (YStart < WinOrgY) {
1819     YStart = WinOrgY;
1820     }
1821     if (XEnd >= WinOrgX+WinWidth) {
1822     XEnd = WinOrgX+WinWidth-1;
1823     }
1824     if (YEnd >= WinOrgY+WinHeight) {
1825     YEnd = WinOrgY+WinHeight-1;
1826     }
1827 maya 3227
1828 maya 3393 TempAttr = DefCharAttr;
1829     TempSel = FALSE;
1830 maya 3227
1831 maya 3393 Caret = IsCaretOn();
1832     if (Caret) {
1833     CaretOff();
1834     }
1835 maya 3227
1836 maya 3393 DispSetupDC(DefCharAttr, TempSel);
1837 maya 3227
1838 maya 3393 Y = (YStart-WinOrgY)*FontHeight;
1839     TmpPtr = GetLinePtr(PageStart+YStart);
1840     for (j = YStart+PageStart ; j <= YEnd+PageStart ; j++) {
1841     IStart = XStart;
1842     IEnd = XEnd;
1843 maya 3227
1844 maya 3393 IStart = LeftHalfOfDBCS(TmpPtr,IStart);
1845 maya 3227
1846 maya 3393 X = (IStart-WinOrgX)*FontWidth;
1847 maya 3227
1848 maya 3393 i = IStart;
1849     do {
1850     CurAttr.Attr = AttrBuff[TmpPtr+i] & ~ AttrKanji;
1851     CurAttr.Attr2 = AttrBuff2[TmpPtr+i];
1852     CurAttr.Fore = AttrBuffFG[TmpPtr+i];
1853     CurAttr.Back = AttrBuffBG[TmpPtr+i];
1854     CurSel = CheckSelect(i,j);
1855     count = 1;
1856     while ( (i+count <= IEnd) &&
1857     (CurAttr.Attr == (AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
1858     (CurAttr.Attr2==AttrBuff2[TmpPtr+i+count]) &&
1859     (CurAttr.Fore==AttrBuffFG[TmpPtr+i+count]) &&
1860     (CurAttr.Back==AttrBuffBG[TmpPtr+i+count]) &&
1861     (CurSel==CheckSelect(i+count,j)) ||
1862     (i+count<NumOfColumns) &&
1863     ((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0) ) {
1864     count++;
1865     }
1866 maya 3227
1867 maya 3393 if (TCharAttrCmp(CurAttr, TempAttr) != 0 || (CurSel != TempSel)) {
1868     DispSetupDC(CurAttr, CurSel);
1869     TempAttr = CurAttr;
1870     TempSel = CurSel;
1871     }
1872     DispStr(&CodeBuff[TmpPtr+i],count,Y, &X);
1873     i = i+count;
1874     }
1875     while (i<=IEnd);
1876     Y = Y + FontHeight;
1877     TmpPtr = NextLinePtr(TmpPtr);
1878     }
1879     if (Caret) {
1880     CaretOn();
1881     }
1882 maya 3227 }
1883    
1884     void UpdateStr()
1885     // Display not-yet-displayed string
1886     {
1887 maya 3393 int X, Y;
1888     TCharAttr TempAttr;
1889 yutakapon 3656 int pos, len;
1890 maya 3227
1891 maya 3393 if (StrChangeCount==0) {
1892     return;
1893     }
1894     X = StrChangeStart;
1895     Y = CursorY;
1896     if (! IsLineVisible(&X, &Y)) {
1897     StrChangeCount = 0;
1898     return;
1899     }
1900 maya 3227
1901 maya 3393 TempAttr.Attr = AttrLine[StrChangeStart];
1902     TempAttr.Attr2 = AttrLine2[StrChangeStart];
1903     TempAttr.Fore = AttrLineFG[StrChangeStart];
1904     TempAttr.Back = AttrLineBG[StrChangeStart];
1905 yutakapon 3656
1906     /* これから描画する文字列の始まりが「URL構成文字属性」だった場合、
1907     * 当該色で行末までペイントされないようにする。
1908     * (2009.10.24 yutaka)
1909     */
1910 doda 3659 if (TempAttr.Attr & AttrURL) {
1911 yutakapon 3656 /* 開始位置からどこまでが AttrURL かをカウントする */
1912     len = 0;
1913     for (pos = 0 ; pos < StrChangeCount ; pos++) {
1914     if (TempAttr.Attr != AttrLine[StrChangeStart + pos])
1915     break;
1916     len++;
1917     }
1918     DispSetupDC(TempAttr, FALSE);
1919     DispStr(&CodeLine[StrChangeStart], len, Y, &X);
1920    
1921     /* 残りの文字列があれば、ふつうに描画を行う。*/
1922     if (len < StrChangeCount) {
1923     TempAttr.Attr = AttrLine[StrChangeStart + pos];
1924     TempAttr.Attr2 = AttrLine2[StrChangeStart + pos];
1925     TempAttr.Fore = AttrLineFG[StrChangeStart + pos];
1926     TempAttr.Back = AttrLineBG[StrChangeStart + pos];
1927    
1928     DispSetupDC(TempAttr, FALSE);
1929     DispStr(&CodeLine[StrChangeStart + pos], (StrChangeCount - len), Y, &X);
1930     }
1931     } else {
1932     DispSetupDC(TempAttr, FALSE);
1933     DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
1934     }
1935    
1936 maya 3393 StrChangeCount = 0;
1937 maya 3227 }
1938    
1939     #if 0
1940     void UpdateStrUnicode(void)
1941     // Display not-yet-displayed string
1942     {
1943     int X, Y;
1944     TCharAttr TempAttr;
1945    
1946     if (StrChangeCount==0) return;
1947     X = StrChangeStart;
1948     Y = CursorY;
1949     if (! IsLineVisible(&X, &Y))
1950     {
1951     StrChangeCount = 0;
1952     return;
1953     }
1954    
1955     TempAttr.Attr = AttrLine[StrChangeStart];
1956     TempAttr.Attr2 = AttrLine2[StrChangeStart];
1957     TempAttr.Fore = AttrLineFG[StrChangeStart];
1958     TempAttr.Back = AttrLineBG[StrChangeStart];
1959     DispSetupDC(TempAttr, FALSE);
1960     DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
1961     StrChangeCount = 0;
1962     }
1963     #endif
1964    
1965     void MoveCursor(int Xnew, int Ynew)
1966     {
1967 maya 3393 UpdateStr();
1968 maya 3227
1969 maya 3393 if (CursorY!=Ynew) {
1970     NewLine(PageStart+Ynew);
1971     }
1972 maya 3227
1973 maya 3393 CursorX = Xnew;
1974     CursorY = Ynew;
1975     Wrap = FALSE;
1976 maya 3227
1977 maya 3393 /* 最下行でだけ自動スクロールする*/
1978 doda 4469 if (ts.AutoScrollOnlyInBottomLine == 0 || WinOrgY == 0) {
1979 maya 3393 DispScrollToCursor(CursorX, CursorY);
1980     }
1981 maya 3227 }
1982    
1983     void MoveRight()
1984     /* move cursor right, but dont update screen.
1985     this procedure must be called from DispChar&DispKanji only */
1986     {
1987 maya 3393 CursorX++;
1988     /* 最下行でだけ自動スクロールする */
1989 doda 4469 if (ts.AutoScrollOnlyInBottomLine == 0 || WinOrgY == 0) {
1990 maya 3393 DispScrollToCursor(CursorX, CursorY);
1991     }
1992 maya 3227 }
1993    
1994     void BuffSetCaretWidth()
1995     {
1996 maya 3393 BOOL DW;
1997 maya 3227
1998 maya 3393 /* check whether cursor on a DBCS character */
1999     DW = (((BYTE)(AttrLine[CursorX]) & AttrKanji) != 0);
2000     DispSetCaretWidth(DW);
2001 maya 3227 }
2002    
2003     void ScrollUp1Line()
2004     {
2005 doda 5324 int i, linelen;
2006 maya 3393 LONG SrcPtr, DestPtr;
2007 maya 3227
2008 maya 3393 if ((CursorTop<=CursorY) && (CursorY<=CursorBottom)) {
2009     UpdateStr();
2010 maya 3227
2011 doda 5324 linelen = CursorRightM - CursorLeftM + 1;
2012     DestPtr = GetLinePtr(PageStart+CursorBottom) + CursorLeftM;
2013 maya 3393 for (i = CursorBottom-1 ; i >= CursorTop ; i--) {
2014     SrcPtr = PrevLinePtr(DestPtr);
2015 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
2016     memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
2017     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
2018     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
2019     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
2020 maya 3393 DestPtr = SrcPtr;
2021     }
2022 doda 5324 memset(&(CodeBuff[SrcPtr]), 0x20, linelen);
2023     memset(&(AttrBuff[SrcPtr]), AttrDefault, linelen);
2024     memset(&(AttrBuff2[SrcPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
2025     memset(&(AttrBuffFG[SrcPtr]), CurCharAttr.Fore, linelen);
2026     memset(&(AttrBuffBG[SrcPtr]), CurCharAttr.Back, linelen);
2027 maya 3227
2028 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1)
2029     BuffUpdateRect(CursorLeftM, CursorTop, CursorRightM, CursorBottom);
2030     else
2031     DispScrollNLines(CursorTop, CursorBottom, -1);
2032 maya 3393 }
2033 maya 3227 }
2034    
2035     void BuffScrollNLines(int n)
2036     {
2037 doda 5324 int i, linelen;
2038 maya 3393 LONG SrcPtr, DestPtr;
2039 maya 3227
2040 maya 3393 if (n<1) {
2041     return;
2042     }
2043     UpdateStr();
2044 maya 3227
2045 doda 5324 if (CursorLeftM == 0 && CursorRightM == NumOfColumns-1 && CursorTop == 0) {
2046     if (CursorBottom == NumOfLines-1) {
2047 maya 3393 WinOrgY = WinOrgY-n;
2048 doda 5324 /* 最下行でだけ自動スクロールする */
2049     if (ts.AutoScrollOnlyInBottomLine != 0 && NewOrgY != 0) {
2050     NewOrgY = WinOrgY;
2051     }
2052 maya 3393 BuffScroll(n,CursorBottom);
2053     DispCountScroll(n);
2054 doda 5324 return;
2055 maya 3393 }
2056 doda 5324 else if (CursorY <= CursorBottom) {
2057     /* 最下行でだけ自動スクロールする */
2058     if (ts.AutoScrollOnlyInBottomLine != 0 && NewOrgY != 0) {
2059     /* スクロールさせない場合の処理 */
2060     WinOrgY = WinOrgY-n;
2061     NewOrgY = WinOrgY;
2062     BuffScroll(n,CursorBottom);
2063     DispCountScroll(n);
2064     } else {
2065     BuffScroll(n,CursorBottom);
2066     DispScrollNLines(WinOrgY,CursorBottom,n);
2067     }
2068     return;
2069     }
2070 maya 3393 }
2071 doda 5324
2072     if ((CursorTop<=CursorY) && (CursorY<=CursorBottom)) {
2073     linelen = CursorRightM - CursorLeftM + 1;
2074     DestPtr = GetLinePtr(PageStart+CursorTop) + (LONG)CursorLeftM;
2075 maya 3393 if (n<CursorBottom-CursorTop+1) {
2076 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorTop+n) + (LONG)CursorLeftM;
2077 maya 3393 for (i = CursorTop+n ; i<=CursorBottom ; i++) {
2078 doda 5324 memmove(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
2079     memmove(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
2080     memmove(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
2081     memmove(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
2082     memmove(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
2083 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
2084     DestPtr = NextLinePtr(DestPtr);
2085     }
2086     }
2087     else {
2088     n = CursorBottom-CursorTop+1;
2089     }
2090     for (i = CursorBottom+1-n ; i<=CursorBottom; i++) {
2091 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
2092     memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
2093     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
2094     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
2095     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
2096 maya 3393 DestPtr = NextLinePtr(DestPtr);
2097     }
2098 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1)
2099     BuffUpdateRect(CursorLeftM, CursorTop, CursorRightM, CursorBottom);
2100     else
2101     DispScrollNLines(CursorTop, CursorBottom, n);
2102 maya 3393 }
2103 maya 3227 }
2104    
2105     void BuffRegionScrollUpNLines(int n) {
2106 maya 3393 int i;
2107     LONG SrcPtr, DestPtr;
2108 maya 3227
2109 maya 3393 if (n<1) {
2110     return;
2111     }
2112     UpdateStr();
2113 maya 3227
2114 maya 3393 if (n > 0) {
2115     if ((CursorTop == 0) && (CursorBottom == NumOfLines-1)) {
2116     WinOrgY = WinOrgY-n;
2117     BuffScroll(n,CursorBottom);
2118     DispCountScroll(n);
2119     }
2120     else if (CursorTop==0) {
2121     BuffScroll(n,CursorBottom);
2122     DispScrollNLines(WinOrgY,CursorBottom,n);
2123     }
2124     else {
2125     DestPtr = GetLinePtr(PageStart+CursorTop);
2126     if (n<CursorBottom-CursorTop+1) {
2127     SrcPtr = GetLinePtr(PageStart+CursorTop+n);
2128     for (i = CursorTop+n ; i<=CursorBottom ; i++) {
2129     memmove(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
2130     memmove(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
2131     memmove(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
2132     memmove(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
2133     memmove(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
2134     SrcPtr = NextLinePtr(SrcPtr);
2135     DestPtr = NextLinePtr(DestPtr);
2136     }
2137     }
2138     else {
2139     n = CursorBottom-CursorTop+1;
2140     }
2141     for (i = CursorBottom+1-n ; i<=CursorBottom; i++) {
2142     memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
2143     memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
2144 doda 4070 memset(&(AttrBuff2[DestPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
2145 maya 3393 memset(&(AttrBuffFG[DestPtr]),CurCharAttr.Fore,NumOfColumns);
2146     memset(&(AttrBuffBG[DestPtr]),CurCharAttr.Back,NumOfColumns);
2147     DestPtr = NextLinePtr(DestPtr);
2148     }
2149     DispScrollNLines(CursorTop,CursorBottom,n);
2150     }
2151 maya 3227 }
2152     }
2153    
2154     void BuffRegionScrollDownNLines(int n) {
2155 maya 3393 int i;
2156     LONG SrcPtr, DestPtr;
2157 maya 3227
2158 maya 3393 if (n<1) {
2159     return;
2160     }
2161     UpdateStr();
2162 maya 3227
2163 maya 3393 DestPtr = GetLinePtr(PageStart+CursorBottom);
2164     if (n < CursorBottom-CursorTop+1) {
2165     SrcPtr = GetLinePtr(PageStart+CursorBottom-n);
2166     for (i=CursorBottom-n ; i>=CursorTop ; i--) {
2167     memmove(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
2168     memmove(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
2169     memmove(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
2170     memmove(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
2171     memmove(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
2172     SrcPtr = PrevLinePtr(SrcPtr);
2173     DestPtr = PrevLinePtr(DestPtr);
2174     }
2175     }
2176     else {
2177     n = CursorBottom - CursorTop + 1;
2178     }
2179     for (i = CursorTop+n-1; i>=CursorTop; i--) {
2180     memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
2181     memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
2182 doda 4070 memset(&(AttrBuff2[DestPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
2183 maya 3393 memset(&(AttrBuffFG[DestPtr]),CurCharAttr.Fore,NumOfColumns);
2184     memset(&(AttrBuffBG[DestPtr]),CurCharAttr.Back,NumOfColumns);
2185     DestPtr = PrevLinePtr(DestPtr);
2186     }
2187 maya 3227
2188 maya 3393 DispScrollNLines(CursorTop,CursorBottom,-n);
2189 maya 3227 }
2190    
2191     void BuffClearScreen()
2192     { // clear screen
2193 doda 5324 if (isCursorOnStatusLine) {
2194 maya 3393 BuffScrollNLines(1); /* clear status line */
2195     }
2196     else { /* clear main screen */
2197 &