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