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 3417 - (hide annotations) (download) (as text)
Wed May 20 14:58:24 2009 UTC (14 years, 10 months ago) by maya
File MIME type: text/x-csrc
File size: 75893 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    
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 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
591 maya 3393 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 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
634 maya 3393 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 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
665 maya 3393 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 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
740 maya 3393 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 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
807 maya 3393 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 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
840 maya 3393 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 yutakapon 3414 // RFC3986(Uniform Resource Identifier (URI): Generic Syntax)に準拠する
1342 maya 3227 // by sakura editor 1.5.2.1: etc_uty.cpp
1343     static const char url_char[] = {
1344     /* +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F */
1345     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* +00: */
1346     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* +10: */
1347     0, -1, 0, -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, /* +20: " !"#$%&'()*+,-./" */
1348     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, /* +30: "0123456789:;<=>?" */
1349     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* +40: "@ABCDEFGHIJKLMNO" */
1350     -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, -1, /* +50: "PQRSTUVWXYZ[\]^_" */
1351     0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* +60: "`abcdefghijklmno" */
1352 yutakapon 3414 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, -1, 0, /* +70: "pqrstuvwxyz{|}~ " */
1353 maya 3227 /* 0 : not url char
1354     * -1 : url char
1355     * other: url head char --> url_table array number + 1
1356     */
1357     };
1358     unsigned char ch = CodeLine[x];
1359    
1360     if (ts.EnableClickableUrl == FALSE)
1361     return;
1362    
1363     // 直前の行から連結しているか。
1364     // TODO: 1つ前の行の終端文字が URL の一部なら、強制的に現在の行頭文字もURLの一部とみなす。
1365     // (2005.4.3 yutaka)
1366     if (x == 0) {
1367     if (AttrLine > AttrBuff && (AttrLine[x-1] & AttrURL)) {
1368     if (!(ch & 0x80 || url_char[ch]==0)) { // かつURL構成文字なら
1369     AttrLine[x] |= AttrURL;
1370     }
1371     }
1372     return;
1373     }
1374    
1375     if ((x-1>=0) && (AttrLine[x-1] & AttrURL) &&
1376     !(ch & 0x80 || url_char[ch]==0)) {
1377     // !((CodeLine[x] <= ' ') && !(AttrLine[x] & AttrKanji))) {
1378     AttrLine[x] |= AttrURL;
1379     // AttrLine[x] |= (AttrURL | AttrUnder);
1380     return;
1381     }
1382    
1383     if ((x-2>=0) && !strncmp(&CodeLine[x-2], "://", 3)) {
1384 maya 3417 int i, len = -1;
1385 maya 3227 if ((x-6>=0) && !strncmp(&CodeLine[x-6], "http", 4)) {
1386     len = 6;
1387     }
1388     if ((x-7>=0) && !strncmp(&CodeLine[x-7], "https", 5)) {
1389     len = 7;
1390     }
1391     if ((x-6>=0) && !strncmp(&CodeLine[x-6], "news", 4)) {
1392     len = 6;
1393     }
1394     if ((x-5>=0) && !strncmp(&CodeLine[x-5], "ftp", 3)) {
1395     len = 5;
1396     }
1397     if ((x-5>=0) && !strncmp(&CodeLine[x-5], "mms", 3)) {
1398     len = 5;
1399     }
1400     #if 0
1401     if ((x-5>=0) && !strncmp(&CodeLine[x-5], "ttp", 3)) {
1402     len = 5;
1403     }
1404     #endif
1405     for (i = 0; i <= len; i++) {
1406     AttrLine[x-i] |= AttrURL;
1407     // AttrLine[x-i] |= (AttrURL | AttrUnder);
1408     }
1409     }
1410     #endif
1411     }
1412     /* end - ishizaki */
1413    
1414     void BuffPutChar(BYTE b, TCharAttr Attr, BOOL Insert)
1415     // Put a character in the buffer at the current position
1416     // b: character
1417     // Attr: attributes
1418     // Insert: Insert flag
1419     {
1420 maya 3393 int XStart;
1421 maya 3227
1422 doda 3312 #ifndef NO_COPYLINE_FIX
1423 maya 3393 if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
1424     Attr.Attr |= AttrLineContinued;
1425     }
1426 doda 3312 #endif /* NO_COPYLINE_FIX */
1427    
1428 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1429 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1430     if (! Insert) {
1431     EraseKanji(0); /* if cursor on left half... */
1432     }
1433     }
1434 maya 3227
1435 maya 3393 if (Insert) {
1436     memmove(&CodeLine[CursorX+1],&CodeLine[CursorX],NumOfColumns-1-CursorX);
1437     memmove(&AttrLine[CursorX+1],&AttrLine[CursorX],NumOfColumns-1-CursorX);
1438     memmove(&AttrLine2[CursorX+1],&AttrLine2[CursorX],NumOfColumns-1-CursorX);
1439     memmove(&AttrLineFG[CursorX+1],&AttrLineFG[CursorX],NumOfColumns-1-CursorX);
1440     memmove(&AttrLineBG[CursorX+1],&AttrLineBG[CursorX],NumOfColumns-1-CursorX);
1441     CodeLine[CursorX] = b;
1442     AttrLine[CursorX] = Attr.Attr;
1443     AttrLine2[CursorX] = Attr.Attr2;
1444     AttrLineFG[CursorX] = Attr.Fore;
1445     AttrLineBG[CursorX] = Attr.Back;
1446     /* last char in current line is kanji first? */
1447     if ((AttrLine[NumOfColumns-1] & AttrKanji) != 0) {
1448     /* then delete it */
1449     CodeLine[NumOfColumns-1] = 0x20;
1450     AttrLine[NumOfColumns-1] = CurCharAttr.Attr;
1451     AttrLine2[NumOfColumns-1] = CurCharAttr.Attr2;
1452     AttrLineFG[NumOfColumns-1] = CurCharAttr.Fore;
1453     AttrLineBG[NumOfColumns-1] = CurCharAttr.Back;
1454     }
1455     /* begin - ishizaki */
1456     markURL(CursorX+1);
1457     markURL(CursorX);
1458     /* end - ishizaki */
1459 maya 3227
1460 maya 3393 if (StrChangeCount==0) {
1461     XStart = CursorX;
1462     }
1463     else {
1464     XStart = StrChangeStart;
1465     }
1466     StrChangeCount = 0;
1467     BuffUpdateRect(XStart,CursorY,NumOfColumns-1,CursorY);
1468     }
1469     else {
1470     CodeLine[CursorX] = b;
1471     AttrLine[CursorX] = Attr.Attr;
1472     AttrLine2[CursorX] = Attr.Attr2;
1473     AttrLineFG[CursorX] = Attr.Fore;
1474     AttrLineBG[CursorX] = Attr.Back;
1475     /* begin - ishizaki */
1476     markURL(CursorX);
1477     /* end - ishizaki */
1478 maya 3227
1479 maya 3393 if (StrChangeCount==0) {
1480     StrChangeStart = CursorX;
1481     }
1482     StrChangeCount++;
1483     }
1484 maya 3227 }
1485    
1486     void BuffPutKanji(WORD w, TCharAttr Attr, BOOL Insert)
1487     // Put a kanji character in the buffer at the current position
1488     // b: character
1489     // Attr: attributes
1490     // Insert: Insert flag
1491     {
1492 maya 3393 int XStart;
1493 maya 3227
1494 doda 3312 #ifndef NO_COPYLINE_FIX
1495 maya 3393 if (ts.EnableContinuedLineCopy && CursorX == 0 && (AttrLine[0] & AttrLineContinued)) {
1496     Attr.Attr |= AttrLineContinued;
1497     }
1498 doda 3312 #endif /* NO_COPYLINE_FIX */
1499    
1500 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1501 maya 3227
1502 maya 3393 if (Insert) {
1503     memmove(&CodeLine[CursorX+2],&CodeLine[CursorX],NumOfColumns-2-CursorX);
1504     memmove(&AttrLine[CursorX+2],&AttrLine[CursorX],NumOfColumns-2-CursorX);
1505     memmove(&AttrLine2[CursorX+2],&AttrLine2[CursorX],NumOfColumns-2-CursorX);
1506     memmove(&AttrLineFG[CursorX+2],&AttrLineFG[CursorX],NumOfColumns-2-CursorX);
1507     memmove(&AttrLineBG[CursorX+2],&AttrLineBG[CursorX],NumOfColumns-2-CursorX);
1508 maya 3227
1509 maya 3393 CodeLine[CursorX] = HIBYTE(w);
1510     AttrLine[CursorX] = Attr.Attr | AttrKanji; /* DBCS first byte */
1511     AttrLine2[CursorX] = Attr.Attr2;
1512     AttrLineFG[CursorX] = Attr.Fore;
1513     AttrLineBG[CursorX] = Attr.Back;
1514     if (CursorX < NumOfColumns-1) {
1515     CodeLine[CursorX+1] = LOBYTE(w);
1516     AttrLine[CursorX+1] = Attr.Attr;
1517     AttrLine2[CursorX+1] = Attr.Attr2;
1518     AttrLineFG[CursorX+1] = Attr.Fore;
1519     AttrLineBG[CursorX+1] = Attr.Back;
1520     }
1521     /* begin - ishizaki */
1522     markURL(CursorX);
1523     markURL(CursorX+1);
1524     /* end - ishizaki */
1525 maya 3227
1526 maya 3393 /* last char in current line is kanji first? */
1527     if ((AttrLine[NumOfColumns-1] & AttrKanji) != 0) {
1528     /* then delete it */
1529     CodeLine[NumOfColumns-1] = 0x20;
1530     AttrLine[NumOfColumns-1] = CurCharAttr.Attr;
1531     AttrLine2[NumOfColumns-1] = CurCharAttr.Attr2;
1532     AttrLineFG[NumOfColumns-1] = CurCharAttr.Fore;
1533     AttrLineBG[NumOfColumns-1] = CurCharAttr.Back;
1534     }
1535 maya 3227
1536 maya 3393 if (StrChangeCount==0) {
1537     XStart = CursorX;
1538     }
1539     else {
1540     XStart = StrChangeStart;
1541     }
1542     StrChangeCount = 0;
1543     BuffUpdateRect(XStart,CursorY,NumOfColumns-1,CursorY);
1544     }
1545     else {
1546     CodeLine[CursorX] = HIBYTE(w);
1547     AttrLine[CursorX] = Attr.Attr | AttrKanji; /* DBCS first byte */
1548     AttrLine2[CursorX] = Attr.Attr2;
1549     AttrLineFG[CursorX] = Attr.Fore;
1550     AttrLineBG[CursorX] = Attr.Back;
1551     if (CursorX < NumOfColumns-1) {
1552     CodeLine[CursorX+1] = LOBYTE(w);
1553     AttrLine[CursorX+1] = Attr.Attr;
1554     AttrLine2[CursorX+1] = Attr.Attr2;
1555     AttrLineFG[CursorX+1] = Attr.Fore;
1556     AttrLineBG[CursorX+1] = Attr.Back;
1557     }
1558     /* begin - ishizaki */
1559     markURL(CursorX);
1560     markURL(CursorX+1);
1561     /* end - ishizaki */
1562 maya 3227
1563 maya 3393 if (StrChangeCount==0) {
1564     StrChangeStart = CursorX;
1565     }
1566     StrChangeCount = StrChangeCount + 2;
1567     }
1568 maya 3227 }
1569    
1570     BOOL CheckSelect(int x, int y)
1571     // subroutine called by BuffUpdateRect
1572     {
1573 maya 3393 LONG L, L1, L2;
1574 maya 3227
1575 maya 3393 if (BoxSelect) {
1576     return (Selected &&
1577     ((SelectStart.x<=x) && (x<SelectEnd.x) ||
1578     (SelectEnd.x<=x) && (x<SelectStart.x)) &&
1579     ((SelectStart.y<=y) && (y<=SelectEnd.y) ||
1580     (SelectEnd.y<=y) && (y<=SelectStart.y)));
1581     }
1582     else {
1583     L = MAKELONG(x,y);
1584     L1 = MAKELONG(SelectStart.x,SelectStart.y);
1585     L2 = MAKELONG(SelectEnd.x,SelectEnd.y);
1586 maya 3227
1587 maya 3393 return (Selected &&
1588     ((L1<=L) && (L<L2) || (L2<=L) && (L<L1)));
1589     }
1590 maya 3227 }
1591    
1592     void BuffUpdateRect
1593     (int XStart, int YStart, int XEnd, int YEnd)
1594     // Display text in a rectangular region in the screen
1595     // XStart: x position of the upper-left corner (screen cordinate)
1596     // YStart: y position
1597     // XEnd: x position of the lower-right corner (last character)
1598     // YEnd: y position
1599     {
1600 maya 3393 int i, j, count;
1601     int IStart, IEnd;
1602     int X, Y;
1603     LONG TmpPtr;
1604     TCharAttr CurAttr, TempAttr;
1605     BOOL CurSel, TempSel, Caret;
1606 maya 3227
1607 maya 3393 if (XStart >= WinOrgX+WinWidth) {
1608     return;
1609     }
1610     if (YStart >= WinOrgY+WinHeight) {
1611     return;
1612     }
1613     if (XEnd < WinOrgX) {
1614     return;
1615     }
1616     if (YEnd < WinOrgY) {
1617     return;
1618     }
1619 maya 3227
1620 maya 3393 if (XStart < WinOrgX) {
1621     XStart = WinOrgX;
1622     }
1623     if (YStart < WinOrgY) {
1624     YStart = WinOrgY;
1625     }
1626     if (XEnd >= WinOrgX+WinWidth) {
1627     XEnd = WinOrgX+WinWidth-1;
1628     }
1629     if (YEnd >= WinOrgY+WinHeight) {
1630     YEnd = WinOrgY+WinHeight-1;
1631     }
1632 maya 3227
1633 maya 3393 TempAttr = DefCharAttr;
1634     TempSel = FALSE;
1635 maya 3227
1636 maya 3393 Caret = IsCaretOn();
1637     if (Caret) {
1638     CaretOff();
1639     }
1640 maya 3227
1641 maya 3393 DispSetupDC(DefCharAttr, TempSel);
1642 maya 3227
1643 maya 3393 Y = (YStart-WinOrgY)*FontHeight;
1644     TmpPtr = GetLinePtr(PageStart+YStart);
1645     for (j = YStart+PageStart ; j <= YEnd+PageStart ; j++) {
1646     IStart = XStart;
1647     IEnd = XEnd;
1648 maya 3227
1649 maya 3393 IStart = LeftHalfOfDBCS(TmpPtr,IStart);
1650 maya 3227
1651 maya 3393 X = (IStart-WinOrgX)*FontWidth;
1652 maya 3227
1653 maya 3393 i = IStart;
1654     do {
1655     CurAttr.Attr = AttrBuff[TmpPtr+i] & ~ AttrKanji;
1656     CurAttr.Attr2 = AttrBuff2[TmpPtr+i];
1657     CurAttr.Fore = AttrBuffFG[TmpPtr+i];
1658     CurAttr.Back = AttrBuffBG[TmpPtr+i];
1659     CurSel = CheckSelect(i,j);
1660     count = 1;
1661     while ( (i+count <= IEnd) &&
1662     (CurAttr.Attr == (AttrBuff[TmpPtr+i+count] & ~ AttrKanji)) &&
1663     (CurAttr.Attr2==AttrBuff2[TmpPtr+i+count]) &&
1664     (CurAttr.Fore==AttrBuffFG[TmpPtr+i+count]) &&
1665     (CurAttr.Back==AttrBuffBG[TmpPtr+i+count]) &&
1666     (CurSel==CheckSelect(i+count,j)) ||
1667     (i+count<NumOfColumns) &&
1668     ((AttrBuff[TmpPtr+i+count-1] & AttrKanji) != 0) ) {
1669     count++;
1670     }
1671 maya 3227
1672 maya 3393 if (TCharAttrCmp(CurAttr, TempAttr) != 0 || (CurSel != TempSel)) {
1673     DispSetupDC(CurAttr, CurSel);
1674     TempAttr = CurAttr;
1675     TempSel = CurSel;
1676     }
1677     DispStr(&CodeBuff[TmpPtr+i],count,Y, &X);
1678     i = i+count;
1679     }
1680     while (i<=IEnd);
1681     Y = Y + FontHeight;
1682     TmpPtr = NextLinePtr(TmpPtr);
1683     }
1684     if (Caret) {
1685     CaretOn();
1686     }
1687 maya 3227 }
1688    
1689     void UpdateStr()
1690     // Display not-yet-displayed string
1691     {
1692 maya 3393 int X, Y;
1693     TCharAttr TempAttr;
1694 maya 3227
1695 maya 3393 if (StrChangeCount==0) {
1696     return;
1697     }
1698     X = StrChangeStart;
1699     Y = CursorY;
1700     if (! IsLineVisible(&X, &Y)) {
1701     StrChangeCount = 0;
1702     return;
1703     }
1704 maya 3227
1705 maya 3393 TempAttr.Attr = AttrLine[StrChangeStart];
1706     TempAttr.Attr2 = AttrLine2[StrChangeStart];
1707     TempAttr.Fore = AttrLineFG[StrChangeStart];
1708     TempAttr.Back = AttrLineBG[StrChangeStart];
1709     DispSetupDC(TempAttr, FALSE);
1710     DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
1711     StrChangeCount = 0;
1712 maya 3227 }
1713    
1714     #if 0
1715     void UpdateStrUnicode(void)
1716     // Display not-yet-displayed string
1717     {
1718     int X, Y;
1719     TCharAttr TempAttr;
1720    
1721     if (StrChangeCount==0) return;
1722     X = StrChangeStart;
1723     Y = CursorY;
1724     if (! IsLineVisible(&X, &Y))
1725     {
1726     StrChangeCount = 0;
1727     return;
1728     }
1729    
1730     TempAttr.Attr = AttrLine[StrChangeStart];
1731     TempAttr.Attr2 = AttrLine2[StrChangeStart];
1732     TempAttr.Fore = AttrLineFG[StrChangeStart];
1733     TempAttr.Back = AttrLineBG[StrChangeStart];
1734     DispSetupDC(TempAttr, FALSE);
1735     DispStr(&CodeLine[StrChangeStart],StrChangeCount,Y, &X);
1736     StrChangeCount = 0;
1737     }
1738     #endif
1739    
1740     void MoveCursor(int Xnew, int Ynew)
1741     {
1742 maya 3393 UpdateStr();
1743 maya 3227
1744 maya 3393 if (CursorY!=Ynew) {
1745     NewLine(PageStart+Ynew);
1746     }
1747 maya 3227
1748 maya 3393 CursorX = Xnew;
1749     CursorY = Ynew;
1750     Wrap = FALSE;
1751 maya 3227
1752 maya 3393 /* 最下行でだけ自動スクロールする*/
1753     if (ts.AutoScrollOnlyInBottomLine == 0 || WinOrgY == 0) {
1754     DispScrollToCursor(CursorX, CursorY);
1755     }
1756 maya 3227 }
1757    
1758     void MoveRight()
1759     /* move cursor right, but dont update screen.
1760     this procedure must be called from DispChar&DispKanji only */
1761     {
1762 maya 3393 CursorX++;
1763     /* 最下行でだけ自動スクロールする */
1764     if (ts.AutoScrollOnlyInBottomLine == 0 || WinOrgY == 0) {
1765     DispScrollToCursor(CursorX, CursorY);
1766     }
1767 maya 3227 }
1768    
1769     void BuffSetCaretWidth()
1770     {
1771 maya 3393 BOOL DW;
1772 maya 3227
1773 maya 3393 /* check whether cursor on a DBCS character */
1774     DW = (((BYTE)(AttrLine[CursorX]) & AttrKanji) != 0);
1775     DispSetCaretWidth(DW);
1776 maya 3227 }
1777    
1778     void ScrollUp1Line()
1779     {
1780 maya 3393 int i;
1781     LONG SrcPtr, DestPtr;
1782 maya 3227
1783 maya 3393 if ((CursorTop<=CursorY) && (CursorY<=CursorBottom)) {
1784     UpdateStr();
1785 maya 3227
1786 maya 3393 DestPtr = GetLinePtr(PageStart+CursorBottom);
1787     for (i = CursorBottom-1 ; i >= CursorTop ; i--) {
1788     SrcPtr = PrevLinePtr(DestPtr);
1789     memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
1790     memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
1791     memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
1792     memcpy(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
1793     memcpy(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
1794     DestPtr = SrcPtr;
1795     }
1796     memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
1797     memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
1798     memset(&(AttrBuff2[SrcPtr]),CurCharAttr.Attr2,NumOfColumns);
1799     memset(&(AttrBuffFG[SrcPtr]),CurCharAttr.Fore,NumOfColumns);
1800     memset(&(AttrBuffBG[SrcPtr]),CurCharAttr.Back,NumOfColumns);
1801 maya 3227
1802 maya 3393 DispScrollNLines(CursorTop,CursorBottom,-1);
1803     }
1804 maya 3227 }
1805    
1806     void BuffScrollNLines(int n)
1807     {
1808 maya 3393 int i;
1809     LONG SrcPtr, DestPtr;
1810 maya 3227
1811 maya 3393 if (n<1) {
1812     return;
1813     }
1814     UpdateStr();
1815 maya 3227
1816 maya 3393 if ((CursorTop == 0) && (CursorBottom == NumOfLines-1)) {
1817     WinOrgY = WinOrgY-n;
1818     /* 最下行でだけ自動スクロールする */
1819     if (ts.AutoScrollOnlyInBottomLine != 0 && NewOrgY != 0) {
1820     NewOrgY = WinOrgY;
1821     }
1822     BuffScroll(n,CursorBottom);
1823     DispCountScroll(n);
1824     }
1825     else if ((CursorTop==0) && (CursorY<=CursorBottom)) {
1826     /* 最下行でだけ自動スクロールする */
1827     if (ts.AutoScrollOnlyInBottomLine != 0 && NewOrgY != 0) {
1828     /* スクロールさせない場合の処理 */
1829     WinOrgY = WinOrgY-n;
1830     NewOrgY = WinOrgY;
1831     BuffScroll(n,CursorBottom);
1832     DispCountScroll(n);
1833     } else {
1834     BuffScroll(n,CursorBottom);
1835     DispScrollNLines(WinOrgY,CursorBottom,n);
1836     }
1837     }
1838     else if ((CursorTop<=CursorY) && (CursorY<=CursorBottom)) {
1839     DestPtr = GetLinePtr(PageStart+CursorTop);
1840     if (n<CursorBottom-CursorTop+1) {
1841     SrcPtr = GetLinePtr(PageStart+CursorTop+n);
1842     for (i = CursorTop+n ; i<=CursorBottom ; i++) {
1843     memmove(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
1844     memmove(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
1845     memmove(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
1846     memmove(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
1847     memmove(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
1848     SrcPtr = NextLinePtr(SrcPtr);
1849     DestPtr = NextLinePtr(DestPtr);
1850     }
1851     }
1852     else {
1853     n = CursorBottom-CursorTop+1;
1854     }
1855     for (i = CursorBottom+1-n ; i<=CursorBottom; i++) {
1856     memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
1857     memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
1858     memset(&(AttrBuff2[DestPtr]),CurCharAttr.Attr2,NumOfColumns);
1859     memset(&(AttrBuffFG[DestPtr]),CurCharAttr.Fore,NumOfColumns);
1860     memset(&(AttrBuffBG[DestPtr]),CurCharAttr.Back,NumOfColumns);
1861     DestPtr = NextLinePtr(DestPtr);
1862     }
1863     DispScrollNLines(CursorTop,CursorBottom,n);
1864     }
1865 maya 3227 }
1866    
1867     void BuffRegionScrollUpNLines(int n) {
1868 maya 3393 int i;
1869     LONG SrcPtr, DestPtr;
1870 maya 3227
1871 maya 3393 if (n<1) {
1872     return;
1873     }
1874     UpdateStr();
1875 maya 3227
1876 maya 3393 if (n > 0) {
1877     if ((CursorTop == 0) && (CursorBottom == NumOfLines-1)) {
1878     WinOrgY = WinOrgY-n;
1879     BuffScroll(n,CursorBottom);
1880     DispCountScroll(n);
1881     }
1882     else if (CursorTop==0) {
1883     BuffScroll(n,CursorBottom);
1884     DispScrollNLines(WinOrgY,CursorBottom,n);
1885     }
1886     else {
1887     DestPtr = GetLinePtr(PageStart+CursorTop);
1888     if (n<CursorBottom-CursorTop+1) {
1889     SrcPtr = GetLinePtr(PageStart+CursorTop+n);
1890     for (i = CursorTop+n ; i<=CursorBottom ; i++) {
1891     memmove(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
1892     memmove(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
1893     memmove(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
1894     memmove(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
1895     memmove(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
1896     SrcPtr = NextLinePtr(SrcPtr);
1897     DestPtr = NextLinePtr(DestPtr);
1898     }
1899     }
1900     else {
1901     n = CursorBottom-CursorTop+1;
1902     }
1903     for (i = CursorBottom+1-n ; i<=CursorBottom; i++) {
1904     memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
1905     memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
1906     memset(&(AttrBuff2[DestPtr]),CurCharAttr.Attr2,NumOfColumns);
1907     memset(&(AttrBuffFG[DestPtr]),CurCharAttr.Fore,NumOfColumns);
1908     memset(&(AttrBuffBG[DestPtr]),CurCharAttr.Back,NumOfColumns);
1909     DestPtr = NextLinePtr(DestPtr);
1910     }
1911     DispScrollNLines(CursorTop,CursorBottom,n);
1912     }
1913 maya 3227 }
1914     }
1915    
1916     void BuffRegionScrollDownNLines(int n) {
1917 maya 3393 int i;
1918     LONG SrcPtr, DestPtr;
1919 maya 3227
1920 maya 3393 if (n<1) {
1921     return;
1922     }
1923     UpdateStr();
1924 maya 3227
1925 maya 3393 DestPtr = GetLinePtr(PageStart+CursorBottom);
1926     if (n < CursorBottom-CursorTop+1) {
1927     SrcPtr = GetLinePtr(PageStart+CursorBottom-n);
1928     for (i=CursorBottom-n ; i>=CursorTop ; i--) {
1929     memmove(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
1930     memmove(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
1931     memmove(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
1932     memmove(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
1933     memmove(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
1934     SrcPtr = PrevLinePtr(SrcPtr);
1935     DestPtr = PrevLinePtr(DestPtr);
1936     }
1937     }
1938     else {
1939     n = CursorBottom - CursorTop + 1;
1940     }
1941     for (i = CursorTop+n-1; i>=CursorTop; i--) {
1942     memset(&(CodeBuff[DestPtr]),0x20,NumOfColumns);
1943     memset(&(AttrBuff[DestPtr]),AttrDefault,NumOfColumns);
1944     memset(&(AttrBuff2[DestPtr]),CurCharAttr.Attr2,NumOfColumns);
1945     memset(&(AttrBuffFG[DestPtr]),CurCharAttr.Fore,NumOfColumns);
1946     memset(&(AttrBuffBG[DestPtr]),CurCharAttr.Back,NumOfColumns);
1947     DestPtr = PrevLinePtr(DestPtr);
1948     }
1949 maya 3227
1950 maya 3393 DispScrollNLines(CursorTop,CursorBottom,-n);
1951 maya 3227 }
1952    
1953     void BuffClearScreen()
1954     { // clear screen
1955 maya 3393 if ((StatusLine>0) && (CursorY==NumOfLines-1)) {
1956     BuffScrollNLines(1); /* clear status line */
1957     }
1958     else { /* clear main screen */
1959     UpdateStr();
1960     BuffScroll(NumOfLines-StatusLine,NumOfLines-1-StatusLine);
1961     DispScrollNLines(WinOrgY,NumOfLines-1-StatusLine,NumOfLines-StatusLine);
1962     }
1963 maya 3227 }
1964    
1965     void BuffUpdateScroll()
1966     // Updates scrolling
1967     {
1968 maya 3393 UpdateStr();
1969     DispUpdateScroll();
1970 maya 3227 }
1971    
1972     void CursorUpWithScroll()
1973     {
1974 maya 3393 if ((0<CursorY) && (CursorY<CursorTop) ||
1975     (CursorTop<CursorY)) {
1976     MoveCursor(CursorX,CursorY-1);
1977     }
1978     else if (CursorY==CursorTop) {
1979     ScrollUp1Line();
1980     }
1981 maya 3227 }
1982    
1983     // called by BuffDblClk
1984     // check if a character is the word delimiter
1985     BOOL IsDelimiter(LONG Line, int CharPtr)
1986     {
1987 maya 3393 if ((AttrBuff[Line+CharPtr] & AttrKanji) !=0) {
1988     return (ts.DelimDBCS!=0);
1989     }
1990     return (strchr(ts.DelimList,CodeBuff[Line+CharPtr])!=NULL);
1991 maya 3227 }
1992    
1993     void GetMinMax(int i1, int i2, int i3,
1994 maya 3393 int *min, int *max)
1995 maya 3227 {
1996 maya 3393 if (i1<i2) {
1997     *min = i1;
1998     *max = i2;
1999     }
2000     else {
2001     *min = i2;
2002     *max = i1;
2003     }
2004     if (i3<*min) {
2005     *min = i3;
2006     }
2007     if (i3>*max) {
2008     *max = i3;
2009     }
2010 maya 3227 }
2011    
2012     /* start - ishizaki */
2013     static void invokeBrowser(LONG ptr)
2014     {
2015     #ifdef URL_EMPHASIS
2016 maya 3393 LONG i, start, end;
2017     char url[1024];
2018 maya 3227 char *uptr, ch;
2019    
2020 maya 3393 start = ptr;
2021     while (AttrBuff[start] & AttrURL) {
2022     start--;
2023     }
2024     start++;
2025 maya 3227
2026 maya 3393 end = ptr;
2027     while (AttrBuff[end] & AttrURL) {
2028     end++;
2029     }
2030     end--;
2031 maya 3227
2032 yutakapon 3405 if (start + (LONG)sizeof(url) <= end) {
2033     end = start + sizeof(url) - 1;
2034     end--; // '\0'の分は引いておく。
2035 maya 3393 }
2036 maya 3227 uptr = url;
2037 maya 3393 for (i = 0; i < end - start + 1; i++) {
2038 maya 3227 ch = CodeBuff[start + i];
2039     if ((start + i) % NumOfColumns == NumOfColumns - 1
2040     && ch == '\\') {
2041     // Emacs対応。行末に \ が来ている場合は、次の行に続くという意味で emacs が
2042     // 自動で挿入する文字なので、URLには含めないようにする。
2043     // (2007.8.7 yutaka)
2044    
2045     } else {
2046     *uptr++ = ch;
2047     }
2048 maya 3393 }
2049 maya 3227 *uptr = '\0';
2050 maya 3393 ShellExecute(NULL, NULL, url, NULL, NULL,SW_SHOWNORMAL);
2051 maya 3227 #endif
2052     }
2053     /* end - ishizaki */
2054    
2055     void ChangeSelectRegion()
2056     {
2057 maya 3393 POINT TempStart, TempEnd;
2058     int j, IStart, IEnd;
2059     BOOL Caret;
2060 maya 3227
2061 maya 3393 if ((SelectEndOld.x==SelectEnd.x) &&
2062     (SelectEndOld.y==SelectEnd.y)) {
2063     return;
2064     }
2065 maya 3227
2066 maya 3393 if (BoxSelect) {
2067     GetMinMax(SelectStart.x,SelectEndOld.x,SelectEnd.x,
2068     (int *)&TempStart.x,(int *)&TempEnd.x);
2069     GetMinMax(SelectStart.y,SelectEndOld.y,SelectEnd.y,
2070     (int *)&TempStart.y,(int *)&TempEnd.y);
2071     TempEnd.x--;
2072     Caret = IsCaretOn();
2073     if (Caret) {
2074     CaretOff();
2075     }
2076     DispInitDC();
2077     BuffUpdateRect(TempStart.x,TempStart.y-PageStart,
2078     TempEnd.x,TempEnd.y-PageStart);
2079     DispReleaseDC();
2080     if (Caret) {
2081     CaretOn();
2082     }
2083     SelectEndOld = SelectEnd;
2084     return;
2085     }
2086 maya 3227
2087 maya 3393 if ((SelectEndOld.y < SelectEnd.y) ||
2088     (SelectEndOld.y==SelectEnd.y) &&
2089     (SelectEndOld.x<=SelectEnd.x)) {
2090     TempStart = SelectEndOld;
2091     TempEnd.x = SelectEnd.x-1;
2092     TempEnd.y = SelectEnd.y;
2093     }
2094     else {
2095     TempStart = SelectEnd;
2096     TempEnd.x = SelectEndOld.x-1;
2097     TempEnd.y = SelectEndOld.y;
2098     }
2099     if (TempEnd.x < 0) {
2100     TempEnd.x = NumOfColumns - 1;
2101     TempEnd.y--;
2102     }
2103 maya 3227
2104 maya 3393 Caret = IsCaretOn();
2105     if (Caret) {
2106     CaretOff();
2107     }
2108     for (j = TempStart.y ; j <= TempEnd.y ; j++) {
2109     IStart = 0;
2110     IEnd = NumOfColumns-1;
2111     if (j==TempStart.y) {
2112     IStart = TempStart.x;
2113     }
2114     if (j==TempEnd.y) {
2115     IEnd = TempEnd.x;
2116     }
2117 maya 3227
2118 maya 3393 if ((IEnd>=IStart) && (j >= PageStart+WinOrgY) &&
2119     (j < PageStart+WinOrgY+WinHeight)) {
2120     DispInitDC();
2121     BuffUpdateRect(IStart,j-PageStart,IEnd,j-PageStart);
2122     DispReleaseDC();
2123     }
2124     }
2125     if (Caret) {
2126     CaretOn();
2127     }
2128 maya 3227
2129 maya 3393 SelectEndOld = SelectEnd;
2130 maya 3227 }
2131    
2132     BOOL BuffUrlDblClk(int Xw, int Yw)
2133     {
2134 maya 3393 int X, Y;
2135     LONG TmpPtr;
2136     BOOL url_invoked = FALSE;
2137 maya 3227
2138 maya 3393 if (! ts.EnableClickableUrl) {
2139     return FALSE;
2140     }
2141 maya 3227
2142 maya 3393 CaretOff();
2143 maya 3227
2144 maya 3393 DispConvWinToScreen(Xw,Yw,&X,&Y,NULL);
2145     Y = Y + PageStart;
2146     if ((Y<0) || (Y>=BuffEnd)) {
2147     return 0;
2148     }
2149     if (X<0) X = 0;
2150     if (X>=NumOfColumns) {
2151     X = NumOfColumns-1;
2152     }
2153 maya 3227
2154 maya 3393 if ((Y>=0) && (Y<BuffEnd)) {
2155     LockBuffer();
2156     TmpPtr = GetLinePtr(Y);
2157     /* start - ishizaki */
2158     if (AttrBuff[TmpPtr+X] & AttrURL) {
2159     BoxSelect = FALSE;
2160     SelectEnd = SelectStart;
2161     ChangeSelectRegion();
2162 maya 3227
2163 maya 3393 url_invoked = TRUE;
2164     invokeBrowser(TmpPtr+X);
2165 maya 3227
2166 maya 3393 SelectStart.x = 0;
2167     SelectStart.y = 0;
2168     SelectEnd.x = 0;
2169     SelectEnd.y = 0;
2170     SelectEndOld.x = 0;
2171     SelectEndOld.y = 0;
2172     Selected = FALSE;
2173     }
2174     UnlockBuffer();
2175     }
2176     return url_invoked;
2177 maya 3227 }
2178    
2179     void BuffDblClk(int Xw, int Yw)
2180     // Select a word at (Xw, Yw) by mouse double click
2181     // Xw: horizontal position in window coordinate (pixels)
2182     // Yw: vertical
2183     {
2184 maya 3393 int X, Y, YStart, YEnd;
2185     int IStart, IEnd, i;
2186     LONG TmpPtr;
2187     BYTE b;
2188     BOOL DBCS;
2189 maya 3227
2190 maya 3393 CaretOff();
2191 maya 3227
2192 maya 3393 DispConvWinToScreen(Xw,Yw,&X,&Y,NULL);
2193     Y = Y + PageStart;
2194     if ((Y<0) || (Y>=BuffEnd)) {
2195     return;
2196     }
2197     if (X<0) X = 0;
2198     if (X>=NumOfColumns) X = NumOfColumns-1;
2199 maya 3227
2200 maya 3393 BoxSelect = FALSE;
2201     LockBuffer();
2202     SelectEnd = SelectStart;
2203     ChangeSelectRegion();
2204 maya 3227
2205 maya 3393 if ((Y>=0) && (Y<BuffEnd)) {
2206     TmpPtr = GetLinePtr(Y);
2207 maya 3227
2208 maya 3393 IStart = X;
2209     IStart = LeftHalfOfDBCS(TmpPtr,IStart);
2210     IEnd = IStart;
2211     YStart = YEnd = Y;
2212 maya 3227
2213 maya 3393 if (IsDelimiter(TmpPtr,IStart)) {
2214     b = CodeBuff[TmpPtr+IStart];
2215     DBCS = (AttrBuff[TmpPtr+IStart] & AttrKanji) != 0;
2216     while ((b==CodeBuff[TmpPtr+IStart]) ||
2217     DBCS &&
2218     ((AttrBuff[TmpPtr+IStart] & AttrKanji)!=0)) {
2219     MoveCharPtr(TmpPtr,&IStart,-1); // move left
2220     if (ts.EnableContinuedLineCopy) {
2221     if (IStart<=0) {
2222     // 左端の場合
2223     if (YStart>0 && AttrBuff[TmpPtr] & AttrLineContinued) {
2224     // 前の行に移動する
2225     YStart--;
2226     TmpPtr = GetLinePtr(YStart);
2227     IStart = NumOfColumns;
2228     }
2229     else {
2230     break;
2231     }
2232     }
2233     }
2234     else {
2235     if (IStart<=0) {
2236     // 左端の場合は終わり
2237     break;
2238     }
2239     }
2240 maya 3227 }
2241 maya 3393 if ((b!=CodeBuff[TmpPtr+IStart]) &&
2242     ! (DBCS && ((AttrBuff[TmpPtr+IStart] & AttrKanji)!=0))) {
2243     // 最終位置が Delimiter でない場合にはひとつ右にずらす
2244     if (ts.EnableContinuedLineCopy && IStart == NumOfColumns-1) {
2245     // 右端の場合には次の行へ移動する
2246     YStart++;
2247     TmpPtr = GetLinePtr(YStart);
2248     IStart = 0;
2249     }
2250     else {
2251     MoveCharPtr(TmpPtr,&IStart,1);
2252     }
2253 maya 3227 }
2254 maya 3393
2255     // 行が移動しているかもしれないので、クリックした行を取り直す
2256     TmpPtr = GetLinePtr(YEnd);
2257     i = 1;
2258     while (((b==CodeBuff[TmpPtr+IEnd]) ||
2259     DBCS &&
2260     ((AttrBuff[TmpPtr+IEnd] & AttrKanji)!=0))) {
2261     i = MoveCharPtr(TmpPtr,&IEnd,1); // move right
2262     if (ts.EnableContinuedLineCopy) {
2263     if (i==0) {
2264     // 右端の場合
2265     if (YEnd<BuffEnd &&
2266     AttrBuff[TmpPtr+IEnd+1+DBCS] & AttrLineContinued) {
2267     // 次の行に移動する
2268     YEnd++;
2269     TmpPtr = GetLinePtr(YEnd);
2270     IEnd = 0;
2271