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 3754 - (hide annotations) (download) (as text)
Thu Jan 28 13:42:34 2010 UTC (14 years, 2 months ago) by doda
File MIME type: text/x-csrc
File size: 80654 byte(s)
Alternate Screen Buffer 使用中に横幅を縮めた時の復元処理がおかしかったのを修正。

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