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 5279 - (hide annotations) (download) (as text)
Fri May 24 10:58:57 2013 UTC (10 years, 10 months ago) by doda
File MIME type: text/x-csrc
File size: 93494 byte(s)
URL 上でマウスカーソル形状を変更する際の判定が左に半文字分ずれていたのを修正。

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