Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /branches/ttcomtester/teraterm/teraterm/buffer.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5426 - (hide annotations) (download) (as text)
Fri Nov 22 09:21:17 2013 UTC (10 years, 4 months ago) by doda
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 98473 byte(s)
インデント修正

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