1 /* ------------- normal.c ------------ */
3 #include "dflat32/dflat.h"
5 #ifdef INCLUDE_MULTI_WINDOWS
6 static void PaintOverLappers(DFWINDOW wnd
);
7 static void PaintUnderLappers(DFWINDOW wnd
);
10 static BOOL
InsideWindow(DFWINDOW
, int, int);
11 static void TerminateMoveSize(void);
12 static void SaveBorder(DFRECT
);
13 static void RestoreBorder(DFRECT
);
14 static void GetVideoBuffer(DFWINDOW
);
15 static void PutVideoBuffer(DFWINDOW
);
16 #ifdef INCLUDE_MINIMIZE
17 static DFRECT
PositionIcon(DFWINDOW
);
19 static void dragborder(DFWINDOW
, int, int);
20 static void sizeborder(DFWINDOW
, int, int);
21 static int px
= -1, py
= -1;
23 static struct window dwnd
= {DUMMY
, NULL
, NormalProc
,
25 static PCHAR_INFO Bsave
;
29 /* -------- array of class definitions -------- */
30 CLASSDEFS classdefs
[] = {
32 #define ClassDef(c,b,p,a) {b,p,a},
33 #include "dflat32/classes.h"
35 DFWINDOW HiddenWindow
;
37 /* --------- CREATE_WINDOW Message ---------- */
38 static void CreateWindowMsg(DFWINDOW wnd
)
41 // ClearAttribute(wnd, VSCROLLBAR | HSCROLLBAR);
42 if (TestAttribute(wnd
, SAVESELF
) && isVisible(wnd
))
46 /* --------- SHOW_WINDOW Message ---------- */
47 static void ShowWindowMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
49 if (GetParent(wnd
) == NULL
|| isVisible(GetParent(wnd
)))
53 if (TestAttribute(wnd
, SAVESELF
) && wnd
->videosave
== NULL
)
56 DfSendMessage(wnd
, PAINT
, 0, TRUE
);
57 DfSendMessage(wnd
, BORDER
, 0, 0);
58 /* --- show the children of this window --- */
59 cwnd
= FirstWindow(wnd
);
62 if (cwnd
->condition
!= ISCLOSING
)
63 DfSendMessage(cwnd
, SHOW_WINDOW
, p1
, p2
);
64 cwnd
= NextWindow(cwnd
);
69 /* --------- HIDE_WINDOW Message ---------- */
70 static void HideWindowMsg(DFWINDOW wnd
)
75 /* --- paint what this window covered --- */
76 if (TestAttribute(wnd
, SAVESELF
))
78 #ifdef INCLUDE_MULTI_WINDOWS
80 PaintOverLappers(wnd
);
85 /* --------- KEYBOARD Message ---------- */
86 static BOOL
KeyboardMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
88 if (WindowMoving
|| WindowSizing
) {
89 /* -- move or size a window with keyboard -- */
91 x
=WindowMoving
?GetLeft(&dwnd
):GetRight(&dwnd
);
92 y
=WindowMoving
?GetTop(&dwnd
):GetBottom(&dwnd
);
102 if (y
< DfGetScreenHeight()-1)
106 if (x
< DfGetScreenWidth()-1)
114 DfSendMessage(wnd
, DFM_BUTTON_RELEASED
,x
,y
);
118 /* -- use the mouse functions to move/size - */
119 DfSendMessage(wnd
, MOUSE_MOVED
, x
, y
);
126 DfSendMessage(wnd
, DFM_COMMAND
, ID_HELP
, 0);
130 if ((int)p2
& ALTKEY
)
131 if (TestAttribute(wnd
, HASTITLEBAR
))
132 if (TestAttribute(wnd
, CONTROLBOX
))
133 BuildSystemMenu(wnd
);
137 if (TestAttribute(wnd
, CONTROLBOX
))
139 DfSendMessage(wnd
, CLOSE_WINDOW
, 0, 0);
140 SkipApplicationControls();
152 /* --------- COMMAND Message ---------- */
153 static void CommandMsg(DFWINDOW wnd
, PARAM p1
)
157 DisplayHelp(wnd
,ClassNames
[GetClass(wnd
)]);
159 #ifdef INCLUDE_RESTORE
161 DfSendMessage(wnd
, RESTORE
, 0, 0);
165 DfSendMessage(wnd
, CAPTURE_MOUSE
, TRUE
,
167 DfSendMessage(wnd
, CAPTURE_KEYBOARD
, TRUE
,
170 dragborder(wnd
, GetLeft(wnd
), GetTop(wnd
));
173 DfSendMessage(wnd
, CAPTURE_MOUSE
, TRUE
,
175 DfSendMessage(wnd
, CAPTURE_KEYBOARD
, TRUE
,
178 dragborder(wnd
, GetLeft(wnd
), GetTop(wnd
));
180 #ifdef INCLUDE_MINIMIZE
182 DfSendMessage(wnd
, MINIMIZE
, 0, 0);
185 #ifdef INCLUDE_MAXIMIZE
187 DfSendMessage(wnd
, MAXIMIZE
, 0, 0);
191 DfSendMessage(wnd
, CLOSE_WINDOW
, 0, 0);
192 SkipApplicationControls();
199 /* --------- SETFOCUS Message ---------- */
200 static void SetFocusMsg(DFWINDOW wnd
, PARAM p1
)
202 DFRECT rc
= {0,0,0,0};
204 if (p1
&& wnd
!= NULL
&& inFocus
!= wnd
)
206 DFWINDOW
this, thispar
;
207 DFWINDOW that
= NULL
, thatpar
= NULL
;
209 DFWINDOW cwnd
= wnd
, fwnd
= GetParent(wnd
);
210 /* ---- post focus in ancestors ---- */
213 fwnd
->childfocus
= cwnd
;
215 fwnd
= GetParent(fwnd
);
217 /* ---- de-post focus in self and children ---- */
221 cwnd
= fwnd
->childfocus
;
222 fwnd
->childfocus
= NULL
;
227 that
= thatpar
= inFocus
;
229 /* ---- find common ancestor of prev focus and this window --- */
230 while (thatpar
!= NULL
)
233 while (thispar
!= NULL
)
235 if (this == CaptureMouse
|| this == CaptureKeyboard
)
237 /* ---- don't repaint if this window has capture ---- */
238 that
= thatpar
= NULL
;
241 if (thispar
== thatpar
)
243 /* ---- don't repaint if SAVESELF window had focus ---- */
244 if (this != that
&& TestAttribute(that
, SAVESELF
))
245 that
= thatpar
= NULL
;
249 thispar
= GetParent(thispar
);
254 thatpar
= GetParent(thatpar
);
257 DfSendMessage(inFocus
, SETFOCUS
, FALSE
, 0);
259 if (that
!= NULL
&& isVisible(wnd
))
261 rc
= subRectangle(WindowRect(that
), WindowRect(this));
264 if (ApplicationWindow
!= NULL
)
266 DFWINDOW fwnd
= FirstWindow(ApplicationWindow
);
269 if (!isAncestor(wnd
, fwnd
))
271 rc
= subRectangle(WindowRect(wnd
),WindowRect(fwnd
));
275 fwnd
= NextWindow(fwnd
);
280 if (that
!= NULL
&& !ValidRect(rc
) && isVisible(wnd
))
282 DfSendMessage(wnd
, BORDER
, 0, 0);
287 DfSendMessage(this, SHOW_WINDOW
, 0, 0);
289 else if (!p1
&& inFocus
== wnd
)
293 DfSendMessage(wnd
, BORDER
, 0, 0);
297 /* --------- DOUBLE_CLICK Message ---------- */
298 static void DoubleClickMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
300 int mx
= (int) p1
- GetLeft(wnd
);
301 int my
= (int) p2
- GetTop(wnd
);
302 if (!WindowSizing
&& !WindowMoving
) {
303 if (HitControlBox(wnd
, mx
, my
)) {
304 DfPostMessage(wnd
, CLOSE_WINDOW
, 0, 0);
305 SkipApplicationControls();
310 /* --------- LEFT_BUTTON Message ---------- */
311 static void LeftButtonMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
313 int mx
= (int) p1
- GetLeft(wnd
);
314 int my
= (int) p2
- GetTop(wnd
);
315 if (WindowSizing
|| WindowMoving
)
317 if (HitControlBox(wnd
, mx
, my
)) {
318 BuildSystemMenu(wnd
);
321 if (my
== 0 && mx
> -1 && mx
< WindowWidth(wnd
)) {
322 /* ---------- hit the top border -------- */
323 if (TestAttribute(wnd
, MINMAXBOX
) &&
324 TestAttribute(wnd
, HASTITLEBAR
)) {
325 if (mx
== WindowWidth(wnd
)-2) {
326 if (wnd
->condition
!= ISRESTORED
)
327 /* --- hit the restore box --- */
328 DfSendMessage(wnd
, RESTORE
, 0, 0);
329 #ifdef INCLUDE_MAXIMIZE
331 /* --- hit the maximize box --- */
332 DfSendMessage(wnd
, MAXIMIZE
, 0, 0);
336 #ifdef INCLUDE_MINIMIZE
337 if (mx
== WindowWidth(wnd
)-3) {
338 /* --- hit the minimize box --- */
339 if (wnd
->condition
!= ISMINIMIZED
)
340 DfSendMessage(wnd
, MINIMIZE
, 0, 0);
345 #ifdef INCLUDE_MAXIMIZE
346 if (wnd
->condition
== ISMAXIMIZED
)
349 if (TestAttribute(wnd
, MOVEABLE
)) {
354 DfSendMessage(wnd
, CAPTURE_MOUSE
, TRUE
,
356 dragborder(wnd
, GetLeft(wnd
), GetTop(wnd
));
360 if (mx
== WindowWidth(wnd
)-1 &&
361 my
== WindowHeight(wnd
)-1) {
362 /* ------- hit the resize corner ------- */
363 #ifdef INCLUDE_MINIMIZE
364 if (wnd
->condition
== ISMINIMIZED
)
367 if (!TestAttribute(wnd
, SIZEABLE
))
369 #ifdef INCLUDE_MAXIMIZE
370 if (wnd
->condition
== ISMAXIMIZED
) {
371 if (GetParent(wnd
) == NULL
)
373 if (TestAttribute(GetParent(wnd
),HASBORDER
))
375 /* ----- resizing a maximized window over a
376 borderless parent ----- */
377 wnd
= GetParent(wnd
);
381 DfSendMessage(wnd
, CAPTURE_MOUSE
,
382 TRUE
, (PARAM
) &dwnd
);
383 dragborder(wnd
, GetLeft(wnd
), GetTop(wnd
));
387 /* --------- MOUSE_MOVED Message ---------- */
388 static BOOL
MouseMovedMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
391 int leftmost
= 0, topmost
= 0,
392 bottommost
= DfGetScreenHeight()-2,
393 rightmost
= DfGetScreenWidth()-2;
394 int x
= (int) p1
- diff
;
396 if (GetParent(wnd
) != NULL
&&
397 !TestAttribute(wnd
, NOCLIP
)) {
398 DFWINDOW wnd1
= GetParent(wnd
);
399 topmost
= GetClientTop(wnd1
);
400 leftmost
= GetClientLeft(wnd1
);
401 bottommost
= GetClientBottom(wnd1
);
402 rightmost
= GetClientRight(wnd1
);
404 if (x
< leftmost
|| x
> rightmost
||
405 y
< topmost
|| y
> bottommost
) {
406 x
= max(x
, leftmost
);
407 x
= min(x
, rightmost
);
409 y
= min(y
, bottommost
);
412 if (x
!= px
|| y
!= py
) {
415 dragborder(wnd
, x
, y
);
420 sizeborder(wnd
, (int) p1
, (int) p2
);
426 #ifdef INCLUDE_MAXIMIZE
427 /* --------- MAXIMIZE Message ---------- */
428 static void MaximizeMsg(DFWINDOW wnd
)
430 DFRECT rc
= {0, 0, 0, 0};
432 holdrc
= wnd
->RestoredRC
;
433 rc
.rt
= DfGetScreenWidth()-1;
434 rc
.bt
= DfGetScreenHeight()-1;
436 rc
= ClientRect(GetParent(wnd
));
437 wnd
->oldcondition
= wnd
->condition
;
438 wnd
->condition
= ISMAXIMIZED
;
439 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
440 DfSendMessage(wnd
, MOVE
,
441 RectLeft(rc
), RectTop(rc
));
442 DfSendMessage(wnd
, DFM_SIZE
,
443 RectRight(rc
), RectBottom(rc
));
444 if (wnd
->restored_attrib
== 0)
445 wnd
->restored_attrib
= wnd
->attrib
;
446 ClearAttribute(wnd
, SHADOW
);
447 DfSendMessage(wnd
, SHOW_WINDOW
, 0, 0);
448 wnd
->RestoredRC
= holdrc
;
452 #ifdef INCLUDE_MINIMIZE
453 /* --------- MINIMIZE Message ---------- */
454 static void MinimizeMsg(DFWINDOW wnd
)
459 holdrc
= wnd
->RestoredRC
;
460 rc
= PositionIcon(wnd
);
461 wnd
->oldcondition
= wnd
->condition
;
462 wnd
->condition
= ISMINIMIZED
;
463 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
464 DfSendMessage(wnd
, MOVE
,
465 RectLeft(rc
), RectTop(rc
));
466 DfSendMessage(wnd
, DFM_SIZE
,
467 RectRight(rc
), RectBottom(rc
));
470 if (wnd
->restored_attrib
== 0)
471 wnd
->restored_attrib
= wnd
->attrib
;
473 SHADOW
| SIZEABLE
| HASMENUBAR
|
474 VSCROLLBAR
| HSCROLLBAR
);
475 DfSendMessage(wnd
, SHOW_WINDOW
, 0, 0);
476 wnd
->RestoredRC
= holdrc
;
480 #ifdef INCLUDE_RESTORE
481 /* --------- RESTORE Message ---------- */
482 static void RestoreMsg(DFWINDOW wnd
)
485 holdrc
= wnd
->RestoredRC
;
486 wnd
->oldcondition
= wnd
->condition
;
487 wnd
->condition
= ISRESTORED
;
488 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
489 wnd
->attrib
= wnd
->restored_attrib
;
490 wnd
->restored_attrib
= 0;
491 DfSendMessage(wnd
, MOVE
, wnd
->RestoredRC
.lf
,
493 wnd
->RestoredRC
= holdrc
;
494 DfSendMessage(wnd
, DFM_SIZE
, wnd
->RestoredRC
.rt
,
497 DfSendMessage(wnd
, SETFOCUS
, TRUE
, 0);
499 DfSendMessage(wnd
, SHOW_WINDOW
, 0, 0);
503 /* --------- MOVE Message ---------- */
504 static void MoveMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
507 BOOL wasVisible
= isVisible(wnd
);
508 int xdif
= (int) p1
- wnd
->rc
.lf
;
509 int ydif
= (int) p2
- wnd
->rc
.tp
;
511 if (xdif
== 0 && ydif
== 0)
514 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
515 wnd
->rc
.lf
= (int) p1
;
516 wnd
->rc
.tp
= (int) p2
;
517 wnd
->rc
.rt
= GetLeft(wnd
)+WindowWidth(wnd
)-1;
518 wnd
->rc
.bt
= GetTop(wnd
)+WindowHeight(wnd
)-1;
519 if (wnd
->condition
== ISRESTORED
)
520 wnd
->RestoredRC
= wnd
->rc
;
522 cwnd
= FirstWindow(wnd
);
523 while (cwnd
!= NULL
) {
524 DfSendMessage(cwnd
, MOVE
, cwnd
->rc
.lf
+xdif
, cwnd
->rc
.tp
+ydif
);
525 cwnd
= NextWindow(cwnd
);
528 DfSendMessage(wnd
, SHOW_WINDOW
, 0, 0);
531 /* --------- SIZE Message ---------- */
532 static void SizeMsg(DFWINDOW wnd
, PARAM p1
, PARAM p2
)
534 BOOL wasVisible
= isVisible(wnd
);
537 int xdif
= (int) p1
- wnd
->rc
.rt
;
538 int ydif
= (int) p2
- wnd
->rc
.bt
;
540 if (xdif
== 0 && ydif
== 0)
543 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
544 wnd
->rc
.rt
= (int) p1
;
545 wnd
->rc
.bt
= (int) p2
;
546 wnd
->ht
= GetBottom(wnd
)-GetTop(wnd
)+1;
547 wnd
->wd
= GetRight(wnd
)-GetLeft(wnd
)+1;
549 if (wnd
->condition
== ISRESTORED
)
550 wnd
->RestoredRC
= WindowRect(wnd
);
552 #ifdef INCLUDE_MAXIMIZE
553 rc
= ClientRect(wnd
);
555 cwnd
= FirstWindow(wnd
);
556 while (cwnd
!= NULL
) {
557 if (cwnd
->condition
== ISMAXIMIZED
)
558 DfSendMessage(cwnd
, DFM_SIZE
, RectRight(rc
), RectBottom(rc
));
559 cwnd
= NextWindow(cwnd
);
564 DfSendMessage(wnd
, SHOW_WINDOW
, 0, 0);
567 /* --------- CLOSE_WINDOW Message ---------- */
568 static void CloseWindowMsg(DFWINDOW wnd
)
571 wnd
->condition
= ISCLOSING
;
572 if (wnd
->PrevMouse
!= NULL
)
573 DfSendMessage(wnd
, RELEASE_MOUSE
, 0, 0);
574 if (wnd
->PrevKeyboard
!= NULL
)
575 DfSendMessage(wnd
, RELEASE_KEYBOARD
, 0, 0);
576 /* ----------- hide this window ------------ */
577 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
578 /* --- close the children of this window --- */
580 cwnd
= LastWindow(wnd
);
581 while (cwnd
!= NULL
) {
584 DfSendMessage(cwnd
,CLOSE_WINDOW
,0,0);
585 cwnd
= LastWindow(wnd
);
588 /* --- change focus if this window had it -- */
591 /* -- free memory allocated to this window - */
592 if (wnd
->title
!= NULL
)
594 if (wnd
->videosave
!= NULL
)
595 free(wnd
->videosave
);
596 /* -- remove window from parent's list of children -- */
603 /* ---- Window-processing module for NORMAL window class ---- */
604 int NormalProc(DFWINDOW wnd
, DFMESSAGE msg
, PARAM p1
, PARAM p2
)
608 CreateWindowMsg(wnd
);
611 ShowWindowMsg(wnd
, p1
, p2
);
613 case DFM_HIDE_WINDOW
:
617 DisplayHelp(wnd
, (char *)p1
);
620 return InsideWindow(wnd
, (int) p1
, (int) p2
);
622 if (KeyboardMsg(wnd
, p1
, p2
))
624 /* ------- fall through ------- */
627 if (GetParent(wnd
) != NULL
)
628 DfPostMessage(GetParent(wnd
), msg
, p1
, p2
);
632 ClearWindow(wnd
, (DFRECT
*)p1
, ' ');
637 if (TestAttribute(wnd
, HASBORDER
))
638 RepaintBorder(wnd
, (DFRECT
*)p1
);
639 else if (TestAttribute(wnd
, HASTITLEBAR
))
640 DisplayTitle(wnd
, (DFRECT
*)p1
);
647 SetFocusMsg(wnd
, p1
);
649 case DFM_DOUBLE_CLICK
:
650 DoubleClickMsg(wnd
, p1
, p2
);
653 LeftButtonMsg(wnd
, p1
, p2
);
656 if (MouseMovedMsg(wnd
, p1
, p2
))
659 case DFM_BUTTON_RELEASED
:
660 if (WindowMoving
|| WindowSizing
)
663 DfPostMessage(wnd
,MOVE
,dwnd
.rc
.lf
,dwnd
.rc
.tp
);
665 DfPostMessage(wnd
, DFM_SIZE
,dwnd
.rc
.rt
,dwnd
.rc
.bt
);
669 #ifdef INCLUDE_MAXIMIZE
671 if (wnd
->condition
!= ISMAXIMIZED
)
675 #ifdef INCLUDE_MINIMIZE
677 if (wnd
->condition
!= ISMINIMIZED
)
681 #ifdef INCLUDE_RESTORE
683 if (wnd
->condition
!= ISRESTORED
) {
684 #ifdef INCLUDE_MAXIMIZE
685 if (wnd
->oldcondition
== ISMAXIMIZED
)
686 DfSendMessage(wnd
, MAXIMIZE
, 0, 0);
694 MoveMsg(wnd
, p1
, p2
);
697 SizeMsg(wnd
, p1
, p2
);
708 #ifdef INCLUDE_MINIMIZE
709 /* ---- compute lower right icon space in a rectangle ---- */
710 static DFRECT
LowerRight(DFRECT prc
)
713 RectLeft(rc
) = RectRight(prc
) - ICONWIDTH
;
714 RectTop(rc
) = RectBottom(prc
) - ICONHEIGHT
;
715 RectRight(rc
) = RectLeft(rc
)+ICONWIDTH
-1;
716 RectBottom(rc
) = RectTop(rc
)+ICONHEIGHT
-1;
719 /* ----- compute a position for a minimized window icon ---- */
720 static DFRECT
PositionIcon(DFWINDOW wnd
)
722 DFWINDOW pwnd
= GetParent(wnd
);
724 RectLeft(rc
) = DfGetScreenWidth()-ICONWIDTH
;
725 RectTop(rc
) = DfGetScreenHeight()-ICONHEIGHT
;
726 RectRight(rc
) = DfGetScreenWidth()-1;
727 RectBottom(rc
) = DfGetScreenHeight()-1;
729 DFRECT prc
= WindowRect(pwnd
);
730 DFWINDOW cwnd
= FirstWindow(pwnd
);
731 rc
= LowerRight(prc
);
732 /* - search for icon available location - */
733 while (cwnd
!= NULL
) {
734 if (cwnd
->condition
== ISMINIMIZED
) {
736 rc1
= WindowRect(cwnd
);
737 if (RectLeft(rc1
) == RectLeft(rc
) &&
738 RectTop(rc1
) == RectTop(rc
)) {
739 RectLeft(rc
) -= ICONWIDTH
;
740 RectRight(rc
) -= ICONWIDTH
;
741 if (RectLeft(rc
) < RectLeft(prc
)+1) {
743 RectRight(prc
)-ICONWIDTH
;
745 RectLeft(rc
)+ICONWIDTH
-1;
746 RectTop(rc
) -= ICONHEIGHT
;
747 RectBottom(rc
) -= ICONHEIGHT
;
748 if (RectTop(rc
) < RectTop(prc
)+1)
749 return LowerRight(prc
);
754 cwnd
= NextWindow(cwnd
);
760 /* ----- terminate the move or size operation ----- */
761 static void TerminateMoveSize(void)
765 DfSendMessage(&dwnd
, RELEASE_MOUSE
, TRUE
, 0);
766 DfSendMessage(&dwnd
, RELEASE_KEYBOARD
, TRUE
, 0);
767 RestoreBorder(dwnd
.rc
);
768 WindowMoving
= WindowSizing
= FALSE
;
770 /* ---- build a dummy window border for moving or sizing --- */
771 static void dragborder(DFWINDOW wnd
, int x
, int y
)
773 RestoreBorder(dwnd
.rc
);
774 /* ------- build the dummy window -------- */
777 dwnd
.rc
.rt
= dwnd
.rc
.lf
+WindowWidth(wnd
)-1;
778 dwnd
.rc
.bt
= dwnd
.rc
.tp
+WindowHeight(wnd
)-1;
779 dwnd
.ht
= WindowHeight(wnd
);
780 dwnd
.wd
= WindowWidth(wnd
);
781 dwnd
.parent
= GetParent(wnd
);
782 dwnd
.attrib
= VISIBLE
| HASBORDER
| NOCLIP
;
783 InitWindowColors(&dwnd
);
785 RepaintBorder(&dwnd
, NULL
);
787 /* ---- write the dummy window border for sizing ---- */
788 static void sizeborder(DFWINDOW wnd
, int rt
, int bt
)
790 int leftmost
= GetLeft(wnd
)+10;
791 int topmost
= GetTop(wnd
)+3;
792 int bottommost
= DfGetScreenHeight()-1;
793 int rightmost
= DfGetScreenWidth()-1;
794 if (GetParent(wnd
)) {
795 bottommost
= min(bottommost
,
796 GetClientBottom(GetParent(wnd
)));
797 rightmost
= min(rightmost
,
798 GetClientRight(GetParent(wnd
)));
800 rt
= min(rt
, rightmost
);
801 bt
= min(bt
, bottommost
);
802 rt
= max(rt
, leftmost
);
803 bt
= max(bt
, topmost
);
805 if (rt
!= px
|| bt
!= py
)
806 RestoreBorder(dwnd
.rc
);
808 /* ------- change the dummy window -------- */
809 dwnd
.ht
= bt
-dwnd
.rc
.tp
+1;
810 dwnd
.wd
= rt
-dwnd
.rc
.lf
+1;
813 if (rt
!= px
|| bt
!= py
) {
817 RepaintBorder(&dwnd
, NULL
);
820 #ifdef INCLUDE_MULTI_WINDOWS
821 /* ----- adjust a rectangle to include the shadow ----- */
822 static DFRECT
adjShadow(DFWINDOW wnd
)
826 if (TestAttribute(wnd
, SHADOW
)) {
827 if (RectRight(rc
) < DfGetScreenWidth()-1)
829 if (RectBottom(rc
) < DfGetScreenHeight()-1)
834 /* --- repaint a rectangular subsection of a window --- */
835 static void PaintOverLap(DFWINDOW wnd
, DFRECT rc
)
837 if (isVisible(wnd
)) {
838 int isBorder
, isTitle
, isData
;
839 isBorder
= isTitle
= FALSE
;
841 if (TestAttribute(wnd
, HASBORDER
)) {
842 isBorder
= RectLeft(rc
) == 0 &&
843 RectTop(rc
) < WindowHeight(wnd
);
844 isBorder
|= RectLeft(rc
) < WindowWidth(wnd
) &&
845 RectRight(rc
) >= WindowWidth(wnd
)-1 &&
846 RectTop(rc
) < WindowHeight(wnd
);
847 isBorder
|= RectTop(rc
) == 0 &&
848 RectLeft(rc
) < WindowWidth(wnd
);
849 isBorder
|= RectTop(rc
) < WindowHeight(wnd
) &&
850 RectBottom(rc
) >= WindowHeight(wnd
)-1 &&
851 RectLeft(rc
) < WindowWidth(wnd
);
853 else if (TestAttribute(wnd
, HASTITLEBAR
))
854 isTitle
= RectTop(rc
) == 0 &&
856 RectLeft(rc
)<WindowWidth(wnd
)-BorderAdj(wnd
);
858 if (RectLeft(rc
) >= WindowWidth(wnd
)-BorderAdj(wnd
))
860 if (RectTop(rc
) >= WindowHeight(wnd
)-BottomBorderAdj(wnd
))
862 if (TestAttribute(wnd
, HASBORDER
)) {
863 if (RectRight(rc
) == 0)
865 if (RectBottom(rc
) == 0)
868 if (TestAttribute(wnd
, SHADOW
))
869 isBorder
|= RectRight(rc
) == WindowWidth(wnd
) ||
870 RectBottom(rc
) == WindowHeight(wnd
);
872 DfSendMessage(wnd
, PAINT
, (PARAM
) &rc
, TRUE
);
874 DfSendMessage(wnd
, BORDER
, (PARAM
) &rc
, 0);
876 DisplayTitle(wnd
, &rc
);
879 /* ------ paint the part of a window that is overlapped
880 by another window that is being hidden ------- */
881 static void PaintOver(DFWINDOW wnd
)
884 wrc
= adjShadow(HiddenWindow
);
886 rc
= subRectangle(rc
, wrc
);
888 PaintOverLap(wnd
, RelativeWindowRect(wnd
, rc
));
890 /* --- paint the overlapped parts of all children --- */
891 static void PaintOverChildren(DFWINDOW pwnd
)
893 DFWINDOW cwnd
= FirstWindow(pwnd
);
894 while (cwnd
!= NULL
) {
895 if (cwnd
!= HiddenWindow
) {
897 PaintOverChildren(cwnd
);
899 cwnd
= NextWindow(cwnd
);
902 /* -- recursive overlapping paint of parents -- */
903 static void PaintOverParents(DFWINDOW wnd
)
905 DFWINDOW pwnd
= GetParent(wnd
);
907 PaintOverParents(pwnd
);
909 PaintOverChildren(pwnd
);
912 /* - paint the parts of all windows that a window is over - */
913 static void PaintOverLappers(DFWINDOW wnd
)
916 PaintOverParents(wnd
);
918 /* --- paint those parts of a window that are overlapped --- */
919 static void PaintUnderLappers(DFWINDOW wnd
)
921 DFWINDOW hwnd
= NextWindow(wnd
);
922 while (hwnd
!= NULL
) {
923 /* ------- test only at document window level ------ */
924 DFWINDOW pwnd
= GetParent(hwnd
);
925 /* if (pwnd == NULL || GetClass(pwnd) == APPLICATION) */ {
926 /* ---- don't bother testing self ----- */
927 if (isVisible(hwnd
) && hwnd
!= wnd
) {
928 /* --- see if other window is descendent --- */
929 while (pwnd
!= NULL
) {
932 pwnd
= GetParent(pwnd
);
934 /* ----- don't test descendent overlaps ----- */
936 /* -- see if other window is ancestor --- */
937 pwnd
= GetParent(wnd
);
938 while (pwnd
!= NULL
) {
941 pwnd
= GetParent(pwnd
);
943 /* --- don't test ancestor overlaps --- */
945 HiddenWindow
= GetAncestor(hwnd
);
946 ClearVisible(HiddenWindow
);
948 SetVisible(HiddenWindow
);
953 hwnd
= NextWindow(hwnd
);
955 /* --------- repaint all children of this window
956 the same way ----------- */
957 hwnd
= FirstWindow(wnd
);
958 while (hwnd
!= NULL
) {
959 PaintUnderLappers(hwnd
);
960 hwnd
= NextWindow(hwnd
);
963 #endif /* #ifdef INCLUDE_MULTI_WINDOWS */
965 /* --- save video area to be used by dummy window border --- */
966 static void SaveBorder(DFRECT rc
)
968 Bht
= RectBottom(rc
) - RectTop(rc
) + 1;
969 Bwd
= RectRight(rc
) - RectLeft(rc
) + 1;
970 Bsave
= DFrealloc(Bsave
, Bht
* Bwd
* sizeof(CHAR_INFO
));
974 /* ---- restore video area used by dummy window border ---- */
975 static void RestoreBorder(DFRECT rc
)
979 StoreVideo(rc
, Bsave
);
984 /* ----- test if screen coordinates are in a window ---- */
985 static BOOL
InsideWindow(DFWINDOW wnd
, int x
, int y
)
988 rc
= WindowRect(wnd
);
989 if (!TestAttribute(wnd
, NOCLIP
))
991 DFWINDOW pwnd
= GetParent(wnd
);
994 rc
= subRectangle(rc
, ClientRect(pwnd
));
995 pwnd
= GetParent(pwnd
);
998 return InsideRect(x
, y
, rc
);
1001 BOOL
isDerivedFrom(DFWINDOW wnd
, DFCLASS
class)
1003 DFCLASS tclass
= GetClass(wnd
);
1004 while (tclass
!= -1) {
1005 if (tclass
== class)
1007 tclass
= (classdefs
[tclass
].base
);
1012 /* -- find the oldest document window ancestor of a window -- */
1013 DFWINDOW
GetAncestor(DFWINDOW wnd
)
1016 while (GetParent(wnd
) != NULL
) {
1017 if (GetClass(GetParent(wnd
)) == APPLICATION
)
1019 wnd
= GetParent(wnd
);
1025 BOOL
isVisible(DFWINDOW wnd
)
1027 while (wnd
!= NULL
) {
1030 wnd
= GetParent(wnd
);
1035 /* -- adjust a window's rectangle to clip it to its parent - */
1036 static DFRECT
ClipRect(DFWINDOW wnd
)
1039 rc
= WindowRect(wnd
);
1040 if (TestAttribute(wnd
, SHADOW
)) {
1044 return ClipRectangle(wnd
, rc
);
1047 /* -- get the video memory that is to be used by a window -- */
1048 static void GetVideoBuffer(DFWINDOW wnd
)
1055 ht
= RectBottom(rc
) - RectTop(rc
) + 1;
1056 wd
= RectRight(rc
) - RectLeft(rc
) + 1;
1057 wnd
->videosave
= DFrealloc(wnd
->videosave
, (ht
* wd
* sizeof(CHAR_INFO
)));
1058 GetVideo(rc
, wnd
->videosave
);
1061 /* -- put the video memory that is used by a window -- */
1062 static void PutVideoBuffer(DFWINDOW wnd
)
1064 if (wnd
->videosave
!= NULL
)
1068 StoreVideo(rc
, wnd
->videosave
);
1069 free(wnd
->videosave
);
1070 wnd
->videosave
= NULL
;
1074 /* ------- return TRUE if awnd is an ancestor of wnd ------- */
1075 BOOL
isAncestor(DFWINDOW wnd
, DFWINDOW awnd
)
1077 while (wnd
!= NULL
) {
1080 wnd
= GetParent(wnd
);