1 /* ------------- textbox.c ------------ */
5 static void ComputeWindowTop(DFWINDOW
);
6 static void ComputeWindowLeft(DFWINDOW
);
7 static int ComputeVScrollBox(DFWINDOW
);
8 static int ComputeHScrollBox(DFWINDOW
);
9 static void MoveScrollBox(DFWINDOW
, int);
10 static char *GetTextLine(DFWINDOW
, int);
15 /* ------------ DFM_ADDTEXT Message -------------- */
16 static BOOL
AddTextMsg(DFWINDOW wnd
, char *txt
)
18 /* --- append text to the textbox's buffer --- */
19 unsigned adln
= strlen(txt
);
20 if (adln
> (unsigned)0xfff0)
22 if (wnd
->text
!= NULL
) {
23 /* ---- appending to existing text ---- */
24 unsigned txln
= strlen(wnd
->text
);
25 if ((long)txln
+adln
> (unsigned) 0xfff0)
27 if (txln
+adln
> wnd
->textlen
) {
28 wnd
->text
= DfRealloc(wnd
->text
, txln
+adln
+3);
29 wnd
->textlen
= txln
+adln
+1;
33 /* ------ 1st text appended ------ */
34 wnd
->text
= DfCalloc(1, adln
+3);
35 wnd
->textlen
= adln
+1;
37 if (wnd
->text
!= NULL
) {
38 /* ---- append the text ---- */
39 strcat(wnd
->text
, txt
);
40 strcat(wnd
->text
, "\n");
41 DfBuildTextPointers(wnd
);
47 /* ------------ DFM_DELETETEXT Message -------------- */
48 static void DeleteTextMsg(DFWINDOW wnd
, int lno
)
50 char *cp1
= DfTextLine(wnd
, lno
);
52 if (lno
== wnd
->wlines
)
55 char *cp2
= DfTextLine(wnd
, lno
+1);
56 memmove(cp1
, cp2
, strlen(cp2
)+1);
58 DfBuildTextPointers(wnd
);
61 /* ------------ DFM_INSERTTEXT Message -------------- */
62 static void InsertTextMsg(DFWINDOW wnd
, char *txt
, int lno
)
64 if (AddTextMsg(wnd
, txt
)) {
65 int len
= strlen(txt
);
66 char *cp2
= DfTextLine(wnd
, lno
);
67 char *cp1
= cp2
+len
+1;
68 memmove(cp1
, cp2
, strlen(cp2
)-len
);
71 DfBuildTextPointers(wnd
);
75 /* ------------ DFM_SETTEXT Message -------------- */
76 static void SetTextMsg(DFWINDOW wnd
, char *txt
)
78 /* -- assign new text value to textbox buffer -- */
79 unsigned int len
= strlen(txt
)+1;
80 DfSendMessage(wnd
, DFM_CLEARTEXT
, 0, 0);
82 wnd
->text
=DfRealloc(wnd
->text
, len
+1);
83 wnd
->text
[len
] = '\0';
84 strcpy(wnd
->text
, txt
);
85 DfBuildTextPointers(wnd
);
88 /* ------------ DFM_CLEARTEXT Message -------------- */
89 static void ClearTextMsg(DFWINDOW wnd
)
91 /* ----- clear text from textbox ----- */
92 if (wnd
->text
!= NULL
)
98 wnd
->wtop
= wnd
->wleft
= 0;
99 DfClearTextBlock(wnd
);
100 DfClearTextPointers(wnd
);
103 /* ------------ DFM_KEYBOARD Message -------------- */
104 static int KeyboardMsg(DFWINDOW wnd
, DF_PARAM p1
)
108 return DfSendMessage(wnd
,DFM_SCROLL
,FALSE
,0);
110 return DfSendMessage(wnd
,DFM_SCROLL
,TRUE
,0);
112 return DfSendMessage(wnd
,DFM_HORIZSCROLL
,TRUE
,0);
114 return DfSendMessage(wnd
,DFM_HORIZSCROLL
,FALSE
,0);
116 return DfSendMessage(wnd
,DFM_SCROLLPAGE
,FALSE
,0);
118 return DfSendMessage(wnd
,DFM_SCROLLPAGE
,TRUE
,0);
120 return DfSendMessage(wnd
,DFM_HORIZPAGE
,FALSE
,0);
122 return DfSendMessage(wnd
,DFM_HORIZPAGE
,TRUE
,0);
124 return DfSendMessage(wnd
,DFM_SCROLLDOC
,TRUE
,0);
126 return DfSendMessage(wnd
,DFM_SCROLLDOC
,FALSE
,0);
133 /* ------------ DFM_LEFT_BUTTON Message -------------- */
134 static int LeftButtonMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
136 int mx
= (int) p1
- DfGetLeft(wnd
);
137 int my
= (int) p2
- DfGetTop(wnd
);
138 if (DfTestAttribute(wnd
, DF_VSCROLLBAR
) &&
139 mx
== DfWindowWidth(wnd
)-1) {
140 /* -------- in the right border ------- */
141 if (my
== 0 || my
== DfClientHeight(wnd
)+1)
142 /* --- above or below the scroll bar --- */
145 /* -------- top scroll button --------- */
146 return DfSendMessage(wnd
, DFM_SCROLL
, FALSE
, 0);
147 if (my
== DfClientHeight(wnd
))
148 /* -------- bottom scroll button --------- */
149 return DfSendMessage(wnd
, DFM_SCROLL
, TRUE
, 0);
150 /* ---------- in the scroll bar ----------- */
151 if (!DfVSliding
&& my
-1 == wnd
->VScrollBox
) {
154 rc
.lf
= rc
.rt
= DfGetRight(wnd
);
155 rc
.tp
= DfGetTop(wnd
)+2;
156 rc
.bt
= DfGetBottom(wnd
)-2;
157 return DfSendMessage(NULL
, DFM_MOUSE_TRAVEL
,
160 if (my
-1 < wnd
->VScrollBox
)
161 return DfSendMessage(wnd
,DFM_SCROLLPAGE
,FALSE
,0);
162 if (my
-1 > wnd
->VScrollBox
)
163 return DfSendMessage(wnd
,DFM_SCROLLPAGE
,TRUE
,0);
165 if (DfTestAttribute(wnd
, DF_HSCROLLBAR
) &&
166 my
== DfWindowHeight(wnd
)-1) {
167 /* -------- in the bottom border ------- */
168 if (mx
== 0 || my
== DfClientWidth(wnd
)+1)
169 /* ------ outside the scroll bar ---- */
172 return DfSendMessage(wnd
, DFM_HORIZSCROLL
,FALSE
,0);
173 if (mx
== DfWindowWidth(wnd
)-2)
174 return DfSendMessage(wnd
, DFM_HORIZSCROLL
,TRUE
,0);
175 if (!DfHSliding
&& mx
-1 == wnd
->HScrollBox
) {
176 /* --- hit the scroll box --- */
178 rc
.lf
= DfGetLeft(wnd
)+2;
179 rc
.rt
= DfGetRight(wnd
)-2;
180 rc
.tp
= rc
.bt
= DfGetBottom(wnd
);
181 /* - keep the mouse in the scroll bar - */
182 DfSendMessage(NULL
,DFM_MOUSE_TRAVEL
,(DF_PARAM
)&rc
,0);
186 if (mx
-1 < wnd
->HScrollBox
)
187 return DfSendMessage(wnd
,DFM_HORIZPAGE
,FALSE
,0);
188 if (mx
-1 > wnd
->HScrollBox
)
189 return DfSendMessage(wnd
,DFM_HORIZPAGE
,TRUE
,0);
194 /* ------------ MOUSE_MOVED Message -------------- */
195 static BOOL
MouseMovedMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
197 int mx
= (int) p1
- DfGetLeft(wnd
);
198 int my
= (int) p2
- DfGetTop(wnd
);
200 /* ---- dragging the vertical scroll box --- */
201 if (my
-1 != wnd
->VScrollBox
) {
202 DfForeground
= DfFrameForeground(wnd
);
203 DfBackground
= DfFrameBackground(wnd
);
204 DfWPutch(wnd
, DF_SCROLLBARCHAR
, DfWindowWidth(wnd
)-1,
206 wnd
->VScrollBox
= my
-1;
207 DfWPutch(wnd
, DF_SCROLLBOXCHAR
, DfWindowWidth(wnd
)-1,
213 /* --- dragging the horizontal scroll box --- */
214 if (mx
-1 != wnd
->HScrollBox
) {
215 DfForeground
= DfFrameForeground(wnd
);
216 DfBackground
= DfFrameBackground(wnd
);
217 DfWPutch(wnd
, DF_SCROLLBARCHAR
, wnd
->HScrollBox
+1,
218 DfWindowHeight(wnd
)-1);
219 wnd
->HScrollBox
= mx
-1;
220 DfWPutch(wnd
, DF_SCROLLBOXCHAR
, mx
, DfWindowHeight(wnd
)-1);
227 /* ------------ BUTTON_RELEASED Message -------------- */
228 static void ButtonReleasedMsg(DFWINDOW wnd
)
230 if (DfHSliding
|| DfVSliding
) {
231 /* release the mouse ouside the scroll bar */
232 DfSendMessage(NULL
, DFM_MOUSE_TRAVEL
, 0, 0);
233 DfVSliding
? ComputeWindowTop(wnd
):ComputeWindowLeft(wnd
);
234 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
235 DfSendMessage(wnd
, DFM_KEYBOARD_CURSOR
, 0, 0);
236 DfVSliding
= DfHSliding
= FALSE
;
240 /* ------------ DFM_SCROLL Message -------------- */
241 static BOOL
ScrollMsg(DFWINDOW wnd
, DF_PARAM p1
)
243 /* ---- vertical scroll one line ---- */
245 /* ----- scroll one line up ----- */
246 if (wnd
->wtop
+DfClientHeight(wnd
) >= wnd
->wlines
)
251 /* ----- scroll one line down ----- */
256 if (DfIsVisible(wnd
)) {
258 rc
= DfClipRectangle(wnd
, DfClientRect(wnd
));
259 if (DfValidRect(rc
)) {
260 /* ---- scroll the window ----- */
261 if (wnd
!= DfInFocus
)
262 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
264 DfScrollWindow(wnd
, rc
, (int)p1
);
266 /* -- write top line (down) -- */
267 DfWriteTextLine(wnd
,NULL
,wnd
->wtop
,FALSE
);
269 /* -- write bottom line (up) -- */
270 int y
=DfRectBottom(rc
)-DfGetClientTop(wnd
);
271 DfWriteTextLine(wnd
, NULL
,
276 /* ---- reset the scroll box ---- */
277 if (DfTestAttribute(wnd
, DF_VSCROLLBAR
)) {
278 int vscrollbox
= ComputeVScrollBox(wnd
);
279 if (vscrollbox
!= wnd
->VScrollBox
)
280 MoveScrollBox(wnd
, vscrollbox
);
286 /* ------------ DFM_HORIZSCROLL Message -------------- */
287 static BOOL
HorizScrollMsg(DFWINDOW wnd
, DF_PARAM p1
)
289 /* --- horizontal scroll one column --- */
291 /* --- scroll left --- */
292 if (wnd
->wleft
+ DfClientWidth(wnd
)-1 >= wnd
->textwidth
)
297 /* --- scroll right --- */
302 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
306 /* ------------ DFM_SCROLLPAGE Message -------------- */
307 static void ScrollPageMsg(DFWINDOW wnd
, DF_PARAM p1
)
309 /* --- vertical scroll one page --- */
310 if ((int) p1
== FALSE
) {
311 /* ---- page up ---- */
313 wnd
->wtop
-= DfClientHeight(wnd
);
316 /* ---- page down ---- */
317 if (wnd
->wtop
+DfClientHeight(wnd
) < wnd
->wlines
) {
318 wnd
->wtop
+= DfClientHeight(wnd
);
319 if (wnd
->wtop
>wnd
->wlines
-DfClientHeight(wnd
))
320 wnd
->wtop
=wnd
->wlines
-DfClientHeight(wnd
);
325 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
328 /* ------------ HORIZSCROLLPAGE Message -------------- */
329 static void HorizScrollPageMsg(DFWINDOW wnd
, DF_PARAM p1
)
331 /* --- horizontal scroll one page --- */
332 if ((int) p1
== FALSE
)
333 /* ---- page left ----- */
334 wnd
->wleft
-= DfClientWidth(wnd
);
336 /* ---- page right ----- */
337 wnd
->wleft
+= DfClientWidth(wnd
);
338 if (wnd
->wleft
> wnd
->textwidth
-DfClientWidth(wnd
))
339 wnd
->wleft
= wnd
->textwidth
-DfClientWidth(wnd
);
343 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
346 /* ------------ DFM_SCROLLDOC Message -------------- */
347 static void ScrollDocMsg(DFWINDOW wnd
, DF_PARAM p1
)
349 /* --- scroll to beginning or end of document --- */
351 wnd
->wtop
= wnd
->wleft
= 0;
352 else if (wnd
->wtop
+DfClientHeight(wnd
) < wnd
->wlines
){
353 wnd
->wtop
= wnd
->wlines
-DfClientHeight(wnd
);
356 DfSendMessage(wnd
, DFM_PAINT
, 0, 0);
359 /* ------------ DFM_PAINT Message -------------- */
360 static void PaintMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
362 /* ------ paint the client area ----- */
367 /* ----- build the rectangle to paint ----- */
368 if ((DFRECT
*)p1
== NULL
)
369 rc
=DfRelativeWindowRect(wnd
, DfWindowRect(wnd
));
372 if (DfTestAttribute(wnd
, DF_HASBORDER
) &&
373 DfRectRight(rc
) >= DfWindowWidth(wnd
)-1) {
374 if (DfRectLeft(rc
) >= DfWindowWidth(wnd
)-1)
376 DfRectRight(rc
) = DfWindowWidth(wnd
)-2;
378 rcc
= DfAdjustRectangle(wnd
, rc
);
380 if (!p2
&& wnd
!= DfInFocus
)
383 /* ----- blank line for padding ----- */
384 memset(blankline
, ' ', DfGetScreenWidth());
385 blankline
[DfRectRight(rcc
)+1] = '\0';
387 /* ------- each line DfWithin rectangle ------ */
388 for (y
= DfRectTop(rc
); y
<= DfRectBottom(rc
); y
++){
390 /* ---- test outside of Client area ---- */
391 if (DfTestAttribute(wnd
,
392 DF_HASBORDER
| DF_HASTITLEBAR
)) {
393 if (y
< DfTopBorderAdj(wnd
))
395 if (y
> DfWindowHeight(wnd
)-2)
398 yy
= y
-DfTopBorderAdj(wnd
);
399 if (yy
< wnd
->wlines
-wnd
->wtop
)
400 /* ---- paint a text line ---- */
401 DfWriteTextLine(wnd
, &rc
,
402 yy
+wnd
->wtop
, FALSE
);
404 /* ---- paint a blank line ---- */
405 DfSetStandardColor(wnd
);
406 DfWriteLine(wnd
, blankline
+DfRectLeft(rcc
),
407 DfRectLeft(rcc
)+DfBorderAdj(wnd
), y
, FALSE
);
410 /* ------- position the scroll box ------- */
411 if (DfTestAttribute(wnd
, DF_VSCROLLBAR
|DF_HSCROLLBAR
)) {
412 int hscrollbox
= ComputeHScrollBox(wnd
);
413 int vscrollbox
= ComputeVScrollBox(wnd
);
414 if (hscrollbox
!= wnd
->HScrollBox
||
415 vscrollbox
!= wnd
->VScrollBox
) {
416 wnd
->HScrollBox
= hscrollbox
;
417 wnd
->VScrollBox
= vscrollbox
;
418 DfSendMessage(wnd
, DFM_BORDER
, p1
, 0);
421 if (!p2
&& wnd
!= DfInFocus
)
425 /* ------------ DFM_CLOSE_WINDOW Message -------------- */
426 static void CloseWindowMsg(DFWINDOW wnd
)
428 DfSendMessage(wnd
, DFM_CLEARTEXT
, 0, 0);
429 if (wnd
->TextPointers
!= NULL
) {
430 free(wnd
->TextPointers
);
431 wnd
->TextPointers
= NULL
;
435 /* ----------- DF_TEXTBOX Message-processing Module ----------- */
436 int DfTextBoxProc(DFWINDOW wnd
, DFMESSAGE msg
, DF_PARAM p1
, DF_PARAM p2
)
439 case DFM_CREATE_WINDOW
:
440 wnd
->HScrollBox
= wnd
->VScrollBox
= 1;
441 DfClearTextPointers(wnd
);
444 return AddTextMsg(wnd
, (char *) p1
);
446 DeleteTextMsg(wnd
, (int) p1
);
449 InsertTextMsg(wnd
, (char *) p1
, (int) p2
);
452 SetTextMsg(wnd
, (char *) p1
);
458 if (DfWindowMoving
|| DfWindowSizing
)
460 if (KeyboardMsg(wnd
, p1
))
463 case DFM_LEFT_BUTTON
:
464 if (DfWindowSizing
|| DfWindowMoving
)
466 if (LeftButtonMsg(wnd
, p1
, p2
))
470 if (MouseMovedMsg(wnd
, p1
, p2
))
473 case DFM_BUTTON_RELEASED
:
474 ButtonReleasedMsg(wnd
);
477 return ScrollMsg(wnd
, p1
);
478 case DFM_HORIZSCROLL
:
479 return HorizScrollMsg(wnd
, p1
);
481 ScrollPageMsg(wnd
, p1
);
484 HorizScrollPageMsg(wnd
, p1
);
487 ScrollDocMsg(wnd
, p1
);
490 if (DfIsVisible(wnd
))
492 PaintMsg(wnd
, p1
, p2
);
496 case DFM_CLOSE_WINDOW
:
502 return DfBaseWndProc(DF_TEXTBOX
, wnd
, msg
, p1
, p2
);
505 /* ------ compute the vertical scroll box position from
506 the text pointers --------- */
507 static int ComputeVScrollBox(DFWINDOW wnd
)
509 int pagelen
= wnd
->wlines
- DfClientHeight(wnd
);
510 int barlen
= DfClientHeight(wnd
)-2;
514 if (pagelen
< 1 || barlen
< 1)
517 if (pagelen
> barlen
)
518 lines_tick
= pagelen
/ barlen
;
520 lines_tick
= barlen
/ pagelen
;
521 vscrollbox
= 1 + (wnd
->wtop
/ lines_tick
);
522 if (vscrollbox
> DfClientHeight(wnd
)-2 ||
523 wnd
->wtop
+ DfClientHeight(wnd
) >= wnd
->wlines
)
524 vscrollbox
= DfClientHeight(wnd
)-2;
529 /* ---- compute top text line from scroll box position ---- */
530 static void ComputeWindowTop(DFWINDOW wnd
)
532 int pagelen
= wnd
->wlines
- DfClientHeight(wnd
);
533 if (wnd
->VScrollBox
== 0)
535 else if (wnd
->VScrollBox
== DfClientHeight(wnd
)-2)
538 int barlen
= DfClientHeight(wnd
)-2;
541 if (pagelen
> barlen
)
542 lines_tick
= barlen
? (pagelen
/ barlen
) : 0;
544 lines_tick
= pagelen
? (barlen
/ pagelen
) : 0;
545 wnd
->wtop
= (wnd
->VScrollBox
-1) * lines_tick
;
546 if (wnd
->wtop
+ DfClientHeight(wnd
) > wnd
->wlines
)
553 /* ------ compute the horizontal scroll box position from
554 the text pointers --------- */
555 static int ComputeHScrollBox(DFWINDOW wnd
)
557 int pagewidth
= wnd
->textwidth
- DfClientWidth(wnd
);
558 int barlen
= DfClientWidth(wnd
)-2;
562 if (pagewidth
< 1 || barlen
< 1)
565 if (pagewidth
> barlen
)
566 chars_tick
= barlen
? (pagewidth
/ barlen
) : 0;
568 chars_tick
= pagewidth
? (barlen
/ pagewidth
) : 0;
569 hscrollbox
= 1 + (chars_tick
? (wnd
->wleft
/ chars_tick
) : 0);
570 if (hscrollbox
> DfClientWidth(wnd
)-2 ||
571 wnd
->wleft
+ DfClientWidth(wnd
) >= wnd
->textwidth
)
572 hscrollbox
= DfClientWidth(wnd
)-2;
577 /* ---- compute left column from scroll box position ---- */
578 static void ComputeWindowLeft(DFWINDOW wnd
)
580 int pagewidth
= wnd
->textwidth
- DfClientWidth(wnd
);
582 if (wnd
->HScrollBox
== 0)
584 else if (wnd
->HScrollBox
== DfClientWidth(wnd
)-2)
585 wnd
->wleft
= pagewidth
;
587 int barlen
= DfClientWidth(wnd
)-2;
590 if (pagewidth
> barlen
)
591 chars_tick
= pagewidth
/ barlen
;
593 chars_tick
= barlen
/ pagewidth
;
594 wnd
->wleft
= (wnd
->HScrollBox
-1) * chars_tick
;
595 if (wnd
->wleft
+ DfClientWidth(wnd
) > wnd
->textwidth
)
596 wnd
->wleft
= pagewidth
;
602 /* ----- get the text to a specified line ----- */
603 static char *GetTextLine(DFWINDOW wnd
, int selection
)
608 cp
= cp1
= DfTextLine(wnd
, selection
);
609 while (*cp
&& *cp
!= '\n') {
613 line
= DfMalloc(len
+7);
614 memmove(line
, cp1
, len
);
619 /* ------- write a line of text to a textbox window ------- */
620 void DfWriteTextLine(DFWINDOW wnd
, DFRECT
*rcc
, int y
, BOOL reverse
)
631 /* ------ make sure y is inside the window ----- */
632 if (y
< wnd
->wtop
|| y
>= wnd
->wtop
+DfClientHeight(wnd
))
635 /* ---- build the retangle DfWithin which can write ---- */
637 rc
= DfRelativeWindowRect(wnd
, DfWindowRect(wnd
));
638 if (DfTestAttribute(wnd
, DF_HASBORDER
) &&
639 DfRectRight(rc
) >= DfWindowWidth(wnd
)-1)
640 DfRectRight(rc
) = DfWindowWidth(wnd
)-2;
645 /* ----- make sure rectangle is DfWithin window ------ */
646 if (DfRectLeft(rc
) >= DfWindowWidth(wnd
)-1)
648 if (DfRectRight(rc
) == 0)
650 rc
= DfAdjustRectangle(wnd
, rc
);
651 if (y
-wnd
->wtop
<DfRectTop(rc
) || y
-wnd
->wtop
>DfRectBottom(rc
))
654 /* --- get the text and length of the text line --- */
655 lp
= svlp
= GetTextLine(wnd
, y
);
658 lnlen
= DfLineLength(lp
);
660 /* -------- insert block DfColor change controls ------- */
661 if (DfTextBlockMarked(wnd
)) {
662 int bbl
= wnd
->BlkBegLine
;
663 int bel
= wnd
->BlkEndLine
;
664 int bbc
= wnd
->BlkBegCol
;
665 int bec
= wnd
->BlkEndCol
;
668 /* ----- put lowest marker first ----- */
673 if (bbl
== bel
&& bbc
> bec
)
676 if (by
>= bbl
&& by
<= bel
) {
677 /* ------ the block includes this line ----- */
680 if (!(by
> bbl
&& by
< bel
)) {
681 /* --- the entire line is not in the block -- */
683 /* ---- the block begins on this line --- */
686 /* ---- the block ends on this line ---- */
689 if (blkend
== 0 && lnlen
== 0) {
693 /* ----- insert the reset DfColor token ----- */
694 memmove(lp
+blkend
+1,lp
+blkend
,strlen(lp
+blkend
)+1);
695 lp
[blkend
] = DF_RESETCOLOR
;
696 /* ----- insert the change DfColor token ----- */
697 memmove(lp
+blkbeg
+3,lp
+blkbeg
,strlen(lp
+blkbeg
)+1);
698 lp
[blkbeg
] = DF_CHANGECOLOR
;
699 /* ----- insert the DfColor tokens ----- */
700 DfSetReverseColor(wnd
);
701 lp
[blkbeg
+1] = DfForeground
| 0x80;
702 lp
[blkbeg
+2] = DfBackground
| 0x80;
706 /* - make sure left margin doesn't overlap DfColor change - */
707 for (i
= 0; i
< wnd
->wleft
+3; i
++) {
710 if (*(lp
+ i
) == DF_RESETCOLOR
)
713 if (*(lp
+i
) && i
< wnd
->wleft
+3) {
714 if (wnd
->wleft
+4 > lnlen
)
720 /* --- it does, shift the DfColor change over --- */
721 for (i
= 0; i
< wnd
->wleft
; i
++) {
724 if (*(lp
+ i
) == DF_CHANGECOLOR
) {
725 *(lp
+wnd
->wleft
+2) = *(lp
+i
+2);
726 *(lp
+wnd
->wleft
+1) = *(lp
+i
+1);
727 *(lp
+wnd
->wleft
) = *(lp
+i
);
732 /* ------ build the line to display -------- */
734 if (lnlen
< wnd
->wleft
)
738 if (lnlen
> DfRectLeft(rc
)) {
739 /* ---- the line exceeds the rectangle ---- */
740 int ct
= DfRectLeft(rc
);
742 /* --- point to end of clipped line --- */
744 if (*lp
== DF_CHANGECOLOR
)
746 else if (*lp
== DF_RESETCOLOR
)
751 if (DfRectLeft(rc
)) {
754 if (*lpp
==DF_CHANGECOLOR
)
756 if (*lpp
==DF_RESETCOLOR
) {
758 while (lpp
>= initlp
) {
759 if (*lpp
== DF_CHANGECOLOR
) {
771 lnlen
= DfLineLength(lp
);
772 len
= min(lnlen
, DfRectWidth(rc
));
773 dif
= strlen(lp
) - lnlen
;
776 strncpy(line
, lp
, len
);
779 /* -------- pad the line --------- */
780 while (len
< DfRectWidth(rc
)+dif
)
784 /* ------ establish the line's main DfColor ----- */
787 DfSetReverseColor(wnd
);
788 while ((cp
= strchr(cp
, DF_CHANGECOLOR
)) != NULL
) {
790 *cp
++ = DfBackground
| 0x80;
792 if (*line
== DF_CHANGECOLOR
)
796 DfSetStandardColor(wnd
);
797 /* ------- display the line -------- */
798 DfWriteLine(wnd
, line
+dif
,
799 DfRectLeft(rc
)+DfBorderAdj(wnd
),
800 y
-wnd
->wtop
+DfTopBorderAdj(wnd
), FALSE
);
804 void DfMarkTextBlock(DFWINDOW wnd
, int BegLine
, int BegCol
,
805 int EndLine
, int EndCol
)
807 wnd
->BlkBegLine
= BegLine
;
808 wnd
->BlkEndLine
= EndLine
;
809 wnd
->BlkBegCol
= BegCol
;
810 wnd
->BlkEndCol
= EndCol
;
813 /* ----- clear and initialize text line pointer array ----- */
814 void DfClearTextPointers(DFWINDOW wnd
)
816 wnd
->TextPointers
= DfRealloc(wnd
->TextPointers
, sizeof(int));
817 *(wnd
->TextPointers
) = 0;
820 #define INITLINES 100
822 /* ---- build array of pointers to text lines ---- */
823 void DfBuildTextPointers(DFWINDOW wnd
)
825 char *cp
= wnd
->text
, *cp1
;
826 int incrs
= INITLINES
;
828 wnd
->textwidth
= wnd
->wlines
= 0;
830 if (incrs
== INITLINES
) {
832 wnd
->TextPointers
= DfRealloc(wnd
->TextPointers
,
833 (wnd
->wlines
+ INITLINES
) * sizeof(int));
835 off
= (unsigned int) ((unsigned int)cp
- (unsigned int)wnd
->text
);
836 *((wnd
->TextPointers
) + wnd
->wlines
) = off
;
840 while (*cp
&& *cp
!= '\n')
842 wnd
->textwidth
= max(wnd
->textwidth
, (int)(cp
- cp1
));
848 static void MoveScrollBox(DFWINDOW wnd
, int vscrollbox
)
850 DfForeground
= DfFrameForeground(wnd
);
851 DfBackground
= DfFrameBackground(wnd
);
852 DfWPutch(wnd
, DF_SCROLLBARCHAR
, DfWindowWidth(wnd
)-1,
854 DfWPutch(wnd
, DF_SCROLLBOXCHAR
, DfWindowWidth(wnd
)-1,
856 wnd
->VScrollBox
= vscrollbox
;
859 int DfTextLineNumber(DFWINDOW wnd
, char *lp
)
863 for (lineno
= 0; lineno
< wnd
->wlines
; lineno
++) {
864 cp
= wnd
->text
+ *((wnd
->TextPointers
) + lineno
);