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 6785 - (hide annotations) (download) (as text)
Fri Jun 9 10:04:32 2017 UTC (6 years, 10 months ago) by doda
File MIME type: text/x-csrc
File size: 99891 byte(s)
InitBuffer 側でも ts.TerminalWidth, ts.TerminalHeight の値のチェックを行うようにした。

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