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 8740 - (hide annotations) (download) (as text)
Sun Apr 26 14:33:56 2020 UTC (3 years, 11 months ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/buffer.c
File MIME type: text/x-csrc
File size: 148060 byte(s)
buffer.c で UNICODE_INTERNAL_BUFF を使用しないようにした

- 常にUnicodeとする
- 他のソースでも要チェック
1 doda 6806 /*
2     * Copyright (C) 1994-1998 T. Teranishi
3 doda 8480 * (C) 2004-2020 TeraTerm Project
4 doda 6806 * All rights reserved.
5     *
6 doda 6841 * Redistribution and use in source and binary forms, with or without
7     * modification, are permitted provided that the following conditions
8     * are met:
9 doda 6806 *
10 doda 6841 * 1. Redistributions of source code must retain the above copyright
11     * notice, this list of conditions and the following disclaimer.
12     * 2. Redistributions in binary form must reproduce the above copyright
13     * notice, this list of conditions and the following disclaimer in the
14     * documentation and/or other materials provided with the distribution.
15     * 3. The name of the author may not be used to endorse or promote products
16     * derived from this software without specific prior written permission.
17 doda 6806 *
18 doda 6841 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
19     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 doda 6806 */
29 maya 3227
30     /* TERATERM.EXE, scroll buffer routines */
31    
32     #include "teraterm.h"
33     #include <string.h>
34 yutakapon 4707 #include <stdio.h>
35 doda 8445 #include <windows.h>
36     #define _CRTDBG_MAP_ALLOC
37     #include <crtdbg.h>
38     #include <mbstring.h>
39     #include <assert.h>
40     #include <errno.h>
41 maya 3227
42 doda 8445 #include "tttypes.h"
43 maya 3227 #include "ttwinman.h"
44     #include "teraprn.h"
45     #include "vtdisp.h"
46     #include "telnet.h"
47     #include "ttplug.h" /* TTPLUG */
48 doda 8445 #include "codeconv.h"
49     #include "unicode.h"
50 maya 3227 #include "buffer.h"
51 doda 8445 #include "unicode_test.h"
52 zmatsuo 8584 #include "asprintf.h"
53 maya 3227
54 doda 8445 typedef unsigned long char32_t; // C++11
55    
56     // �o�b�t�@�������p1������������
57     typedef struct {
58     char32_t u32;
59     char32_t u32_last;
60     char WidthProperty; // 'W' or 'F' or 'H' or 'A' (����������)
61     char HalfWidth; // TRUE/FALSE = ���p/�S�p (�\������������������)
62     char Padding; // TRUE = �S�p�������l���� or �s�����l����
63     char Emoji; // TRUE = �G����
64 zmatsuo 8585 unsigned char CombinationCharCount16; // charactor count
65     unsigned char CombinationCharSize16; // buffer size
66     unsigned char CombinationCharCount32;
67     unsigned char CombinationCharSize32;
68 doda 8445 wchar_t *pCombinationChars16;
69     char32_t *pCombinationChars32;
70     wchar_t wc2[2];
71     } buff_char_t;
72    
73 maya 3227 #define BuffXMax TermWidthMax
74     //#define BuffYMax 100000
75     //#define BuffSizeMax 8000000
76     // �X�N���[���o�b�t�@�����������g�� (2004.11.28 yutaka)
77     #define BuffYMax 500000
78     #define BuffSizeMax (BuffYMax * 80)
79    
80     // status line
81 doda 6435 int StatusLine; //0: none 1: shown
82 doda 5324 /* top, bottom, left & right margin */
83     int CursorTop, CursorBottom, CursorLeftM, CursorRightM;
84 doda 8400 BOOL Selected, Selecting;
85 maya 3227 BOOL Wrap;
86    
87     static WORD TabStops[256];
88     static int NTabStops;
89    
90     static WORD BuffLock = 0;
91    
92     static PCHAR CodeBuff; /* Character code buffer */
93     static PCHAR AttrBuff; /* Attribute buffer */
94     static PCHAR AttrBuff2; /* Color attr buffer */
95     static PCHAR AttrBuffFG; /* Foreground color attr buffer */
96     static PCHAR AttrBuffBG; /* Background color attr buffer */
97 zmatsuo 8739 #define ATR 0
98     #if ATR
99 maya 3227 static PCHAR CodeLine;
100     static PCHAR AttrLine;
101     static PCHAR AttrLine2;
102     static PCHAR AttrLineFG;
103     static PCHAR AttrLineBG;
104 doda 8445 static buff_char_t *CodeLineW;
105     #endif
106 zmatsuo 8739 static buff_char_t *CodeBuffW;
107 maya 3227 static LONG LinePtr;
108     static LONG BufferSize;
109     static int NumOfLinesInBuff;
110     static int BuffStartAbs, BuffEndAbs;
111 doda 8400 static POINT SelectStart, SelectStartTmp, SelectEnd, SelectEndOld;
112     static DWORD SelectStartTime;
113 maya 3227 static BOOL BoxSelect;
114     static POINT DblClkStart, DblClkEnd;
115    
116 doda 8445 // �`��
117     static int StrChangeStart; // �`���J�n X (Y=CursorY)
118     static int StrChangeCount; // �`���L�����N�^��(���p�P��),0�������`����������������
119 maya 3227
120     static BOOL SeveralPageSelect; // add (2005.5.15 yutaka)
121    
122     static TCharAttr CurCharAttr;
123    
124 doda 8445 static char *SaveBuff = NULL;
125     static int SaveBuffX;
126     static int SaveBuffY;
127 doda 3743
128 doda 8445 static void BuffDrawLineI(int DrawX, int DrawY, int SY, int IStart, int IEnd);
129    
130     static void BuffSetChar2(buff_char_t *buff, char32_t u32, char property, BOOL half_width, char emoji)
131 maya 3227 {
132 doda 8445 size_t wstr_len;
133     buff_char_t *p = buff;
134     if (p->pCombinationChars16 != NULL) {
135     free(p->pCombinationChars16);
136     p->pCombinationChars16 = NULL;
137     }
138     p->CombinationCharCount16 = 0;
139     p->CombinationCharSize16 = 0;
140     if (p->pCombinationChars32 != NULL) {
141     free(p->pCombinationChars32);
142     p->pCombinationChars32 = NULL;
143     }
144     p->CombinationCharCount32 = 0;
145     p->CombinationCharSize32 = 0;
146     p->WidthProperty = property;
147     p->HalfWidth = (char)half_width;
148     p->u32 = u32;
149     p->u32_last = u32;
150     p->Padding = FALSE;
151     p->Emoji = emoji;
152    
153     //
154     wstr_len = UTF32ToUTF16(u32, &p->wc2[0], 2);
155     switch (wstr_len) {
156     case 0:
157     default:
158     p->wc2[0] = 0;
159     p->wc2[1] = 0;
160     break;
161     case 1:
162     p->wc2[1] = 0;
163     break;
164     case 2:
165     break;
166     }
167     }
168    
169     static void BuffSetChar(buff_char_t *buff, char32_t u32, char property)
170     {
171     BuffSetChar2(buff, u32, property, TRUE, FALSE);
172     }
173    
174     /**
175     * �����������A�R���r�l�[�V����
176     */
177     static void BuffAddChar(buff_char_t *buff, char32_t u32)
178     {
179     buff_char_t *p = buff;
180     assert(p->u32 != 0);
181     // �������������������g������
182     if (p->CombinationCharSize16 < p->CombinationCharCount16 + 2) {
183     size_t new_size = p->CombinationCharSize16;
184     new_size = new_size == 0 ? 5 : new_size * 2;
185     p->pCombinationChars16 = realloc(p->pCombinationChars16, sizeof(wchar_t) * new_size);
186     p->CombinationCharSize16 = (char)new_size;
187     }
188     if (p->CombinationCharSize32 < p->CombinationCharCount32 + 2) {
189     size_t new_size = p->CombinationCharSize32;
190     new_size = new_size == 0 ? 5 : new_size * 2;
191     p->pCombinationChars32 = realloc(p->pCombinationChars32, sizeof(char32_t) * new_size);
192     p->CombinationCharSize32 = (char)new_size;
193     }
194    
195     // UTF-32
196     p->u32_last = u32;
197     p->pCombinationChars32[(size_t)p->CombinationCharCount32] = u32;
198     p->CombinationCharCount32++;
199    
200     // UTF-16
201     {
202     wchar_t *u16 = &p->pCombinationChars16[(size_t)p->CombinationCharCount16];
203     size_t wlen = UTF32ToUTF16(u32, u16, 2);
204     p->CombinationCharCount16 += (char)wlen;
205     }
206     }
207    
208     static void memcpyW(buff_char_t *dest, const buff_char_t *src, size_t count)
209     {
210     size_t i;
211     memcpy(dest, src, count * sizeof(buff_char_t));
212     for (i=0; i<count; i++) {
213     buff_char_t *p = &dest[i];
214     size_t size = p->CombinationCharSize16;
215     if (size > 0) {
216     wchar_t *new_buf = malloc(sizeof(wchar_t) * size);
217     memcpy(new_buf, p->pCombinationChars16, sizeof(wchar_t) * size);
218     p->pCombinationChars16 = new_buf;
219     }
220     size = p->CombinationCharSize32;
221     if (size > 0) {
222     char32_t *new_buf = malloc(sizeof(char32_t) * size);
223     memcpy(new_buf, p->pCombinationChars32, sizeof(char32_t) * size);
224     p->pCombinationChars32 = new_buf;
225     }
226     }
227     }
228    
229     static void memsetW(buff_char_t *dest, wchar_t ch, size_t count)
230     {
231     size_t i;
232     for (i=0; i<count; i++) {
233     BuffSetChar(dest, ch, 'H');
234     dest++;
235     }
236     }
237    
238     static void memmoveW(buff_char_t *dest, const buff_char_t *src, size_t count)
239     {
240     memmove(dest, src, count * sizeof(buff_char_t));
241     }
242    
243     static BOOL IsBuffPadding(const buff_char_t *b)
244     {
245     if (b->Padding == TRUE)
246     return TRUE;
247     if (b->u32 == 0)
248     return TRUE;
249     return FALSE;
250     }
251    
252     static BOOL IsBuffFullWidth(const buff_char_t *b)
253     {
254     if (b->HalfWidth == FALSE)
255     return TRUE;
256     return FALSE;
257     }
258    
259     static LONG GetLinePtr(int Line)
260     {
261 maya 3393 LONG Ptr;
262 maya 3227
263 maya 3393 Ptr = (LONG)(BuffStartAbs + Line) * (LONG)(NumOfColumns);
264     while (Ptr>=BufferSize) {
265     Ptr = Ptr - BufferSize;
266     }
267     return Ptr;
268 maya 3227 }
269    
270 doda 8445 static LONG NextLinePtr(LONG Ptr)
271 maya 3227 {
272 maya 3393 Ptr = Ptr + (LONG)NumOfColumns;
273     if (Ptr >= BufferSize) {
274     Ptr = Ptr - BufferSize;
275     }
276     return Ptr;
277 maya 3227 }
278    
279 doda 8445 static LONG PrevLinePtr(LONG Ptr)
280 maya 3227 {
281 maya 3393 Ptr = Ptr - (LONG)NumOfColumns;
282     if (Ptr < 0) {
283     Ptr = Ptr + BufferSize;
284     }
285     return Ptr;
286 maya 3227 }
287    
288 doda 8445 static BOOL ChangeBuffer(int Nx, int Ny)
289 maya 3227 {
290 zmatsuo 8739 // buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
291     // PCHAR CodeLine = &CodeBuff[LinePtr];
292 maya 3393 LONG NewSize;
293     int NxCopy, NyCopy, i;
294     PCHAR CodeDest, AttrDest, AttrDest2, AttrDestFG, AttrDestBG;
295     LONG SrcPtr, DestPtr;
296     WORD LockOld;
297 doda 8445 buff_char_t *CodeDestW;
298 maya 3227
299 maya 3393 if (Nx > BuffXMax) {
300     Nx = BuffXMax;
301     }
302     if (ts.ScrollBuffMax > BuffYMax) {
303     ts.ScrollBuffMax = BuffYMax;
304     }
305     if (Ny > ts.ScrollBuffMax) {
306     Ny = ts.ScrollBuffMax;
307     }
308 maya 3227
309 maya 3393 if ( (LONG)Nx * (LONG)Ny > BuffSizeMax ) {
310     Ny = BuffSizeMax / Nx;
311     }
312 maya 3227
313 maya 3393 NewSize = (LONG)Nx * (LONG)Ny;
314 maya 3227
315 doda 8445 CodeDest = NULL;
316     AttrDest = NULL;
317     AttrDest2 = NULL;
318     AttrDestFG = NULL;
319     AttrDestBG = NULL;
320     CodeDestW = NULL;
321 maya 3227
322 doda 8445 CodeDest = malloc(NewSize);
323     if (CodeDest == NULL) {
324 doda 3686 goto allocate_error;
325 maya 3393 }
326 doda 8445 AttrDest = malloc(NewSize);
327     if (AttrDest == NULL) {
328 doda 3686 goto allocate_error;
329 maya 3393 }
330 doda 8445 AttrDest2 = malloc(NewSize);
331     if (AttrDest2 == NULL) {
332 doda 3686 goto allocate_error;
333 maya 3393 }
334 doda 8445 AttrDestFG = malloc(NewSize);
335     if (AttrDestFG == NULL) {
336 doda 3686 goto allocate_error;
337 maya 3393 }
338 doda 8445 AttrDestBG = malloc(NewSize);
339     if (AttrDestBG == NULL) {
340 doda 3686 goto allocate_error;
341 maya 3393 }
342 doda 8445 CodeDestW = malloc(NewSize * sizeof(buff_char_t));
343     if (CodeDestW == NULL) {
344     goto allocate_error;
345     }
346 maya 3227
347 maya 3393 memset(&CodeDest[0], 0x20, NewSize);
348 doda 8445 memset(&CodeDestW[0], 0, NewSize * sizeof(buff_char_t));
349     memsetW(&CodeDestW[0], 0x20, NewSize);
350 maya 3393 memset(&AttrDest[0], AttrDefault, NewSize);
351     memset(&AttrDest2[0], AttrDefault, NewSize);
352     memset(&AttrDestFG[0], AttrDefaultFG, NewSize);
353     memset(&AttrDestBG[0], AttrDefaultBG, NewSize);
354 doda 8445 if ( CodeBuff != NULL ) {
355 maya 3393 if ( NumOfColumns > Nx ) {
356     NxCopy = Nx;
357     }
358     else {
359     NxCopy = NumOfColumns;
360     }
361 maya 3227
362 maya 3393 if ( BuffEnd > Ny ) {
363     NyCopy = Ny;
364     }
365     else {
366     NyCopy = BuffEnd;
367     }
368     LockOld = BuffLock;
369     LockBuffer();
370     SrcPtr = GetLinePtr(BuffEnd-NyCopy);
371     DestPtr = 0;
372     for (i = 1 ; i <= NyCopy ; i++) {
373     memcpy(&CodeDest[DestPtr],&CodeBuff[SrcPtr],NxCopy);
374 doda 8445 memcpyW(&CodeDestW[DestPtr],&CodeBuffW[SrcPtr],NxCopy);
375 maya 3393 memcpy(&AttrDest[DestPtr],&AttrBuff[SrcPtr],NxCopy);
376     memcpy(&AttrDest2[DestPtr],&AttrBuff2[SrcPtr],NxCopy);
377     memcpy(&AttrDestFG[DestPtr],&AttrBuffFG[SrcPtr],NxCopy);
378     memcpy(&AttrDestBG[DestPtr],&AttrBuffBG[SrcPtr],NxCopy);
379 doda 3766 if (AttrDest[DestPtr+NxCopy-1] & AttrKanji) {
380     CodeDest[DestPtr+NxCopy-1] = ' ';
381     AttrDest[DestPtr+NxCopy-1] ^= AttrKanji;
382     }
383 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
384     DestPtr = DestPtr + (LONG)Nx;
385     }
386     FreeBuffer();
387     }
388     else {
389     LockOld = 0;
390     NyCopy = NumOfLines;
391     Selected = FALSE;
392     }
393 maya 3227
394 maya 3393 if (Selected) {
395     SelectStart.y = SelectStart.y - BuffEnd + NyCopy;
396     SelectEnd.y = SelectEnd.y - BuffEnd + NyCopy;
397     if (SelectStart.y < 0) {
398     SelectStart.y = 0;
399     SelectStart.x = 0;
400     }
401     if (SelectEnd.y<0) {
402     SelectEnd.x = 0;
403     SelectEnd.y = 0;
404     }
405 maya 3227
406 maya 3393 Selected = (SelectEnd.y > SelectStart.y) ||
407 zmatsuo 8411 ((SelectEnd.y == SelectStart.y) &&
408 maya 3393 (SelectEnd.x > SelectStart.x));
409     }
410 maya 3227
411 doda 8445 CodeBuff = CodeDest;
412     AttrBuff = AttrDest;
413     AttrBuff2 = AttrDest2;
414     AttrBuffFG = AttrDestFG;
415     AttrBuffBG = AttrDestBG;
416     CodeBuffW = CodeDestW;
417 maya 3393 BufferSize = NewSize;
418     NumOfLinesInBuff = Ny;
419     BuffStartAbs = 0;
420     BuffEnd = NyCopy;
421 maya 3227
422 maya 3393 if (BuffEnd==NumOfLinesInBuff) {
423     BuffEndAbs = 0;
424     }
425     else {
426     BuffEndAbs = BuffEnd;
427     }
428 maya 3227
429 maya 3393 PageStart = BuffEnd - NumOfLines;
430    
431     LinePtr = 0;
432     if (LockOld>0) {
433 zmatsuo 8739 #if ATR
434 maya 3393 CodeLine = CodeBuff;
435 doda 8445 CodeLineW = CodeBuffW;
436 maya 3393 AttrLine = AttrBuff;
437     AttrLine2 = AttrBuff2;
438     AttrLineFG = AttrBuffFG;
439     AttrLineBG = AttrBuffBG;
440 zmatsuo 8739 #endif
441 maya 3393 }
442     else {
443 doda 8445 ;
444 maya 3393 }
445     BuffLock = LockOld;
446    
447     return TRUE;
448 doda 3686
449     allocate_error:
450 doda 8445 if (CodeDest) free(CodeDest);
451     if (AttrDest) free(AttrDest);
452     if (AttrDest2) free(AttrDest2);
453     if (AttrDestFG) free(AttrDestFG);
454     if (AttrDestBG) free(AttrDestBG);
455     if (CodeDestW) free(CodeDestW);
456 doda 3686 return FALSE;
457 maya 3227 }
458    
459     void InitBuffer()
460     {
461 maya 3393 int Ny;
462 maya 3227
463 maya 3393 /* setup terminal */
464     NumOfColumns = ts.TerminalWidth;
465     NumOfLines = ts.TerminalHeight;
466 maya 3227
467 doda 6785 if (NumOfColumns <= 0)
468     NumOfColumns = 80;
469     else if (NumOfColumns > TermWidthMax)
470     NumOfColumns = TermWidthMax;
471    
472     if (NumOfLines <= 0)
473     NumOfLines = 24;
474     else if (NumOfLines > TermHeightMax)
475     NumOfLines = TermHeightMax;
476    
477 maya 3393 /* setup window */
478     if (ts.EnableScrollBuff>0) {
479     if (ts.ScrollBuffSize < NumOfLines) {
480     ts.ScrollBuffSize = NumOfLines;
481     }
482     Ny = ts.ScrollBuffSize;
483     }
484     else {
485     Ny = NumOfLines;
486     }
487 maya 3227
488 maya 3393 if (! ChangeBuffer(NumOfColumns,Ny)) {
489     PostQuitMessage(0);
490     }
491 maya 3227
492 maya 3393 if (ts.EnableScrollBuff>0) {
493     ts.ScrollBuffSize = NumOfLinesInBuff;
494     }
495 maya 3227
496 maya 3393 StatusLine = 0;
497 maya 3227 }
498    
499 doda 8445 static void NewLine(int Line)
500 maya 3227 {
501 maya 3393 LinePtr = GetLinePtr(Line);
502 zmatsuo 8739 #if ATR
503 maya 3393 CodeLine = &CodeBuff[LinePtr];
504     AttrLine = &AttrBuff[LinePtr];
505     AttrLine2 = &AttrBuff2[LinePtr];
506     AttrLineFG = &AttrBuffFG[LinePtr];
507     AttrLineBG = &AttrBuffBG[LinePtr];
508 doda 8445 CodeLineW = &CodeBuffW[LinePtr];
509     #endif
510 maya 3227 }
511    
512     void LockBuffer()
513     {
514 maya 3393 BuffLock++;
515     if (BuffLock>1) {
516     return;
517     }
518     NewLine(PageStart+CursorY);
519 maya 3227 }
520    
521     void UnlockBuffer()
522     {
523 maya 3393 if (BuffLock==0) {
524     return;
525     }
526     BuffLock--;
527     if (BuffLock>0) {
528     return;
529     }
530 maya 3227 }
531    
532     void FreeBuffer()
533     {
534 maya 3393 BuffLock = 1;
535     UnlockBuffer();
536 doda 8445 if (CodeBuff!=NULL) {
537     free(CodeBuff);
538     CodeBuff = NULL;
539 maya 3393 }
540 doda 8445 if (CodeBuffW != NULL) {
541     free(CodeBuffW);
542     CodeBuffW = NULL;
543 maya 3393 }
544 doda 8445 if (AttrBuff!=NULL) {
545     free(AttrBuff);
546     AttrBuff = NULL;
547 maya 3393 }
548 doda 8445 if (AttrBuff2!=NULL) {
549     free(AttrBuff2);
550     AttrBuff2 = NULL;
551 maya 3393 }
552 doda 8445 if (AttrBuffFG!=NULL) {
553     free(AttrBuffFG);
554     AttrBuffFG = NULL;
555 maya 3393 }
556 doda 8445 if (AttrBuffBG!=NULL) {
557     free(AttrBuffBG);
558     AttrBuffBG = NULL;
559     }
560 maya 3227 }
561    
562     void BuffAllSelect()
563     {
564     SelectStart.x = 0;
565     SelectStart.y = 0;
566     SelectEnd.x = 0;
567     SelectEnd.y = BuffEnd;
568     // SelectEnd.x = NumOfColumns;
569     // SelectEnd.y = BuffEnd - 1;
570 doda 8400 Selecting = TRUE;
571 maya 3227 }
572    
573     void BuffScreenSelect()
574     {
575     int X, Y;
576     DispConvWinToScreen(0, 0, &X, &Y, NULL);
577     SelectStart.x = X;
578     SelectStart.y = Y + PageStart;
579     SelectEnd.x = 0;
580     SelectEnd.y = SelectStart.y + NumOfLines;
581     // SelectEnd.x = X + NumOfColumns;
582     // SelectEnd.y = Y + PageStart + NumOfLines - 1;
583 doda 8400 Selecting = TRUE;
584 maya 3227 }
585    
586     void BuffCancelSelection()
587     {
588     SelectStart.x = 0;
589     SelectStart.y = 0;
590     SelectEnd.x = 0;
591     SelectEnd.y = 0;
592 doda 8400 Selecting = FALSE;
593 maya 3227 }
594    
595     void BuffReset()
596     // Reset buffer status. don't update real display
597     // called by ResetTerminal()
598     {
599 maya 3393 int i;
600 maya 3227
601 maya 3393 /* Cursor */
602     NewLine(PageStart);
603     WinOrgX = 0;
604     WinOrgY = 0;
605     NewOrgX = 0;
606     NewOrgY = 0;
607 maya 3227
608 maya 3393 /* Top/bottom margin */
609     CursorTop = 0;
610     CursorBottom = NumOfLines-1;
611 doda 5324 CursorLeftM = 0;
612     CursorRightM = NumOfColumns-1;
613 maya 3227
614 maya 3393 /* Tab stops */
615     NTabStops = (NumOfColumns-1) >> 3;
616     for (i=1 ; i<=NTabStops ; i++) {
617 doda 8445 TabStops[i-1] = (WORD)(i*8);
618 maya 3393 }
619 maya 3227
620 maya 3393 /* Initialize text selection region */
621     SelectStart.x = 0;
622     SelectStart.y = 0;
623     SelectEnd = SelectStart;
624     SelectEndOld = SelectStart;
625     Selected = FALSE;
626 maya 3227
627 maya 3393 StrChangeCount = 0;
628     Wrap = FALSE;
629     StatusLine = 0;
630 maya 3227
631 maya 3393 SeveralPageSelect = FALSE; // yutaka
632 doda 3745
633     /* Alternate Screen Buffer */
634     BuffDiscardSavedScreen();
635 maya 3227 }
636    
637     void BuffScroll(int Count, int Bottom)
638     {
639 maya 3393 int i, n;
640     LONG SrcPtr, DestPtr;
641     int BuffEndOld;
642 maya 3227
643 maya 3393 if (Count>NumOfLinesInBuff) {
644     Count = NumOfLinesInBuff;
645     }
646 maya 3227
647 maya 3393 DestPtr = GetLinePtr(PageStart+NumOfLines-1+Count);
648     n = Count;
649     if (Bottom<NumOfLines-1) {
650     SrcPtr = GetLinePtr(PageStart+NumOfLines-1);
651     for (i=NumOfLines-1; i>=Bottom+1; i--) {
652     memcpy(&(CodeBuff[DestPtr]),&(CodeBuff[SrcPtr]),NumOfColumns);
653 doda 8445 memcpyW(&(CodeBuffW[DestPtr]),&(CodeBuffW[SrcPtr]),NumOfColumns);
654 maya 3393 memcpy(&(AttrBuff[DestPtr]),&(AttrBuff[SrcPtr]),NumOfColumns);
655     memcpy(&(AttrBuff2[DestPtr]),&(AttrBuff2[SrcPtr]),NumOfColumns);
656     memcpy(&(AttrBuffFG[DestPtr]),&(AttrBuffFG[SrcPtr]),NumOfColumns);
657     memcpy(&(AttrBuffBG[DestPtr]),&(AttrBuffBG[SrcPtr]),NumOfColumns);
658     memset(&(CodeBuff[SrcPtr]),0x20,NumOfColumns);
659 doda 8445 memsetW(&(CodeBuffW[SrcPtr]),0x20,NumOfColumns);
660 maya 3393 memset(&(AttrBuff[SrcPtr]),AttrDefault,NumOfColumns);
661 doda 4070 memset(&(AttrBuff2[SrcPtr]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
662 maya 3393 memset(&(AttrBuffFG[SrcPtr]),CurCharAttr.Fore,NumOfColumns);
663     memset(&(AttrBuffBG[SrcPtr]),CurCharAttr.Back,NumOfColumns);
664     SrcPtr = PrevLinePtr(SrcPtr);
665     DestPtr = PrevLinePtr(DestPtr);
666     n--;
667     }
668     }
669     for (i = 1 ; i <= n ; i++) {
670     memset(&CodeBuff[DestPtr],0x20,NumOfColumns);
671 doda 8445 memsetW(&CodeBuffW[DestPtr],0x20,NumOfColumns);
672 maya 3393 memset(&AttrBuff[DestPtr],AttrDefault,NumOfColumns);
673 doda 4070 memset(&AttrBuff2[DestPtr],CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns);
674 maya 3393 memset(&AttrBuffFG[DestPtr],CurCharAttr.Fore,NumOfColumns);
675     memset(&AttrBuffBG[DestPtr],CurCharAttr.Back,NumOfColumns);
676     DestPtr = PrevLinePtr(DestPtr);
677     }
678 maya 3227
679 maya 3393 BuffEndAbs = BuffEndAbs + Count;
680     if (BuffEndAbs >= NumOfLinesInBuff) {
681     BuffEndAbs = BuffEndAbs - NumOfLinesInBuff;
682     }
683     BuffEndOld = BuffEnd;
684     BuffEnd = BuffEnd + Count;
685     if (BuffEnd >= NumOfLinesInBuff) {
686     BuffEnd = NumOfLinesInBuff;
687     BuffStartAbs = BuffEndAbs;
688     }
689     PageStart = BuffEnd-NumOfLines;
690 maya 3227
691 maya 3393 if (Selected) {
692     SelectStart.y = SelectStart.y - Count + BuffEnd - BuffEndOld;
693     SelectEnd.y = SelectEnd.y - Count + BuffEnd - BuffEndOld;
694     if ( SelectStart.y<0 ) {
695     SelectStart.x = 0;
696     SelectStart.y = 0;
697     }
698     if ( SelectEnd.y<0 ) {
699     SelectEnd.x = 0;
700     SelectEnd.y = 0;
701     }
702     Selected = (SelectEnd.y > SelectStart.y) ||
703     ((SelectEnd.y==SelectStart.y) &&
704     (SelectEnd.x > SelectStart.x));
705     }
706 maya 3227
707 maya 3393 NewLine(PageStart+CursorY);
708 maya 3227 }
709    
710 zmatsuo 8739 #if 0
711     static void NextLine()
712 maya 3227 {
713 maya 3393 LinePtr = NextLinePtr(LinePtr);
714 zmatsuo 8739 #if ATR
715 maya 3393 CodeLine = &CodeBuff[LinePtr];
716     AttrLine = &AttrBuff[LinePtr];
717     AttrLine2 = &AttrBuff2[LinePtr];
718     AttrLineFG = &AttrBuffFG[LinePtr];
719     AttrLineBG = &AttrBuffBG[LinePtr];
720 doda 8445 CodeLineW = &CodeBuffW[LinePtr];
721     #endif
722 maya 3227 }
723 zmatsuo 8739 #endif
724 maya 3227
725 zmatsuo 8739 #if 0
726     static void PrevLine()
727 maya 3227 {
728 maya 3393 LinePtr = PrevLinePtr(LinePtr);
729 zmatsuo 8739 #if ATR
730 maya 3393 CodeLine = &CodeBuff[LinePtr];
731     AttrLine = &AttrBuff[LinePtr];
732     AttrLine2 = &AttrBuff2[LinePtr];
733     AttrLineFG = &AttrBuffFG[LinePtr];
734     AttrLineBG = &AttrBuffBG[LinePtr];
735 doda 8445 CodeLineW = &CodeBuffW[LinePtr];
736     #endif
737 maya 3227 }
738 zmatsuo 8739 #endif
739 maya 3227
740     // If cursor is on left/right half of a Kanji, erase it.
741     // LR: left(0)/right(1) flag
742 doda 8445 // LR 0 �J�[�\��������������
743     // 1 �J�[�\�����������E��
744     static void EraseKanji(int LR)
745     {
746 zmatsuo 8739 #if !ATR
747     PCHAR CodeLine = &CodeBuff[LinePtr];
748     PCHAR AttrLine = &AttrBuff[LinePtr];
749     PCHAR AttrLine2 = &AttrBuff2[LinePtr];
750     PCHAR AttrLineFG = &AttrBuffFG[LinePtr];
751     PCHAR AttrLineBG = &AttrBuffBG[LinePtr];
752     buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
753     #endif
754    
755 doda 8445 buff_char_t *p;
756     int bx;
757     if (CursorX < LR) {
758     // �S�p������������
759     return;
760     }
761     bx = CursorX-LR;
762     p = &CodeLineW[bx];
763     if (IsBuffFullWidth(p)) {
764     // �S�p��������
765     BuffSetChar(p, ' ', 'H');
766     CodeLine[bx] = 0x20;
767     AttrLine[bx] = CurCharAttr.Attr;
768     AttrLine2[bx] = CurCharAttr.Attr2;
769     AttrLineFG[bx] = CurCharAttr.Fore;
770     AttrLineBG[bx] = CurCharAttr.Back;
771     if (bx+1 < NumOfColumns) {
772     BuffSetChar(p + 1, ' ', 'H');
773     CodeLine[bx+1] = 0x20;
774     AttrLine[bx+1] = CurCharAttr.Attr;
775     AttrLine2[bx+1] = CurCharAttr.Attr2;
776     AttrLineFG[bx+1] = CurCharAttr.Fore;
777     AttrLineBG[bx+1] = CurCharAttr.Back;
778     }
779     }
780 maya 3227 }
781    
782 doda 5371 void EraseKanjiOnLRMargin(LONG ptr, int count)
783     {
784     int i;
785     LONG pos;
786    
787     if (count < 1)
788     return;
789    
790     for (i=0; i<count; i++) {
791     pos = ptr + CursorLeftM-1;
792     if (CursorLeftM>0 && (AttrBuff[pos] & AttrKanji)) {
793     CodeBuff[pos] = 0x20;
794 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
795 doda 5371 AttrBuff[pos] &= ~AttrKanji;
796     pos++;
797     CodeBuff[pos] = 0x20;
798 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
799 doda 5371 AttrBuff[pos] &= ~AttrKanji;
800     }
801     pos = ptr + CursorRightM;
802     if (CursorRightM < NumOfColumns-1 && (AttrBuff[pos] & AttrKanji)) {
803     CodeBuff[pos] = 0x20;
804 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
805 doda 5371 AttrBuff[pos] &= ~AttrKanji;
806     pos++;
807     CodeBuff[pos] = 0x20;
808 doda 8445 BuffSetChar(&CodeBuffW[pos], 0x20, 'H');
809 doda 5371 AttrBuff[pos] &= ~AttrKanji;
810     }
811     ptr = NextLinePtr(ptr);
812     }
813     }
814    
815 doda 8445 // Insert space characters at the current position
816     // Count: Number of characters to be inserted
817 maya 3227 void BuffInsertSpace(int Count)
818 doda 8445 {
819 zmatsuo 8739 #if !ATR
820     PCHAR CodeLine = &CodeBuff[LinePtr];
821     PCHAR AttrLine = &AttrBuff[LinePtr];
822     PCHAR AttrLine2 = &AttrBuff2[LinePtr];
823     PCHAR AttrLineFG = &AttrBuffFG[LinePtr];
824     PCHAR AttrLineBG = &AttrBuffBG[LinePtr];
825     buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
826     #endif
827 doda 8445 int MoveLen;
828     int extr = 0;
829     int sx;
830     buff_char_t *b;
831    
832     if (CursorX < CursorLeftM || CursorX > CursorRightM)
833     return;
834    
835     NewLine(PageStart + CursorY);
836    
837     sx = CursorX;
838     b = &CodeLineW[CursorX];
839     if (IsBuffPadding(b)) {
840     /* if cursor is on right half of a kanji, erase the kanji */
841     BuffSetChar(b - 1, ' ', 'H');
842     BuffSetChar(b, ' ', 'H');
843     AttrLine[CursorX] &= ~AttrKanji;
844     sx--;
845     extr++;
846     }
847    
848     if (CursorRightM < NumOfColumns - 1 && (AttrLine[CursorRightM] & AttrKanji)) {
849     CodeLine[CursorRightM + 1] = 0x20;
850     BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
851     AttrLine[CursorRightM + 1] &= ~AttrKanji;
852     extr++;
853     }
854    
855     if (Count > CursorRightM + 1 - CursorX)
856     Count = CursorRightM + 1 - CursorX;
857    
858     MoveLen = CursorRightM + 1 - CursorX - Count;
859    
860     if (MoveLen > 0) {
861     memmove(&(CodeLine[CursorX + Count]), &(CodeLine[CursorX]), MoveLen);
862     memmoveW(&(CodeLineW[CursorX + Count]), &(CodeLineW[CursorX]), MoveLen);
863     memmove(&(AttrLine[CursorX + Count]), &(AttrLine[CursorX]), MoveLen);
864     memmove(&(AttrLine2[CursorX + Count]), &(AttrLine2[CursorX]), MoveLen);
865     memmove(&(AttrLineFG[CursorX + Count]), &(AttrLineFG[CursorX]), MoveLen);
866     memmove(&(AttrLineBG[CursorX + Count]), &(AttrLineBG[CursorX]), MoveLen);
867     }
868     memset(&(CodeLine[CursorX]), 0x20, Count);
869     memsetW(&(CodeLineW[CursorX]), 0x20, Count);
870     memset(&(AttrLine[CursorX]), AttrDefault, Count);
871     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
872     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
873     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
874     /* last char in current line is kanji first? */
875     if ((AttrLine[CursorRightM] & AttrKanji) != 0) {
876     /* then delete it */
877     CodeLine[CursorRightM] = 0x20;
878     BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
879     AttrLine[CursorRightM] &= ~AttrKanji;
880     }
881     BuffUpdateRect(sx, CursorY, CursorRightM + extr, CursorY);
882     }
883 doda 5324
884 maya 3227 void BuffEraseCurToEnd()
885     // Erase characters from cursor to the end of screen
886     {
887 maya 3393 LONG TmpPtr;
888     int offset;
889     int i, YEnd;
890 maya 3227
891 maya 3393 NewLine(PageStart+CursorY);
892 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
893 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
894     }
895     offset = CursorX;
896     TmpPtr = GetLinePtr(PageStart+CursorY);
897     YEnd = NumOfLines-1;
898 doda 5324 if (StatusLine && !isCursorOnStatusLine) {
899 maya 3393 YEnd--;
900     }
901     for (i = CursorY ; i <= YEnd ; i++) {
902     memset(&(CodeBuff[TmpPtr+offset]),0x20,NumOfColumns-offset);
903 doda 8445 memsetW(&(CodeBuffW[TmpPtr+offset]),0x20,NumOfColumns-offset);
904 maya 3393 memset(&(AttrBuff[TmpPtr+offset]),AttrDefault,NumOfColumns-offset);
905 doda 4070 memset(&(AttrBuff2[TmpPtr+offset]),CurCharAttr.Attr2 & Attr2ColorMask, NumOfColumns-offset);
906 maya 3393 memset(&(AttrBuffFG[TmpPtr+offset]),CurCharAttr.Fore,NumOfColumns-offset);
907     memset(&(AttrBuffBG[TmpPtr+offset]),CurCharAttr.Back,NumOfColumns-offset);
908     offset = 0;
909     TmpPtr = NextLinePtr(TmpPtr);
910     }
911     /* update window */
912     DispEraseCurToEnd(YEnd);
913 maya 3227 }
914    
915     void BuffEraseHomeToCur()
916     // Erase characters from home to cursor
917     {
918 maya 3393 LONG TmpPtr;
919     int offset;
920     int i, YHome;
921 maya 3227
922 maya 3393 NewLine(PageStart+CursorY);
923 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
924 maya 3393 EraseKanji(0); /* if cursor is on left half of a kanji, erase the kanji */
925     }
926     offset = NumOfColumns;
927 doda 5324 if (isCursorOnStatusLine) {
928 maya 3393 YHome = CursorY;
929     }
930     else {
931     YHome = 0;
932     }
933     TmpPtr = GetLinePtr(PageStart+YHome);
934     for (i = YHome ; i <= CursorY ; i++) {
935     if (i==CursorY) {
936     offset = CursorX+1;
937     }
938     memset(&(CodeBuff[TmpPtr]),0x20,offset);
939 doda 8445 memsetW(&(CodeBuffW[TmpPtr]),0x20,offset);
940 maya 3393 memset(&(AttrBuff[TmpPtr]),AttrDefault,offset);
941 doda 4070 memset(&(AttrBuff2[TmpPtr]),CurCharAttr.Attr2 & Attr2ColorMask, offset);
942 maya 3393 memset(&(AttrBuffFG[TmpPtr]),CurCharAttr.Fore,offset);
943     memset(&(AttrBuffBG[TmpPtr]),CurCharAttr.Back,offset);
944     TmpPtr = NextLinePtr(TmpPtr);
945     }
946 maya 3227
947 maya 3393 /* update window */
948     DispEraseHomeToCur(YHome);
949 maya 3227 }
950    
951     void BuffInsertLines(int Count, int YEnd)
952     // Insert lines at current position
953     // Count: number of lines to be inserted
954     // YEnd: bottom line number of scroll region (screen coordinate)
955     {
956 doda 5324 int i, linelen;
957 doda 5371 int extl=0, extr=0;
958 maya 3393 LONG SrcPtr, DestPtr;
959 maya 3227
960 maya 3393 BuffUpdateScroll();
961 maya 3227
962 doda 5371 if (CursorLeftM > 0)
963     extl = 1;
964     if (CursorRightM < NumOfColumns-1)
965     extr = 1;
966     if (extl || extr)
967     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
968    
969 doda 5324 SrcPtr = GetLinePtr(PageStart+YEnd-Count) + CursorLeftM;
970     DestPtr = GetLinePtr(PageStart+YEnd) + CursorLeftM;
971     linelen = CursorRightM - CursorLeftM + 1;
972 maya 3393 for (i= YEnd-Count ; i>=CursorY ; i--) {
973 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
974 doda 8445 memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
975 doda 5324 memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
976     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
977     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
978     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
979 maya 3393 SrcPtr = PrevLinePtr(SrcPtr);
980     DestPtr = PrevLinePtr(DestPtr);
981     }
982     for (i = 1 ; i <= Count ; i++) {
983 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
984 doda 8445 memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
985 doda 5324 memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
986     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
987     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
988     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
989 maya 3393 DestPtr = PrevLinePtr(DestPtr);
990     }
991 maya 3227
992 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || !DispInsertLines(Count, YEnd)) {
993 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
994 maya 3393 }
995 maya 3227 }
996    
997     void BuffEraseCharsInLine(int XStart, int Count)
998     // erase characters in the current line
999     // XStart: start position of erasing
1000     // Count: number of characters to be erased
1001     {
1002 zmatsuo 8739 #if !ATR
1003     PCHAR CodeLine = &CodeBuff[LinePtr];
1004     PCHAR AttrLine = &AttrBuff[LinePtr];
1005     PCHAR AttrLine2 = &AttrBuff2[LinePtr];
1006     PCHAR AttrLineFG = &AttrBuffFG[LinePtr];
1007     PCHAR AttrLineBG = &AttrBuffBG[LinePtr];
1008     buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
1009     #endif
1010 maya 3393 BOOL LineContinued=FALSE;
1011 doda 3312
1012 maya 3393 if (ts.EnableContinuedLineCopy && XStart == 0 && (AttrLine[0] & AttrLineContinued)) {
1013     LineContinued = TRUE;
1014     }
1015 doda 3312
1016 doda 3416 if (ts.Language==IdJapanese || ts.Language==IdKorean || ts.Language==IdUtf8) {
1017 maya 3393 EraseKanji(1); /* if cursor is on right half of a kanji, erase the kanji */
1018     }
1019 maya 3227
1020 maya 3393 NewLine(PageStart+CursorY);
1021     memset(&(CodeLine[XStart]),0x20,Count);
1022 doda 8445 memsetW(&(CodeLineW[XStart]),0x20,Count);
1023 maya 3393 memset(&(AttrLine[XStart]),AttrDefault,Count);
1024 doda 4070 memset(&(AttrLine2[XStart]),CurCharAttr.Attr2 & Attr2ColorMask, Count);
1025 maya 3393 memset(&(AttrLineFG[XStart]),CurCharAttr.Fore,Count);
1026     memset(&(AttrLineBG[XStart]),CurCharAttr.Back,Count);
1027 maya 3227
1028 maya 3393 if (ts.EnableContinuedLineCopy) {
1029     if (LineContinued) {
1030     BuffLineContinued(TRUE);
1031     }
1032    
1033     if (XStart + Count >= NumOfColumns) {
1034     AttrBuff[NextLinePtr(LinePtr)] &= ~AttrLineContinued;
1035     }
1036     }
1037 doda 3312
1038 maya 3393 DispEraseCharsInLine(XStart, Count);
1039 maya 3227 }
1040    
1041     void BuffDeleteLines(int Count, int YEnd)
1042     // Delete lines from current line
1043     // Count: number of lines to be deleted
1044     // YEnd: bottom line number of scroll region (screen coordinate)
1045     {
1046 doda 5324 int i, linelen;
1047 doda 5371 int extl=0, extr=0;
1048 maya 3393 LONG SrcPtr, DestPtr;
1049 maya 3227
1050 maya 3393 BuffUpdateScroll();
1051 maya 3227
1052 doda 5371 if (CursorLeftM > 0)
1053     extl = 1;
1054     if (CursorRightM < NumOfColumns-1)
1055     extr = 1;
1056     if (extl || extr)
1057     EraseKanjiOnLRMargin(GetLinePtr(PageStart+CursorY), YEnd-CursorY+1);
1058    
1059 doda 5324 SrcPtr = GetLinePtr(PageStart+CursorY+Count) + (LONG)CursorLeftM;
1060     DestPtr = GetLinePtr(PageStart+CursorY) + (LONG)CursorLeftM;
1061     linelen = CursorRightM - CursorLeftM + 1;
1062 maya 3393 for (i=CursorY ; i<= YEnd-Count ; i++) {
1063 doda 5324 memcpy(&(CodeBuff[DestPtr]), &(CodeBuff[SrcPtr]), linelen);
1064 doda 8445 memcpyW(&(CodeBuffW[DestPtr]), &(CodeBuffW[SrcPtr]), linelen);
1065 doda 5324 memcpy(&(AttrBuff[DestPtr]), &(AttrBuff[SrcPtr]), linelen);
1066     memcpy(&(AttrBuff2[DestPtr]), &(AttrBuff2[SrcPtr]), linelen);
1067     memcpy(&(AttrBuffFG[DestPtr]), &(AttrBuffFG[SrcPtr]), linelen);
1068     memcpy(&(AttrBuffBG[DestPtr]), &(AttrBuffBG[SrcPtr]), linelen);
1069 maya 3393 SrcPtr = NextLinePtr(SrcPtr);
1070     DestPtr = NextLinePtr(DestPtr);
1071     }
1072     for (i = YEnd+1-Count ; i<=YEnd ; i++) {
1073 doda 5324 memset(&(CodeBuff[DestPtr]), 0x20, linelen);
1074 doda 8445 memsetW(&(CodeBuffW[DestPtr]), 0x20, linelen);
1075 doda 5324 memset(&(AttrBuff[DestPtr]), AttrDefault, linelen);
1076     memset(&(AttrBuff2[DestPtr]), CurCharAttr.Attr2 & Attr2ColorMask, linelen);
1077     memset(&(AttrBuffFG[DestPtr]), CurCharAttr.Fore, linelen);
1078     memset(&(AttrBuffBG[DestPtr]), CurCharAttr.Back, linelen);
1079 maya 3393 DestPtr = NextLinePtr(DestPtr);
1080     }
1081 maya 3227
1082 doda 5324 if (CursorLeftM > 0 || CursorRightM < NumOfColumns-1 || ! DispDeleteLines(Count,YEnd)) {
1083 doda 5371 BuffUpdateRect(CursorLeftM-extl, CursorY, CursorRightM+extr, YEnd);
1084 maya 3393 }
1085 maya 3227 }
1086    
1087     // Delete characters in current line from cursor
1088     // Count: number of characters to be deleted
1089 doda 8445 void BuffDeleteChars(int Count)
1090 maya 3227 {
1091 zmatsuo 8739 #if !ATR
1092     PCHAR CodeLine = &CodeBuff[LinePtr];
1093     PCHAR AttrLine = &AttrBuff[LinePtr];
1094     PCHAR AttrLine2 = &AttrBuff2[LinePtr];
1095     PCHAR AttrLineFG = &AttrBuffFG[LinePtr];
1096     PCHAR AttrLineBG = &AttrBuffBG[LinePtr];
1097     buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
1098     #endif
1099 doda 5325 int MoveLen;
1100 doda 8445 int extr = 0;
1101     buff_char_t *b;
1102    
1103     if (Count > CursorRightM + 1 - CursorX)
1104     Count = CursorRightM + 1 - CursorX;
1105    
1106     if (CursorX < CursorLeftM || CursorX > CursorRightM)
1107     return;
1108    
1109     NewLine(PageStart + CursorY);
1110    
1111     b = &CodeLineW[CursorX];
1112    
1113     if (IsBuffPadding(b)) {
1114     // �S�p���E���A�S�p���X�y�[�X���u��������
1115     BuffSetChar(b - 1, ' ', 'H');
1116     BuffSetChar(b, ' ', 'H');
1117     }
1118     if (IsBuffFullWidth(b)) {
1119     // �S�p�������A�S�p���X�y�[�X���u��������
1120     BuffSetChar(b, ' ', 'H');
1121     BuffSetChar(b + 1, ' ', 'H');
1122     }
1123     if (Count > 1) {
1124     // �I�[���`�F�b�N
1125     if (IsBuffPadding(b + Count)) {
1126     // �S�p���E���A�S�p���X�y�[�X���u��������
1127     BuffSetChar(b + Count - 1, ' ', 'H');
1128     BuffSetChar(b + Count, ' ', 'H');
1129     }
1130     }
1131    
1132     if (CursorRightM < NumOfColumns - 1 && (AttrLine[CursorRightM] & AttrKanji)) {
1133     CodeLine[CursorRightM] = 0x20;
1134     BuffSetChar(&CodeLineW[CursorRightM], 0x20, 'H');
1135     AttrLine[CursorRightM] &= ~AttrKanji;
1136     CodeLine[CursorRightM + 1] = 0x20;
1137     BuffSetChar(&CodeLineW[CursorRightM + 1], 0x20, 'H');
1138     AttrLine[CursorRightM + 1] &= ~AttrKanji;
1139     extr = 1;
1140     }
1141    
1142     MoveLen = CursorRightM + 1 - CursorX - Count;
1143    
1144     if (MoveLen > 0) {
1145     memmove(&(CodeLine[CursorX]), &(CodeLine[CursorX + Count]), MoveLen);
1146     memmoveW(&(CodeLineW[CursorX]), &(CodeLineW[CursorX + Count]), MoveLen);
1147     memmove(&(AttrLine[CursorX]), &(AttrLine[CursorX + Count]), MoveLen);
1148     memmove(&(AttrLine2[CursorX]), &(AttrLine2[CursorX + Count]), MoveLen);
1149     memmove(&(AttrLineFG[CursorX]), &(AttrLineFG[CursorX + Count]), MoveLen);
1150     memmove(&(AttrLineBG[CursorX]), &(AttrLineBG[CursorX + Count]), MoveLen);
1151     }
1152     memset(&(CodeLine[CursorX + MoveLen]), 0x20, Count);
1153     memsetW(&(CodeLineW[CursorX + MoveLen]), ' ', Count);
1154     memset(&(AttrLine[CursorX + MoveLen]), AttrDefault, Count);
1155     memset(&(AttrLine2[CursorX + MoveLen]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
1156     memset(&(AttrLineFG[CursorX + MoveLen]), CurCharAttr.Fore, Count);
1157     memset(&(AttrLineBG[CursorX + MoveLen]), CurCharAttr.Back, Count);
1158    
1159     BuffUpdateRect(CursorX, CursorY, CursorRightM + extr, CursorY);
1160     }
1161 doda 5325
1162 maya 3227 // Erase characters in current line from cursor
1163     // Count: number of characters to be deleted
1164 doda 8445 void BuffEraseChars(int Count)
1165 maya 3227 {
1166 zmatsuo 8739 #if !ATR
1167     PCHAR CodeLine = &CodeBuff[LinePtr];
1168     PCHAR AttrLine = &AttrBuff[LinePtr];
1169     PCHAR AttrLine2 = &AttrBuff2[LinePtr];
1170     PCHAR AttrLineFG = &AttrBuffFG[LinePtr];
1171     PCHAR AttrLineBG = &AttrBuffBG[LinePtr];
1172     buff_char_t * CodeLineW = &CodeBuffW[LinePtr];
1173     #endif
1174 doda 8445 int extr = 0;
1175     int sx = CursorX;
1176     buff_char_t *b;
1177     NewLine(PageStart + CursorY);
1178    
1179     if (Count > NumOfColumns - CursorX) {
1180     Count = NumOfColumns - CursorX;
1181     }
1182    
1183     b = &CodeLineW[CursorX];
1184     if (IsBuffPadding(b)) {
1185     // �S�p���E���A�S�p���X�y�[�X���u��������
1186     BuffSetChar(b - 1, ' ', 'H');
1187     BuffSetChar(b, ' ', 'H');
1188     sx--;
1189     extr++;
1190     }
1191     if (IsBuffFullWidth(b)) {
1192     // �S�p�������A�S�p���X�y�[�X���u��������
1193     BuffSetChar(b, ' ', 'H');
1194     BuffSetChar(b + 1, ' ', 'H');
1195     if (Count == 1) {
1196     extr++;
1197     }
1198     }
1199     if (Count > 1) {
1200     // �I�[���`�F�b�N
1201     if (IsBuffPadding(b + Count)) {
1202     // �S�p���E���A�S�p���X�y�[�X���u��������
1203     BuffSetChar(b + Count - 1, ' ', 'H');
1204     BuffSetChar(b + Count, ' ', 'H');
1205     extr++;
1206     }
1207     }
1208    
1209     memset(&(CodeLine[CursorX]), 0x20, Count);
1210     memsetW(&(CodeLineW[CursorX]), 0x20, Count);
1211     memset(&(AttrLine[CursorX]), AttrDefault, Count);
1212     memset(&(AttrLine2[CursorX]), CurCharAttr.Attr2 & Attr2ColorMask, Count);
1213     memset(&(AttrLineFG[CursorX]), CurCharAttr.Fore, Count);
1214     memset(&(AttrLineBG[CursorX]), CurCharAttr.Back, Count);
1215    
1216     /* update window */
1217     DispEraseCharsInLine(sx, Count + extr);
1218     }
1219 maya 3227
1220     void BuffFillWithE()
1221     // Fill screen with 'E' characters
1222     {
1223 maya 3393 LONG TmpPtr;
1224     int i;
1225 maya 3227
1226 maya 3393 TmpPtr = GetLinePtr(PageStart);
1227     for (i = 0 ; i <= NumOfLines-1-StatusLine ; i++) {
1228     memset(&(CodeBuff[TmpPtr]),'E',NumOfColumns);
1229 doda 8445 memsetW(&(CodeBuffW[TmpPtr]),'E',NumOfColumns);
1230 maya 3393 memset(&(AttrBuff[TmpPtr]),AttrDefault,NumOfColumns);
1231     memset(&(AttrBuff2[TmpPtr]),AttrDefault,NumOfColumns);
1232     memset(&(AttrBuffFG[TmpPtr]),AttrDefaultFG,NumOfColumns);
1233     memset(&(AttrBuffBG[TmpPtr]),AttrDefaultBG,NumOfColumns);
1234     TmpPtr = NextLinePtr(TmpPtr);
1235     }
1236     BuffUpdateRect(WinOrgX,WinOrgY,WinOrgX+WinWidth-1,WinOrgY+WinHeight-1);
1237 maya 3227 }
1238    
1239     void BuffDrawLine(TCharAttr Attr, int Direction, int C)
1240     { // IO-8256 terminal
1241 maya 3393 LONG Ptr;
1242     int i, X, Y;
1243 maya 3227
1244 maya 3393 if (C==0) {
1245     return;
1246     }
1247     Attr.Attr |= AttrSpecial;
1248 maya 3227
1249 maya 3393 switch (Direction) {
1250     case 3:
1251     case 4:
1252     if (Direction==3) {
1253     if (CursorY==0) {
1254     return;
1255     }
1256     Y = CursorY-1;
1257     }
1258     else {
1259     if (CursorY==NumOfLines-1-StatusLine) {
1260     return;
1261     }
1262     Y = CursorY+1;
1263     }
1264     if (CursorX+C > NumOfColumns) {
1265     C = NumOfColumns-CursorX;
1266     }
1267     Ptr = GetLinePtr(PageStart+Y);
1268     memset(&(CodeBuff[Ptr+CursorX]),'q',C);
1269 doda 8445 memsetW(&(CodeBuffW[Ptr+CursorX]),'q',C);
1270 maya 3393 memset(&(AttrBuff[Ptr+CursorX]),Attr.Attr,C);
1271     memset(&(AttrBuff2[Ptr+CursorX]),Attr.Attr2,C);
1272     memset(&(AttrBuffFG[Ptr+CursorX]),Attr.Fore,C);
1273     memset(&(AttrBuffBG[Ptr+CursorX]),Attr.Back,C);
1274     BuffUpdateRect(CursorX,Y,CursorX+C-1,Y);
1275     break;
1276     case 5:
1277     case 6:
1278     if (Direction==5) {
1279     if (CursorX==0) {
1280     return;
1281     }
1282     X = CursorX - 1;
1283     }
1284     else {
1285     if (CursorX==NumOfColumns-1) {
1286     X = CursorX-1;
1287     }
1288     else {
1289     X = CursorX+1;
1290     }
1291     }
1292     Ptr = GetLinePtr(PageStart+CursorY);
1293     if (CursorY+C > NumOfLines-StatusLine) {
1294     C = NumOfLines-StatusLine-CursorY;
1295     }
1296     for (i=1; i<=C; i++) {
1297     CodeBuff[Ptr+X] = 'x';
1298 doda 8445 BuffSetChar(&CodeBuffW[Ptr+X], 0x20, 'H');
1299 maya 3393 AttrBuff[Ptr+X] = Attr.Attr;
1300     AttrBuff2[Ptr+X] = Attr.Attr2;
1301     AttrBuffFG[Ptr+X] = Attr.Fore;
1302     AttrBuffBG[Ptr+X] = Attr.Back;
1303     Ptr = NextLinePtr(Ptr);
1304     }
1305     BuffUpdateRect(X,CursorY,X,CursorY+C-1);
1306     break;
1307     }
1308 maya 3227 }
1309    
1310     void BuffEraseBox
1311     (int XStart, int YStart, int XEnd, int YEnd)
1312     {
1313 maya 3393 int C, i;
1314     LONG Ptr;
1315 maya 3227
1316 maya 3393 if (XEnd>NumOfColumns-1) {
1317     XEnd = NumOfColumns-1;
1318     }
1319     if (YEnd>NumOfLines-1-StatusLine) {
1320     YEnd = NumOfLines-1-StatusLine;
1321     }
1322     if (XStart>XEnd) {
1323     return;
1324     }
1325     if (YStart>YEnd) {
1326     return;
1327     }
1328     C = XEnd-XStart+1;
1329     Ptr = GetLinePtr(PageStart+YStart);
1330     for (i=YStart; i<=YEnd; i++) {
1331     if ((XStart>0) &&
1332     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
1333     CodeBuff[Ptr+XStart-1] = 0x20;
1334 doda 8445 BuffSetChar(&CodeBuffW[Ptr+XStart-1], 0x20, 'H');
1335 maya 3393 AttrBuff[Ptr+XStart-1] = CurCharAttr.Attr;
1336     AttrBuff2[Ptr+XStart-1] = CurCharAttr.Attr2;
1337     AttrBuffFG[Ptr+XStart-1] = CurCharAttr.Fore;
1338     AttrBuffBG[Ptr+XStart-1] = CurCharAttr.Back;
1339     }
1340     if ((XStart+C<NumOfColumns) &&
1341     ((AttrBuff[Ptr+XStart+C-1] & AttrKanji) != 0)) {
1342     CodeBuff[Ptr+XStart+C] = 0x20;
1343 doda 8445 BuffSetChar(&CodeBuffW[Ptr+XStart+C], 0x20, 'H');
1344 maya 3393 AttrBuff[Ptr+XStart+C] = CurCharAttr.Attr;
1345     AttrBuff2[Ptr+XStart+C] = CurCharAttr.Attr2;
1346     AttrBuffFG[Ptr+XStart+C] = CurCharAttr.Fore;
1347     AttrBuffBG[Ptr+XStart+C] = CurCharAttr.Back;
1348     }
1349     memset(&(CodeBuff[Ptr+XStart]),0x20,C);
1350 doda 8445 memsetW(&(CodeBuffW[Ptr+XStart]),0x20,C);
1351 maya 3393 memset(&(AttrBuff[Ptr+XStart]),AttrDefault,C);
1352 doda 4070 memset(&(AttrBuff2[Ptr+XStart]),CurCharAttr.Attr2 & Attr2ColorMask, C);
1353 maya 3393 memset(&(AttrBuffFG[Ptr+XStart]),CurCharAttr.Fore,C);
1354     memset(&(AttrBuffBG[Ptr+XStart]),CurCharAttr.Back,C);
1355     Ptr = NextLinePtr(Ptr);
1356     }
1357     BuffUpdateRect(XStart,YStart,XEnd,YEnd);
1358 maya 3227 }
1359    
1360 doda 5090 void BuffFillBox(char ch, int XStart, int YStart, int XEnd, int YEnd)
1361     {
1362     int Cols, i;
1363     LONG Ptr;
1364    
1365     if (XEnd>NumOfColumns-1) {
1366     XEnd = NumOfColumns-1;
1367     }
1368     if (YEnd>NumOfLines-1-StatusLine) {
1369     YEnd = NumOfLines-1-StatusLine;
1370     }
1371     if (XStart>XEnd) {
1372     return;
1373     }
1374     if (YStart>YEnd) {
1375     return;
1376     }
1377     Cols = XEnd-XStart+1;
1378     Ptr = GetLinePtr(PageStart+YStart);
1379     for (i=YStart; i<=YEnd; i++) {
1380     if ((XStart>0) &&
1381     ((AttrBuff[Ptr+XStart-1] & AttrKanji) != 0)) {
1382     CodeBuff[Ptr+XStart-1] = 0x20;
1383 doda 8446 BuffSetChar(&CodeBuffW[Ptr + XStart - 1], 0x20, 'H');
1384 doda 5090 AttrBuff[Ptr+XStart-1] ^= AttrKanji;
1385     }
1386     if ((XStart+Cols<NumOfColumns) &&
1387     ((AttrBuff[Ptr+XStart+Cols-1] & AttrKanji) != 0)) {
1388     CodeBuff[Ptr+XStart+Cols] = 0x20;
1389 doda 8446 BuffSetChar(&CodeBuffW[Ptr + XStart + Cols], 0x20, 'H');
1390 doda 5090 }
1391     memset(&(CodeBuff[Ptr+XStart]), ch, Cols);
1392 doda 8446 memsetW(&(CodeBuffW[Ptr+XStart]), ch, Cols);
1393 doda 5090 memset(&(AttrBuff[Ptr+XStart]), CurCharAttr.Attr, Cols);
1394 doda 5092 memset(&(AttrBuff2[Ptr+XStart]), CurCharAttr.Attr2, Cols);
1395 doda 5090 memset(&(AttrBuffFG[Ptr+XStart]), CurCharAttr.Fore, Cols);
1396     memset(&(AttrBuffBG[Ptr+XStart]), CurCharAttr.Back, Cols);
1397     Ptr = NextLinePtr(Ptr);
1398     }
1399     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1400     }
1401    
1402 doda 6174 //
1403     // TODO: 1 origin �������������� 0 origin ������
1404     //
1405 doda 5089 void BuffCopyBox(
1406     int SrcXStart, int SrcYStart, int SrcXEnd, int SrcYEnd, int SrcPage,
1407     int DstX, int DstY, int DstPage)
1408     {
1409     int i, C, L;
1410     LONG SPtr, DPtr;
1411    
1412     SrcXStart--;
1413     SrcYStart--;
1414     SrcXEnd--;
1415     SrcYEnd--;
1416     SrcPage--;
1417     DstX--;
1418     DstY--;
1419     DstPage--;
1420    
1421     if (SrcXEnd > NumOfColumns - 1) {
1422     SrcXEnd = NumOfColumns-1;
1423     }
1424     if (SrcYEnd > NumOfLines-1-StatusLine) {
1425     SrcYEnd = NumOfColumns-1;
1426     }
1427     if (SrcXStart > SrcXEnd ||
1428     SrcYStart > SrcYEnd ||
1429     DstX > NumOfColumns-1 ||
1430     DstY > NumOfLines-1-StatusLine) {
1431     return;
1432     }
1433    
1434     C = SrcXEnd - SrcXStart + 1;
1435     if (DstX + C > NumOfColumns) {
1436     C = NumOfColumns - DstX;
1437     }
1438     L = SrcYEnd - SrcYStart + 1;
1439     if (DstY + C > NumOfColumns) {
1440     C = NumOfColumns - DstX;
1441     }
1442    
1443     if (SrcXStart > DstX) {
1444     SPtr = GetLinePtr(PageStart+SrcYStart);
1445     DPtr = GetLinePtr(PageStart+DstY);
1446     for (i=0; i<L; i++) {
1447     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1448 doda 8445 memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1449 doda 5089 memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1450     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1451     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1452     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1453     SPtr = NextLinePtr(SPtr);
1454     DPtr = NextLinePtr(DPtr);
1455     }
1456     }
1457     else if (SrcXStart < DstX) {
1458     SPtr = GetLinePtr(PageStart+SrcYEnd);
1459     DPtr = GetLinePtr(PageStart+DstY+L-1);
1460     for (i=L; i>0; i--) {
1461     memcpy(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1462 doda 8445 memcpyW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1463 doda 5089 memcpy(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1464     memcpy(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1465     memcpy(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1466     memcpy(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1467     SPtr = PrevLinePtr(SPtr);
1468     DPtr = PrevLinePtr(DPtr);
1469     }
1470     }
1471     else if (SrcYStart != DstY) {
1472     SPtr = GetLinePtr(PageStart+SrcYStart);
1473     DPtr = GetLinePtr(PageStart+DstY);
1474     for (i=0; i<L; i++) {
1475     memmove(&(CodeBuff[DPtr+DstX]), &(CodeBuff[SPtr+SrcXStart]), C);
1476 doda 8445 memmoveW(&(CodeBuffW[DPtr+DstX]), &(CodeBuffW[SPtr+SrcXStart]), C);
1477 doda 5089 memmove(&(AttrBuff[DPtr+DstX]), &(AttrBuff[SPtr+SrcXStart]), C);
1478     memmove(&(AttrBuff2[DPtr+DstX]), &(AttrBuff2[SPtr+SrcXStart]), C);
1479     memmove(&(AttrBuffFG[DPtr+DstX]), &(AttrBuffFG[SPtr+SrcXStart]), C);
1480     memmove(&(AttrBuffBG[DPtr+DstX]), &(AttrBuffBG[SPtr+SrcXStart]), C);
1481     SPtr = NextLinePtr(SPtr);
1482     DPtr = NextLinePtr(DPtr);
1483     }
1484     }
1485     BuffUpdateRect(DstX,DstY,DstX+C-1,DstY+L-1);
1486     }
1487    
1488 doda 5095 void BuffChangeAttrBox(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1489     {
1490     int C, i, j;
1491     LONG Ptr;
1492    
1493     if (XEnd>NumOfColumns-1) {
1494     XEnd = NumOfColumns-1;
1495     }
1496     if (YEnd>NumOfLines-1-StatusLine) {
1497     YEnd = NumOfLines-1-StatusLine;
1498     }
1499     if (XStart>XEnd || YStart>YEnd) {
1500     return;
1501     }
1502     C = XEnd-XStart+1;
1503     Ptr = GetLinePtr(PageStart+YStart);
1504    
1505     if (mask) { // DECCARA
1506     for (i=YStart; i<=YEnd; i++) {
1507     j = Ptr+XStart-1;
1508     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1509     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1510 doda 7085 AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1511 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[j] = attr->Fore; }
1512     if (mask->Attr2 & Attr2Back) { AttrBuffBG[j] = attr->Back; }
1513 doda 5095 }
1514 doda 7083 while (++j < Ptr+XStart+C) {
1515 doda 5095 AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1516     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1517 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[j] = attr->Fore; }
1518     if (mask->Attr2 & Attr2Back) { AttrBuffBG[j] = attr->Back; }
1519 doda 5095 }
1520     if (XStart+C<NumOfColumns && (AttrBuff[j-1] & AttrKanji)) {
1521     AttrBuff[j] = AttrBuff[j] & ~mask->Attr | attr->Attr;
1522     AttrBuff2[j] = AttrBuff2[j] & ~mask->Attr2 | attr->Attr2;
1523 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[j] = attr->Fore; }
1524     if (mask->Attr2 & Attr2Back) { AttrBuffBG[j] = attr->Back; }
1525 doda 5095 }
1526     Ptr = NextLinePtr(Ptr);
1527     }
1528     }
1529     else { // DECRARA
1530     for (i=YStart; i<=YEnd; i++) {
1531     j = Ptr+XStart-1;
1532     if (XStart>0 && (AttrBuff[j] & AttrKanji)) {
1533 doda 7083 AttrBuff[j] ^= attr->Attr;
1534 doda 5095 }
1535 doda 7083 while (++j < Ptr+XStart+C) {
1536     AttrBuff[j] ^= attr->Attr;
1537 doda 5095 }
1538     if (XStart+C<NumOfColumns && (AttrBuff[j-1] & AttrKanji)) {
1539     AttrBuff[j] ^= attr->Attr;
1540     }
1541     Ptr = NextLinePtr(Ptr);
1542     }
1543     }
1544     BuffUpdateRect(XStart, YStart, XEnd, YEnd);
1545     }
1546    
1547 doda 7086 void BuffChangeAttrStream(int XStart, int YStart, int XEnd, int YEnd, PCharAttr attr, PCharAttr mask)
1548     {
1549     int i, j, endp;
1550     LONG Ptr;
1551    
1552     if (XEnd>NumOfColumns-1) {
1553     XEnd = NumOfColumns-1;
1554     }
1555     if (YEnd>NumOfLines-1-StatusLine) {
1556     YEnd = NumOfLines-1-StatusLine;
1557     }
1558     if (XStart>XEnd || YStart>YEnd) {
1559     return;
1560     }
1561    
1562     Ptr = GetLinePtr(PageStart+YStart);
1563    
1564     if (mask) { // DECCARA
1565     if (YStart == YEnd) {
1566     i = Ptr + XStart - 1;
1567     endp = Ptr + XEnd + 1;
1568    
1569     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1570     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1571     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1572 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1573     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1574 doda 7086 }
1575     while (++i < endp) {
1576     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1577     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1578 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1579     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1580 doda 7086 }
1581     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1582     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1583     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1584 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1585     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1586 doda 7086 }
1587     }
1588     else {
1589     i = Ptr + XStart - 1;
1590     endp = Ptr + NumOfColumns;
1591    
1592     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1593     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1594     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1595 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1596     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1597 doda 7086 }
1598     while (++i < endp) {
1599     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1600     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1601 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1602     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1603 doda 7086 }
1604    
1605     for (j=0; j < YEnd-YStart-1; j++) {
1606     Ptr = NextLinePtr(Ptr);
1607     i = Ptr;
1608     endp = Ptr + NumOfColumns;
1609    
1610     while (i < endp) {
1611     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1612     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1613 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1614     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1615 doda 7086 i++;
1616     }
1617     }
1618    
1619     Ptr = NextLinePtr(Ptr);
1620     i = Ptr;
1621     endp = Ptr + XEnd + 1;
1622    
1623     while (i < endp) {
1624     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1625     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1626 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1627     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1628 doda 7086 i++;
1629     }
1630     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1631     AttrBuff[i] = AttrBuff[i] & ~mask->Attr | attr->Attr;
1632     AttrBuff2[i] = AttrBuff2[i] & ~mask->Attr2 | attr->Attr2;
1633 doda 7087 if (mask->Attr2 & Attr2Fore) { AttrBuffFG[i] = attr->Fore; }
1634     if (mask->Attr2 & Attr2Back) { AttrBuffBG[i] = attr->Back; }
1635 doda 7086 }
1636     }
1637     }
1638     else { // DECRARA
1639     if (YStart == YEnd) {
1640     i = Ptr + XStart - 1;
1641     endp = Ptr + XEnd + 1;
1642    
1643     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1644     AttrBuff[i] ^= attr->Attr;
1645     }
1646     while (++i < endp) {
1647     AttrBuff[i] ^= attr->Attr;
1648     }
1649     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1650     AttrBuff[i] ^= attr->Attr;
1651     }
1652     }
1653     else {
1654     i = Ptr + XStart - 1;
1655     endp = Ptr + NumOfColumns;
1656    
1657     if (XStart > 0 && (AttrBuff[i] & AttrKanji)) {
1658     AttrBuff[i] ^= attr->Attr;
1659     }
1660     while (++i < endp) {
1661     AttrBuff[i] ^= attr->Attr;
1662     }
1663    
1664     for (j=0; j < YEnd-YStart-1; j++) {
1665     Ptr = NextLinePtr(Ptr);
1666     i = Ptr;
1667     endp = Ptr + NumOfColumns;
1668    
1669     while (i < endp) {
1670     AttrBuff[i] ^= attr->Attr;
1671     i++;
1672     }
1673     }
1674    
1675     Ptr = NextLinePtr(Ptr);
1676     i = Ptr;
1677     endp = Ptr + XEnd + 1;
1678    
1679     while (i < endp) {
1680     AttrBuff[i] ^= attr->Attr;
1681     i++;
1682     }
1683     if (XEnd < NumOfColumns-1 && (AttrBuff[i-1] & AttrKanji)) {
1684     AttrBuff[i] ^= attr->Attr;
1685     }
1686     Ptr = NextLinePtr(Ptr);
1687     }
1688     }
1689     BuffUpdateRect(0, YStart, NumOfColumns-1, YEnd);
1690     }
1691    
1692 doda 8445 static int LeftHalfOfDBCS(LONG Line, int CharPtr)
1693 maya 3227 // If CharPtr is on the right half of a DBCS character,
1694     // return pointer to the left half
1695     // Line: points to a line in CodeBuff
1696     // CharPtr: points to a char
1697     // return: points to the left half of the DBCS
1698     {
1699 maya 3393 if ((CharPtr>0) &&
1700     ((AttrBuff[Line+CharPtr-1] & AttrKanji) != 0)) {
1701     CharPtr--;
1702     }
1703     return CharPtr;
1704 maya 3227 }
1705    
1706 doda 8445 static int MoveCharPtr(LONG Line, int *x, int dx)
1707 maya 3227 // move character pointer x by dx character unit
1708     // in the line specified by Line
1709     // Line: points to a line in CodeBuff
1710     // x: points to a character in the line
1711     // dx: moving distance in character unit (-: left, +: right)
1712 maya 3393 // One DBCS character is counted as one character.
1713 maya 3227 // The pointer stops at the beginning or the end of line.
1714     // Output
1715     // x: new pointer. x points to a SBCS character or
1716     // the left half of a DBCS character.
1717     // return: actual moving distance in character unit
1718     {
1719 maya 3393 int i;
1720 maya 3227
1721 maya 3393 *x = LeftHalfOfDBCS(Line,*x);
1722     i = 0;
1723     while (dx!=0) {
1724     if (dx>0) { // move right
1725     if ((AttrBuff[Line+*x] & AttrKanji) != 0) {
1726     if (*x<NumOfColumns-2) {
1727     i++;
1728     *x = *x + 2;
1729     }
1730     }
1731     else if (*x<NumOfColumns-1) {
1732     i++;
1733     (*x)++;
1734     }
1735     dx--;
1736     }
1737     else { // move left
1738     if (*x>0) {
1739     i--;
1740     (*x)--;
1741     }
1742     *x = LeftHalfOfDBCS(Line,*x);
1743     dx++;
1744     }
1745 maya 3227 }
1746 maya 3393 return i;
1747 maya 3227 }
1748    
1749 doda 8445 /**
1750     * (�N���b�v�{�[�h�p��)������������
1751     * @param[in] sx,sy,ex,ey �I������
1752     * @param[in] box_select TRUE=���^(���`)�I��
1753     * FALSE=�s�I��
1754     * @param[out] _str_len ��������(�����[L'\0'������)
1755     * NULL����������������
1756     * @return ������
1757     * �g�p���� free() ��������
1758     */
1759     static wchar_t *BuffGetStringForCB(int sx, int sy, int ex, int ey, BOOL box_select, size_t *_str_len)
1760     {
1761     wchar_t *str_w;
1762     size_t str_size; // �m�������T�C�Y
1763     size_t k;
1764     LONG TmpPtr;
1765     int IStart, IEnd;
1766     int x, y;
1767     BOOL LineContinued;
1768    
1769     str_size = NumOfColumns * (ey - sy + 1);
1770     str_w = malloc(sizeof(wchar_t) * str_size);
1771    
1772     LockBuffer();
1773    
1774     str_w[0] = 0;
1775     TmpPtr = GetLinePtr(sy);
1776     k = 0;
1777     for (y = sy; y<=ey ; y++) {
1778     if (box_select) {
1779     IStart = SelectStart.x;
1780     IEnd = SelectEnd.x-1;
1781     }
1782     else {
1783     IStart = 0;
1784     IEnd = NumOfColumns-1;
1785     if (y== sy) {
1786     IStart = sx;
1787     }
1788     if (y== ey) {
1789     IEnd = ex -1;
1790     }
1791     }
1792    
1793     // �����s����������?
1794     LineContinued = FALSE;
1795     if (!box_select) {
1796     // �s�I������������
1797     if (ts.EnableContinuedLineCopy && y!= ey ) {
1798     LONG NextTmpPtr = NextLinePtr(TmpPtr);
1799     if ((AttrBuff[NextTmpPtr] & AttrLineContinued) != 0) {
1800     LineContinued = TRUE;
1801     }
1802     }
1803     }
1804    
1805     if (!LineContinued) {
1806     while ((IEnd>0)) {
1807     // �R�s�[�s�v��������
1808     const buff_char_t *b = &CodeBuffW[TmpPtr + IEnd];
1809     if (b->u32 == 0x20) {
1810     MoveCharPtr(TmpPtr,&IEnd,-1); // �����l����
1811     }
1812     else {
1813     break;
1814     }
1815     }
1816     }
1817    
1818     x = IStart;
1819     while (x <= IEnd) {
1820     const buff_char_t *b = &CodeBuffW[TmpPtr + x];
1821     if (b->u32 != 0) {
1822     str_w[k++] = b->wc2[0];
1823     if (b->wc2[1] != 0) {
1824     str_w[k++] = b->wc2[1];
1825     }
1826     if (k + 2 >= str_size) {
1827     str_size *= 2;
1828     str_w = realloc(str_w, sizeof(wchar_t) * str_size);
1829     }
1830     {
1831     int i;
1832     // �R���r�l�[�V����
1833     if (k + b->CombinationCharCount16 >= str_size) {
1834     str_size += + b->CombinationCharCount16;
1835     str_w = realloc(str_w, sizeof(wchar_t) * str_size);
1836     }
1837     for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
1838     str_w[k++] = b->pCombinationChars16[i];
1839     }
1840     }
1841     }
1842     x++;
1843     }
1844    
1845     if (y < ey) {
1846     // ���s��������(�������s���O������)
1847     if (!LineContinued) {
1848     str_w[k++] = 0x0d;
1849     str_w[k++] = 0x0a;
1850     }
1851     }
1852    
1853     TmpPtr = NextLinePtr(TmpPtr);
1854     }
1855     str_w[k++] = 0;
1856    
1857     UnlockBuffer();
1858    
1859     if (_str_len != NULL) {
1860     *_str_len = k;
1861     }
1862     return str_w;
1863     }
1864    
1865     /**
1866 zmatsuo 8678 * 1�Z������wchar_t���������W�J����
1867     * @param[in] b 1�Z�������������������|�C���^
1868     * @param[in,out] buf �������W�J�� NULL���������W�J��������
1869     * @param[in] buf_size buf�������� NULL���������Q����������
1870     * @retrun ������
1871     */
1872     static size_t expand_wchar(const buff_char_t *b, wchar_t *buf, size_t buf_size, BOOL *too_samll)
1873     {
1874     size_t len;
1875    
1876     if (IsBuffPadding(b)) {
1877     if (too_samll != NULL) {
1878     *too_samll = FALSE;
1879     }
1880     return 0;
1881     }
1882    
1883     // ����������
1884     len = 0;
1885     if (b->wc2[1] == 0) {
1886     // �T���Q�[�g�y�A��������
1887     len++;
1888     } else {
1889     // �T���Q�[�g�y�A
1890     len += 2;
1891     }
1892     // �R���r�l�[�V����
1893     len += b->CombinationCharCount16;
1894    
1895     if (buf == NULL) {
1896     // ��������������
1897     return len;
1898     }
1899    
1900     // �o�b�t�@��������?
1901     if (len > buf_size) {
1902     // �o�b�t�@������������
1903     if (too_samll != NULL) {
1904     *too_samll = TRUE;
1905     }
1906     return 0;
1907     }
1908     if (too_samll != NULL) {
1909     *too_samll = FALSE;
1910     }
1911    
1912     // �W�J��������
1913     *buf++ = b->wc2[0];
1914     if (b->wc2[1] != 0) {
1915     *buf++ = b->wc2[1];
1916     }
1917     if (b->CombinationCharCount16 != 0) {
1918     memcpy(buf, b->pCombinationChars16, b->CombinationCharCount16 * sizeof(wchar_t));
1919     }
1920    
1921     return len;
1922     }
1923    
1924     /**
1925 doda 8445 * (x,y) ��1������ str��������������
1926     * *�� 1������������wchar_t�����\������������
1927     *
1928     * @param y PageStart + CursorY
1929     * @param str 1����(wchar_t��)
1930     * @param len ��������
1931     * @retval 0=�}�b�`����������
1932     * �}�b�`������������
1933     */
1934     static size_t MatchOneString(int x, int y, const wchar_t *str, size_t len)
1935     {
1936     int match_pos = 0;
1937     int TmpPtr = GetLinePtr(y);
1938     const buff_char_t *b = &CodeBuffW[TmpPtr + x];
1939     if (b->wc2[1] == 0) {
1940     // �T���Q�[�g�y�A��������
1941     if (str[match_pos] != b->wc2[0]) {
1942     return 0;
1943     }
1944     match_pos++;
1945     len--;
1946     } else {
1947     // �T���Q�[�g�y�A
1948     if (len < 2) {
1949     return 0;
1950     }
1951     if (str[match_pos+0] != b->wc2[0] ||
1952     str[match_pos+1] != b->wc2[1]) {
1953     return 0;
1954     }
1955     match_pos+=2;
1956     len-=2;
1957     }
1958     if (b->CombinationCharCount16 > 0) {
1959     // �R���r�l�[�V����
1960     int i;
1961     if (len < b->CombinationCharCount16) {
1962     return 0;
1963     }
1964     for (i = 0 ; i < (int)b->CombinationCharCount16; i++) {
1965     if (str[match_pos++] != b->pCombinationChars16[i]) {
1966     return 0;
1967     }
1968     }
1969     len -= b->CombinationCharCount16;
1970     }
1971     return match_pos;
1972     }
1973    
1974     /**
1975     * (x,y)���� str��������������
1976     *
1977     * @param x �}�C�i�X�����A�����s������������
1978     * @param y PageStart + CursorY
1979     * @param LineCntinued TRUE=�s���p�����l������
1980     * @retval TRUE �}�b�`����
1981     * @retval FALSE �}�b�`����������
1982     */
1983     static BOOL MatchString(int x, int y, const wchar_t *str, BOOL LineContinued)
1984     {
1985     BOOL result;
1986     int TmpPtr = GetLinePtr(y);
1987     size_t len = wcslen(str);
1988     if (len == 0) {
1989     return FALSE;
1990     }
1991     while(x < 0) {
1992     if (LineContinued && (AttrBuff[TmpPtr+0] & AttrLineContinued) == 0) {
1993     // �s���p�������������l�� & �p������������
1994     x = 0; // �s������������
1995     break;
1996     }
1997     TmpPtr = PrevLinePtr(TmpPtr);
1998     x += NumOfColumns;
1999     y--;
2000     }
2001     while(x > NumOfColumns) {
2002     if (LineContinued && (AttrBuff[TmpPtr+NumOfColumns-1] & AttrLineContinued) == 0) {
2003     // �s���p�������������l�� & �p������������
2004     x = 0; // �s������������
2005     break;
2006     }
2007     TmpPtr = NextLinePtr(TmpPtr);
2008     x -= NumOfColumns;
2009     }
2010    
2011     for(;;) {
2012     // 1����������������
2013     size_t match_len = MatchOneString(x, y, str, len);
2014     if (match_len == 0) {
2015     result = FALSE;
2016     break;
2017     }
2018     len -= match_len;
2019     if (len == 0) {
2020     // �S���������I������
2021     result = TRUE;
2022     break;
2023     }
2024     str += match_len;
2025    
2026     // ��������
2027     x++;
2028     if (x == NumOfColumns) {
2029     if (LineContinued && (AttrBuff[TmpPtr+NumOfColumns-1] & AttrLineContinued) != 0) {
2030     // �����s��
2031     x = 0;
2032     TmpPtr = NextLinePtr(TmpPtr);
2033     y++;
2034     } else {
2035     // �s��
2036     result = FALSE;
2037     break;
2038     }
2039     }
2040     }
2041    
2042     return result;
2043     }
2044    
2045     /**
2046     * (sx,sy)����(ex,ey)������ str ���}�b�`�����������T����
2047     * ���u������
2048     *
2049     * @param sy,ex PageStart + CursorY
2050     * @param[out] x �}�b�`�������u
2051     * @param[out] y �}�b�`�������u
2052     * @retval TRUE �}�b�`����
2053     */
2054     static BOOL BuffGetMatchPosFromString(
2055     int sx, int sy, int ex, int ey, const wchar_t *str,
2056     int *match_x, int *match_y)
2057     {
2058     int IStart, IEnd;
2059     int x, y;
2060    
2061     for (y = sy; y<=ey ; y++) {
2062     IStart = 0;
2063     IEnd = NumOfColumns-1;
2064     if (y== sy) {
2065     IStart = sx;
2066     }
2067     if (y== ey) {
2068     IEnd = ex;
2069     }
2070    
2071     x = IStart;
2072     while (x <= IEnd) {
2073     if (MatchString(x, y, str, TRUE)) {
2074     // �}�b�`����
2075     if (match_x != NULL) {
2076     *match_x = x;
2077     }
2078     if (match_y != NULL) {
2079     *match_y = y;
2080     }
2081     return TRUE;
2082     }
2083     x++;
2084     }
2085     }
2086     return FALSE;
2087     }
2088    
2089    
2090     /**
2091     * �A�������X�y�[�X���^�u1�����u������
2092     * @param[out] _str_len ��������(L'\0'������)
2093     * @return ������
2094     * �g�p���� free() ��������
2095     */
2096     static wchar_t *ConvertTable(const wchar_t *src, size_t src_len, size_t *str_len)
2097     {
2098     wchar_t *dest_top = malloc(sizeof(wchar_t) * src_len);
2099     wchar_t *dest = dest_top;
2100     BOOL WhiteSpace = FALSE;
2101     while (*src != '\0') {
2102     wchar_t c = *src++;
2103     if (c == 0x0d || c == 0x0a) {
2104     *dest++ = c;
2105     WhiteSpace = FALSE;
2106     } else if (c <= L' ') {
2107     if (!WhiteSpace) {
2108     // insert tab
2109     *dest++ = 0x09;
2110     WhiteSpace = TRUE;
2111     }
2112     } else {
2113     *dest++ = c;
2114     WhiteSpace = FALSE;
2115     }
2116     }
2117     *dest = L'\0';
2118     *str_len = dest - dest_top + 1;
2119     return dest_top;
2120     }
2121    
2122    
2123 zmatsuo 8676 /**
2124     * �N���b�v�{�[�h�p����������
2125     * @return ������
2126     * �g�p���� free() ��������
2127     */
2128     wchar_t *BuffCBCopyUnicode(BOOL Table)
2129 doda 8445 {
2130     wchar_t *str_ptr;
2131     size_t str_len;
2132     str_ptr = BuffGetStringForCB(
2133     SelectStart.x, SelectStart.y,
2134     SelectEnd.x, SelectEnd.y, BoxSelect,
2135     &str_len);
2136    
2137     // �e�[�u���`��������
2138     if (Table) {
2139     size_t table_len;
2140     wchar_t *table_ptr = ConvertTable(str_ptr, str_len, &table_len);
2141     free(str_ptr);
2142     str_ptr = table_ptr;
2143     str_len = table_len;
2144     }
2145 zmatsuo 8676 return str_ptr;
2146 doda 8445 }
2147    
2148 maya 3227 void BuffPrint(BOOL ScrollRegion)
2149     // Print screen or selected text
2150     {
2151 maya 3393 int Id;
2152     POINT PrintStart, PrintEnd;
2153     TCharAttr CurAttr, TempAttr;
2154     int i, j, count;
2155     int IStart, IEnd;
2156     LONG TmpPtr;
2157 maya 3227
2158 maya 3393 TempAttr = DefCharAttr;
2159 maya 3227
2160 maya 3393 if (ScrollRegion) {
2161     Id = VTPrintInit(IdPrnScrollRegion);
2162     }
2163     else if (Selected) {
2164     Id = VTPrintInit(IdPrnScreen | IdPrnSelectedText);
2165     }
2166     else {
2167     Id = VTPrintInit(IdPrnScreen);
2168     }
2169     if (Id==IdPrnCancel) {
2170     return;
2171     }
2172 maya 3227
2173 maya 3393 /* set print region */
2174     if (Id==IdPrnSelectedText) {
2175     /* print selected region */
2176     PrintStart = SelectStart;
2177     PrintEnd = SelectEnd;
2178     }
2179     else if (Id==IdPrnScrollRegion) {
2180     /* print scroll region */
2181     PrintStart.x = 0;
2182     PrintStart.y = PageStart + CursorTop;
2183     PrintEnd.x = NumOfColumns;
2184     PrintEnd.y = PageStart + CursorBottom;
2185     }
2186     else {
2187     /* print current screen */
2188     PrintStart.x = 0;
2189     PrintStart.y = PageStart;
2190     PrintEnd.x = NumOfColumns;
2191     PrintEnd.y = PageStart + NumOfLines - 1;
2192     }
2193     if (PrintEnd.y > BuffEnd-1) {
2194     PrintEnd.y = BuffEnd-1;
2195     }
2196 maya 3227
2197 maya 3393 LockBuffer();
2198 maya 3227
2199 maya 3393 TmpPtr = GetLinePtr(PrintStart.y);
2200     for (j = PrintStart.y ; j <= PrintEnd.y ; j++) {
2201     if (j==PrintStart.y) {
2202     IStart = PrintStart.x;
2203     }
2204     else {
2205     IStart = 0;
2206     }
2207     if (j == PrintEnd.y) {
2208     IEnd = PrintEnd.x - 1;
2209     }
2210     else {
2211     IEnd = NumOfColumns - 1;
2212     }
2213 maya 3227
2214 maya 3393 while ((IEnd>=IStart) &&
2215     (CodeBuff[TmpPtr+IEnd]==0x20) &&
2216     (AttrBuff[TmpPtr+IEnd]==AttrDefault)