Develop and Download Open Source Software

Browse Subversion Repository

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4102 - (hide annotations) (download) (as text)
Mon Sep 13 07:07:46 2010 UTC (13 years, 7 months ago) by doda
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 85175 byte(s)
DECSED で左端の表示がクリアされなかったのを修正。

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