1 /* ------------- normal.c ------------ */
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 DfWindow dwnd
= {DF_DUMMY
, NULL
, DfNormalProc
,
24 {{-1},{-1},{-1},{-1}}};
25 static PCHAR_INFO Bsave
;
29 /* -------- array of class definitions -------- */
30 DFCLASSDEFS DfClassDefs
[] = {
32 #define DfClassDef(c,b,p,a) {b,p,a},
35 DFWINDOW HiddenWindow
;
37 /* --------- DFM_CREATE_WINDOW Message ---------- */
38 static void CreateWindowMsg(DFWINDOW wnd
)
41 // DfClearAttribute(wnd, DF_VSCROLLBAR | DF_HSCROLLBAR);
42 if (DfTestAttribute(wnd
, DF_SAVESELF
) && DfIsVisible(wnd
))
46 /* --------- DFM_SHOW_WINDOW Message ---------- */
47 static void ShowWindowMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
49 if (DfGetParent(wnd
) == NULL
|| DfIsVisible(DfGetParent(wnd
)))
53 if (DfTestAttribute(wnd
, DF_SAVESELF
) && wnd
->videosave
== NULL
)
56 DfSendMessage(wnd
, DFM_PAINT
, 0, TRUE
);
57 DfSendMessage(wnd
, DFM_BORDER
, 0, 0);
58 /* --- show the children of this window --- */
59 cwnd
= DfFirstWindow(wnd
);
62 if (cwnd
->condition
!= DF_ISCLOSING
)
63 DfSendMessage(cwnd
, DFM_SHOW_WINDOW
, p1
, p2
);
64 cwnd
= DfNextWindow(cwnd
);
69 /* --------- HIDE_WINDOW Message ---------- */
70 static void HideWindowMsg(DFWINDOW wnd
)
75 /* --- paint what this window covered --- */
76 if (DfTestAttribute(wnd
, DF_SAVESELF
))
78 #ifdef INCLUDE_MULTI_WINDOWS
80 PaintOverLappers(wnd
);
85 /* --------- DFM_KEYBOARD Message ---------- */
86 static BOOL
KeyboardMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
88 if (DfWindowMoving
|| DfWindowSizing
) {
89 /* -- move or size a window with keyboard -- */
91 x
=DfWindowMoving
?DfGetLeft(&dwnd
):DfGetRight(&dwnd
);
92 y
=DfWindowMoving
?DfGetTop(&dwnd
):DfGetBottom(&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
, DF_ID_HELP
, 0);
130 if ((int)p2
& DF_ALTKEY
)
131 if (DfTestAttribute(wnd
, DF_HASTITLEBAR
))
132 if (DfTestAttribute(wnd
, DF_CONTROLBOX
))
133 DfBuildSystemMenu(wnd
);
137 if (DfTestAttribute(wnd
, DF_CONTROLBOX
))
139 DfSendMessage(wnd
, DFM_CLOSE_WINDOW
, 0, 0);
140 DfSkipApplicationControls();
152 /* --------- COMMAND Message ---------- */
153 static void CommandMsg(DFWINDOW wnd
, DF_PARAM p1
)
157 DfDisplayHelp(wnd
,DfClassNames
[DfGetClass(wnd
)]);
159 #ifdef INCLUDE_RESTORE
160 case DF_ID_SYSRESTORE
:
161 DfSendMessage(wnd
, DFM_RESTORE
, 0, 0);
165 DfSendMessage(wnd
, DFM_CAPTURE_MOUSE
, TRUE
,
167 DfSendMessage(wnd
, DFM_CAPTURE_KEYBOARD
, TRUE
,
169 DfWindowMoving
= TRUE
;
170 dragborder(wnd
, DfGetLeft(wnd
), DfGetTop(wnd
));
173 DfSendMessage(wnd
, DFM_CAPTURE_MOUSE
, TRUE
,
175 DfSendMessage(wnd
, DFM_CAPTURE_KEYBOARD
, TRUE
,
177 DfWindowSizing
= TRUE
;
178 dragborder(wnd
, DfGetLeft(wnd
), DfGetTop(wnd
));
180 #ifdef INCLUDE_MINIMIZE
181 case DF_ID_SYSMINIMIZE
:
182 DfSendMessage(wnd
, DFM_MINIMIZE
, 0, 0);
185 #ifdef INCLUDE_MAXIMIZE
186 case DF_ID_SYSMAXIMIZE
:
187 DfSendMessage(wnd
, DFM_MAXIMIZE
, 0, 0);
191 DfSendMessage(wnd
, DFM_CLOSE_WINDOW
, 0, 0);
192 DfSkipApplicationControls();
199 /* --------- DFM_SETFOCUS Message ---------- */
200 static void SetFocusMsg(DFWINDOW wnd
, DF_PARAM p1
)
202 DFRECT rc
= {0,0,0,0};
204 if (p1
&& wnd
!= NULL
&& DfInFocus
!= wnd
)
206 DFWINDOW
this, thispar
;
207 DFWINDOW that
= NULL
, thatpar
= NULL
;
209 DFWINDOW cwnd
= wnd
, fwnd
= DfGetParent(wnd
);
210 /* ---- post focus in ancestors ---- */
213 fwnd
->childfocus
= cwnd
;
215 fwnd
= DfGetParent(fwnd
);
217 /* ---- de-post focus in self and children ---- */
221 cwnd
= fwnd
->childfocus
;
222 fwnd
->childfocus
= NULL
;
227 that
= thatpar
= DfInFocus
;
229 /* ---- find common ancestor of prev focus and this window --- */
230 while (thatpar
!= NULL
)
233 while (thispar
!= NULL
)
235 if (this == DfCaptureMouse
|| this == DfCaptureKeyboard
)
237 /* ---- don't repaint if this window has capture ---- */
238 that
= thatpar
= NULL
;
241 if (thispar
== thatpar
)
243 /* ---- don't repaint if DF_SAVESELF window had focus ---- */
244 if (this != that
&& DfTestAttribute(that
, DF_SAVESELF
))
245 that
= thatpar
= NULL
;
249 thispar
= DfGetParent(thispar
);
254 thatpar
= DfGetParent(thatpar
);
256 if (DfInFocus
!= NULL
)
257 DfSendMessage(DfInFocus
, DFM_SETFOCUS
, FALSE
, 0);
259 if (that
!= NULL
&& DfIsVisible(wnd
))
261 rc
= DfSubRectangle(DfWindowRect(that
), DfWindowRect(this));
262 if (!DfValidRect(rc
))
264 if (DfApplicationWindow
!= NULL
)
266 DFWINDOW fwnd
= DfFirstWindow(DfApplicationWindow
);
269 if (!DfIsAncestor(wnd
, fwnd
))
271 rc
= DfSubRectangle(DfWindowRect(wnd
),DfWindowRect(fwnd
));
275 fwnd
= DfNextWindow(fwnd
);
280 if (that
!= NULL
&& !DfValidRect(rc
) && DfIsVisible(wnd
))
282 DfSendMessage(wnd
, DFM_BORDER
, 0, 0);
287 DfSendMessage(this, DFM_SHOW_WINDOW
, 0, 0);
289 else if (!p1
&& DfInFocus
== wnd
)
293 DfSendMessage(wnd
, DFM_BORDER
, 0, 0);
297 /* --------- DOUBLE_CLICK Message ---------- */
298 static void DoubleClickMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
300 int mx
= (int) p1
- DfGetLeft(wnd
);
301 int my
= (int) p2
- DfGetTop(wnd
);
302 if (!DfWindowSizing
&& !DfWindowMoving
) {
303 if (DfHitControlBox(wnd
, mx
, my
)) {
304 DfPostMessage(wnd
, DFM_CLOSE_WINDOW
, 0, 0);
305 DfSkipApplicationControls();
310 /* --------- DFM_LEFT_BUTTON Message ---------- */
311 static void LeftButtonMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
313 int mx
= (int) p1
- DfGetLeft(wnd
);
314 int my
= (int) p2
- DfGetTop(wnd
);
315 if (DfWindowSizing
|| DfWindowMoving
)
317 if (DfHitControlBox(wnd
, mx
, my
)) {
318 DfBuildSystemMenu(wnd
);
321 if (my
== 0 && mx
> -1 && mx
< DfWindowWidth(wnd
)) {
322 /* ---------- hit the top border -------- */
323 if (DfTestAttribute(wnd
, DF_MINMAXBOX
) &&
324 DfTestAttribute(wnd
, DF_HASTITLEBAR
)) {
325 if (mx
== DfWindowWidth(wnd
)-2) {
326 if (wnd
->condition
!= DF_SRESTORED
)
327 /* --- hit the restore box --- */
328 DfSendMessage(wnd
, DFM_RESTORE
, 0, 0);
329 #ifdef INCLUDE_MAXIMIZE
331 /* --- hit the maximize box --- */
332 DfSendMessage(wnd
, DFM_MAXIMIZE
, 0, 0);
336 #ifdef INCLUDE_MINIMIZE
337 if (mx
== DfWindowWidth(wnd
)-3) {
338 /* --- hit the minimize box --- */
339 if (wnd
->condition
!= DF_ISMINIMIZED
)
340 DfSendMessage(wnd
, DFM_MINIMIZE
, 0, 0);
345 #ifdef INCLUDE_MAXIMIZE
346 if (wnd
->condition
== DF_ISMAXIMIZED
)
349 if (DfTestAttribute(wnd
, DF_MOVEABLE
)) {
350 DfWindowMoving
= TRUE
;
354 DfSendMessage(wnd
, DFM_CAPTURE_MOUSE
, TRUE
,
356 dragborder(wnd
, DfGetLeft(wnd
), DfGetTop(wnd
));
360 if (mx
== DfWindowWidth(wnd
)-1 &&
361 my
== DfWindowHeight(wnd
)-1) {
362 /* ------- hit the resize corner ------- */
363 #ifdef INCLUDE_MINIMIZE
364 if (wnd
->condition
== DF_ISMINIMIZED
)
367 if (!DfTestAttribute(wnd
, DF_SIZEABLE
))
369 #ifdef INCLUDE_MAXIMIZE
370 if (wnd
->condition
== DF_ISMAXIMIZED
) {
371 if (DfGetParent(wnd
) == NULL
)
373 if (DfTestAttribute(DfGetParent(wnd
),DF_HASBORDER
))
375 /* ----- resizing a maximized window over a
376 borderless parent ----- */
377 wnd
= DfGetParent(wnd
);
380 DfWindowSizing
= TRUE
;
381 DfSendMessage(wnd
, DFM_CAPTURE_MOUSE
,
382 TRUE
, (DF_PARAM
) &dwnd
);
383 dragborder(wnd
, DfGetLeft(wnd
), DfGetTop(wnd
));
387 /* --------- MOUSE_MOVED Message ---------- */
388 static BOOL
MouseMovedMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
390 if (DfWindowMoving
) {
391 int leftmost
= 0, topmost
= 0,
392 bottommost
= DfGetScreenHeight()-2,
393 rightmost
= DfGetScreenWidth()-2;
394 int x
= (int) p1
- diff
;
396 if (DfGetParent(wnd
) != NULL
&&
397 !DfTestAttribute(wnd
, DF_NOCLIP
)) {
398 DFWINDOW wnd1
= DfGetParent(wnd
);
399 topmost
= DfGetClientTop(wnd1
);
400 leftmost
= DfGetClientLeft(wnd1
);
401 bottommost
= DfGetClientBottom(wnd1
);
402 rightmost
= DfGetClientRight(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
);
419 if (DfWindowSizing
) {
420 sizeborder(wnd
, (int) p1
, (int) p2
);
426 #ifdef INCLUDE_MAXIMIZE
427 /* --------- DFM_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;
435 if (DfGetParent(wnd
))
436 rc
= DfClientRect(DfGetParent(wnd
));
437 wnd
->oldcondition
= wnd
->condition
;
438 wnd
->condition
= DF_ISMAXIMIZED
;
439 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
440 DfSendMessage(wnd
, DFM_MOVE
,
441 DfRectLeft(rc
), DfRectTop(rc
));
442 DfSendMessage(wnd
, DFM_DFM_SIZE
,
443 DfRectRight(rc
), DfRectBottom(rc
));
444 if (wnd
->restored_attrib
== 0)
445 wnd
->restored_attrib
= wnd
->attrib
;
446 DfClearAttribute(wnd
, DF_SHADOW
);
447 DfSendMessage(wnd
, DFM_SHOW_WINDOW
, 0, 0);
448 wnd
->RestoredRC
= holdrc
;
452 #ifdef INCLUDE_MINIMIZE
453 /* --------- DFM_MINIMIZE Message ---------- */
454 static void MinimizeMsg(DFWINDOW wnd
)
459 holdrc
= wnd
->RestoredRC
;
460 rc
= PositionIcon(wnd
);
461 wnd
->oldcondition
= wnd
->condition
;
462 wnd
->condition
= DF_ISMINIMIZED
;
463 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
464 DfSendMessage(wnd
, DFM_MOVE
,
465 DfRectLeft(rc
), DfRectTop(rc
));
466 DfSendMessage(wnd
, DFM_DFM_SIZE
,
467 DfRectRight(rc
), DfRectBottom(rc
));
468 if (wnd
== DfInFocus
)
470 if (wnd
->restored_attrib
== 0)
471 wnd
->restored_attrib
= wnd
->attrib
;
472 DfClearAttribute(wnd
,
473 DF_SHADOW
| DF_SIZEABLE
| DF_HASMENUBAR
|
474 DF_VSCROLLBAR
| DF_HSCROLLBAR
);
475 DfSendMessage(wnd
, DFM_SHOW_WINDOW
, 0, 0);
476 wnd
->RestoredRC
= holdrc
;
480 #ifdef INCLUDE_RESTORE
481 /* --------- DFM_RESTORE Message ---------- */
482 static void RestoreMsg(DFWINDOW wnd
)
485 holdrc
= wnd
->RestoredRC
;
486 wnd
->oldcondition
= wnd
->condition
;
487 wnd
->condition
= DF_SRESTORED
;
488 DfSendMessage(wnd
, DFM_HIDE_WINDOW
, 0, 0);
489 wnd
->attrib
= wnd
->restored_attrib
;
490 wnd
->restored_attrib
= 0;
491 DfSendMessage(wnd
, DFM_MOVE
, wnd
->RestoredRC
.lf
,
493 wnd
->RestoredRC
= holdrc
;
494 DfSendMessage(wnd
, DFM_DFM_SIZE
, wnd
->RestoredRC
.rt
,
496 if (wnd
!= DfInFocus
)
497 DfSendMessage(wnd
, DFM_SETFOCUS
, TRUE
, 0);
499 DfSendMessage(wnd
, DFM_SHOW_WINDOW
, 0, 0);
503 /* --------- DFM_MOVE Message ---------- */
504 static void MoveMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
507 BOOL wasVisible
= DfIsVisible(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
= DfGetLeft(wnd
)+DfWindowWidth(wnd
)-1;
518 wnd
->rc
.bt
= DfGetTop(wnd
)+DfWindowHeight(wnd
)-1;
519 if (wnd
->condition
== DF_SRESTORED
)
520 wnd
->RestoredRC
= wnd
->rc
;
522 cwnd
= DfFirstWindow(wnd
);
523 while (cwnd
!= NULL
) {
524 DfSendMessage(cwnd
, DFM_MOVE
, cwnd
->rc
.lf
+xdif
, cwnd
->rc
.tp
+ydif
);
525 cwnd
= DfNextWindow(cwnd
);
528 DfSendMessage(wnd
, DFM_SHOW_WINDOW
, 0, 0);
531 /* --------- SIZE Message ---------- */
532 static void SizeMsg(DFWINDOW wnd
, DF_PARAM p1
, DF_PARAM p2
)
534 BOOL wasVisible
= DfIsVisible(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
= DfGetBottom(wnd
)-DfGetTop(wnd
)+1;
547 wnd
->wd
= DfGetRight(wnd
)-DfGetLeft(wnd
)+1;
549 if (wnd
->condition
== DF_SRESTORED
)
550 wnd
->RestoredRC
= DfWindowRect(wnd
);
552 #ifdef INCLUDE_MAXIMIZE
553 rc
= DfClientRect(wnd
);
555 cwnd
= DfFirstWindow(wnd
);
556 while (cwnd
!= NULL
) {
557 if (cwnd
->condition
== DF_ISMAXIMIZED
)
558 DfSendMessage(cwnd
, DFM_DFM_SIZE
, DfRectRight(rc
), DfRectBottom(rc
));
559 cwnd
= DfNextWindow(cwnd
);
564 DfSendMessage(wnd
, DFM_SHOW_WINDOW
, 0, 0);
567 /* --------- DFM_CLOSE_WINDOW Message ---------- */
568 static void CloseWindowMsg(DFWINDOW wnd
)
571 wnd
->condition
= DF_ISCLOSING
;
572 if (wnd
->PrevMouse
!= NULL
)
573 DfSendMessage(wnd
, DFM_RELEASE_MOUSE
, 0, 0);
574 if (wnd
->PrevKeyboard
!= NULL
)
575 DfSendMessage(wnd
, DFM_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
= DfLastWindow(wnd
);
581 while (cwnd
!= NULL
) {
582 if (DfInFocus
== cwnd
)
584 DfSendMessage(cwnd
,DFM_CLOSE_WINDOW
,0,0);
585 cwnd
= DfLastWindow(wnd
);
588 /* --- change focus if this window had it -- */
589 if (wnd
== DfInFocus
)
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 -- */
598 if (wnd
== DfInFocus
)
603 /* ---- Window-processing module for DF_NORMAL window class ---- */
604 int DfNormalProc(DFWINDOW wnd
, DFMESSAGE msg
, DF_PARAM p1
, DF_PARAM p2
)
607 case DFM_CREATE_WINDOW
:
608 CreateWindowMsg(wnd
);
610 case DFM_SHOW_WINDOW
:
611 ShowWindowMsg(wnd
, p1
, p2
);
613 case DFM_HIDE_WINDOW
:
616 case DFM_DISPLAY_HELP
:
617 DfDisplayHelp(wnd
, (char *)p1
);
619 case DFM_INSIDE_WINDOW
:
620 return InsideWindow(wnd
, (int) p1
, (int) p2
);
622 if (KeyboardMsg(wnd
, p1
, p2
))
624 /* ------- fall through ------- */
626 case DFM_SHIFT_CHANGED
:
627 if (DfGetParent(wnd
) != NULL
)
628 DfPostMessage(DfGetParent(wnd
), msg
, p1
, p2
);
631 if (DfIsVisible(wnd
))
632 DfClearWindow(wnd
, (DFRECT
*)p1
, ' ');
635 if (DfIsVisible(wnd
))
637 if (DfTestAttribute(wnd
, DF_HASBORDER
))
638 DfRepaintBorder(wnd
, (DFRECT
*)p1
);
639 else if (DfTestAttribute(wnd
, DF_HASTITLEBAR
))
640 DfDisplayTitle(wnd
, (DFRECT
*)p1
);
647 SetFocusMsg(wnd
, p1
);
649 case DFM_DOUBLE_CLICK
:
650 DoubleClickMsg(wnd
, p1
, p2
);
652 case DFM_LEFT_BUTTON
:
653 LeftButtonMsg(wnd
, p1
, p2
);
656 if (MouseMovedMsg(wnd
, p1
, p2
))
659 case DFM_BUTTON_RELEASED
:
660 if (DfWindowMoving
|| DfWindowSizing
)
663 DfPostMessage(wnd
,DFM_MOVE
,dwnd
.rc
.lf
,dwnd
.rc
.tp
);
665 DfPostMessage(wnd
, DFM_DFM_SIZE
,dwnd
.rc
.rt
,dwnd
.rc
.bt
);
669 #ifdef INCLUDE_MAXIMIZE
671 if (wnd
->condition
!= DF_ISMAXIMIZED
)
675 #ifdef INCLUDE_MINIMIZE
677 if (wnd
->condition
!= DF_ISMINIMIZED
)
681 #ifdef INCLUDE_RESTORE
683 if (wnd
->condition
!= DF_SRESTORED
) {
684 #ifdef INCLUDE_MAXIMIZE
685 if (wnd
->oldcondition
== DF_ISMAXIMIZED
)
686 DfSendMessage(wnd
, DFM_MAXIMIZE
, 0, 0);
694 MoveMsg(wnd
, p1
, p2
);
697 SizeMsg(wnd
, p1
, p2
);
700 case DFM_CLOSE_WINDOW
:
708 #ifdef INCLUDE_MINIMIZE
709 /* ---- compute lower right icon space in a rectangle ---- */
710 static DFRECT
LowerRight(DFRECT prc
)
713 DfRectLeft(rc
) = DfRectRight(prc
) - DF_ICONWIDTH
;
714 DfRectTop(rc
) = DfRectBottom(prc
) - DF_ICONHEIGHT
;
715 DfRectRight(rc
) = DfRectLeft(rc
)+DF_ICONWIDTH
-1;
716 DfRectBottom(rc
) = DfRectTop(rc
)+DF_ICONHEIGHT
-1;
719 /* ----- compute a position for a minimized window icon ---- */
720 static DFRECT
PositionIcon(DFWINDOW wnd
)
722 DFWINDOW pwnd
= DfGetParent(wnd
);
724 DfRectLeft(rc
) = DfGetScreenWidth()-DF_ICONWIDTH
;
725 DfRectTop(rc
) = DfGetScreenHeight()-DF_ICONHEIGHT
;
726 DfRectRight(rc
) = DfGetScreenWidth()-1;
727 DfRectBottom(rc
) = DfGetScreenHeight()-1;
729 DFRECT prc
= DfWindowRect(pwnd
);
730 DFWINDOW cwnd
= DfFirstWindow(pwnd
);
731 rc
= LowerRight(prc
);
732 /* - search for icon available location - */
733 while (cwnd
!= NULL
) {
734 if (cwnd
->condition
== DF_ISMINIMIZED
) {
736 rc1
= DfWindowRect(cwnd
);
737 if (DfRectLeft(rc1
) == DfRectLeft(rc
) &&
738 DfRectTop(rc1
) == DfRectTop(rc
)) {
739 DfRectLeft(rc
) -= DF_ICONWIDTH
;
740 DfRectRight(rc
) -= DF_ICONWIDTH
;
741 if (DfRectLeft(rc
) < DfRectLeft(prc
)+1) {
743 DfRectRight(prc
)-DF_ICONWIDTH
;
745 DfRectLeft(rc
)+DF_ICONWIDTH
-1;
746 DfRectTop(rc
) -= DF_ICONHEIGHT
;
747 DfRectBottom(rc
) -= DF_ICONHEIGHT
;
748 if (DfRectTop(rc
) < DfRectTop(prc
)+1)
749 return LowerRight(prc
);
754 cwnd
= DfNextWindow(cwnd
);
760 /* ----- terminate the move or size operation ----- */
761 static void TerminateMoveSize(void)
765 DfSendMessage(&dwnd
, DFM_RELEASE_MOUSE
, TRUE
, 0);
766 DfSendMessage(&dwnd
, DFM_RELEASE_KEYBOARD
, TRUE
, 0);
767 RestoreBorder(dwnd
.rc
);
768 DfWindowMoving
= DfWindowSizing
= 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
+DfWindowWidth(wnd
)-1;
778 dwnd
.rc
.bt
= dwnd
.rc
.tp
+DfWindowHeight(wnd
)-1;
779 dwnd
.ht
= DfWindowHeight(wnd
);
780 dwnd
.wd
= DfWindowWidth(wnd
);
781 dwnd
.parent
= DfGetParent(wnd
);
782 dwnd
.attrib
= DF_VISIBLE
| DF_HASBORDER
| DF_NOCLIP
;
783 DfInitWindowColors(&dwnd
);
785 DfRepaintBorder(&dwnd
, NULL
);
787 /* ---- write the dummy window border for sizing ---- */
788 static void sizeborder(DFWINDOW wnd
, int rt
, int bt
)
790 int leftmost
= DfGetLeft(wnd
)+10;
791 int topmost
= DfGetTop(wnd
)+3;
792 int bottommost
= DfGetScreenHeight()-1;
793 int rightmost
= DfGetScreenWidth()-1;
794 if (DfGetParent(wnd
)) {
795 bottommost
= min(bottommost
,
796 DfGetClientBottom(DfGetParent(wnd
)));
797 rightmost
= min(rightmost
,
798 DfGetClientRight(DfGetParent(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 DfRepaintBorder(&dwnd
, NULL
);
820 #ifdef INCLUDE_MULTI_WINDOWS
821 /* ----- adjust a rectangle to include the shadow ----- */
822 static DFRECT
adjShadow(DFWINDOW wnd
)
826 if (DfTestAttribute(wnd
, DF_SHADOW
)) {
827 if (DfRectRight(rc
) < DfGetScreenWidth()-1)
829 if (DfRectBottom(rc
) < DfGetScreenHeight()-1)
834 /* --- repaint a rectangular subsection of a window --- */
835 static void PaintOverLap(DFWINDOW wnd
, DFRECT rc
)
837 if (DfIsVisible(wnd
)) {
838 int isBorder
, isTitle
, isData
;
839 isBorder
= isTitle
= FALSE
;
841 if (DfTestAttribute(wnd
, DF_HASBORDER
)) {
842 isBorder
= DfRectLeft(rc
) == 0 &&
843 DfRectTop(rc
) < DfWindowHeight(wnd
);
844 isBorder
|= DfRectLeft(rc
) < DfWindowWidth(wnd
) &&
845 DfRectRight(rc
) >= DfWindowWidth(wnd
)-1 &&
846 DfRectTop(rc
) < DfWindowHeight(wnd
);
847 isBorder
|= DfRectTop(rc
) == 0 &&
848 DfRectLeft(rc
) < DfWindowWidth(wnd
);
849 isBorder
|= DfRectTop(rc
) < DfWindowHeight(wnd
) &&
850 DfRectBottom(rc
) >= DfWindowHeight(wnd
)-1 &&
851 DfRectLeft(rc
) < DfWindowWidth(wnd
);
853 else if (DfTestAttribute(wnd
, DF_HASTITLEBAR
))
854 isTitle
= DfRectTop(rc
) == 0 &&
855 DfRectRight(rc
) > 0 &&
856 DfRectLeft(rc
)<DfWindowWidth(wnd
)-DfBorderAdj(wnd
);
858 if (DfRectLeft(rc
) >= DfWindowWidth(wnd
)-DfBorderAdj(wnd
))
860 if (DfRectTop(rc
) >= DfWindowHeight(wnd
)-DfBottomBorderAdj(wnd
))
862 if (DfTestAttribute(wnd
, DF_HASBORDER
)) {
863 if (DfRectRight(rc
) == 0)
865 if (DfRectBottom(rc
) == 0)
868 if (DfTestAttribute(wnd
, DF_SHADOW
))
869 isBorder
|= DfRectRight(rc
) == DfWindowWidth(wnd
) ||
870 DfRectBottom(rc
) == DfWindowHeight(wnd
);
872 DfSendMessage(wnd
, DFM_PAINT
, (DF_PARAM
) &rc
, TRUE
);
874 DfSendMessage(wnd
, DFM_BORDER
, (DF_PARAM
) &rc
, 0);
876 DfDisplayTitle(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
= DfSubRectangle(rc
, wrc
);
888 PaintOverLap(wnd
, DfRelativeWindowRect(wnd
, rc
));
890 /* --- paint the overlapped parts of all children --- */
891 static void PaintOverChildren(DFWINDOW pwnd
)
893 DFWINDOW cwnd
= DfFirstWindow(pwnd
);
894 while (cwnd
!= NULL
) {
895 if (cwnd
!= HiddenWindow
) {
897 PaintOverChildren(cwnd
);
899 cwnd
= DfNextWindow(cwnd
);
902 /* -- recursive overlapping paint of parents -- */
903 static void PaintOverParents(DFWINDOW wnd
)
905 DFWINDOW pwnd
= DfGetParent(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
);
920 /* --- paint those parts of a window that are overlapped --- */
921 static void PaintUnderLappers(DFWINDOW wnd
)
923 DFWINDOW hwnd
= DfNextWindow(wnd
);
924 while (hwnd
!= NULL
) {
925 /* ------- test only at document window level ------ */
926 DFWINDOW pwnd
= DfGetParent(hwnd
);
927 /* if (pwnd == NULL || DfGetClass(pwnd) == DF_APPLICATION) */ {
928 /* ---- don't bother testing self ----- */
929 if (DfIsVisible(hwnd
) && hwnd
!= wnd
) {
930 /* --- see if other window is descendent --- */
931 while (pwnd
!= NULL
) {
934 pwnd
= DfGetParent(pwnd
);
936 /* ----- don't test descendent overlaps ----- */
938 /* -- see if other window is ancestor --- */
939 pwnd
= DfGetParent(wnd
);
940 while (pwnd
!= NULL
) {
943 pwnd
= DfGetParent(pwnd
);
945 /* --- don't test ancestor overlaps --- */
947 HiddenWindow
= DfGetAncestor(hwnd
);
948 DfClearVisible(HiddenWindow
);
950 DfSetVisible(HiddenWindow
);
955 hwnd
= DfNextWindow(hwnd
);
957 /* --------- repaint all children of this window
958 the same way ----------- */
959 hwnd
= DfFirstWindow(wnd
);
960 while (hwnd
!= NULL
) {
961 PaintUnderLappers(hwnd
);
962 hwnd
= DfNextWindow(hwnd
);
966 #endif /* #ifdef INCLUDE_MULTI_WINDOWS */
968 /* --- save video area to be used by dummy window border --- */
969 static void SaveBorder(DFRECT rc
)
971 Bht
= DfRectBottom(rc
) - DfRectTop(rc
) + 1;
972 Bwd
= DfRectRight(rc
) - DfRectLeft(rc
) + 1;
973 Bsave
= DfRealloc(Bsave
, Bht
* Bwd
* sizeof(CHAR_INFO
));
975 DfGetVideo(rc
,Bsave
);
977 /* ---- restore video area used by dummy window border ---- */
978 static void RestoreBorder(DFRECT rc
)
982 DfStoreVideo(rc
, Bsave
);
987 /* ----- test if screen coordinates are in a window ---- */
988 static BOOL
InsideWindow(DFWINDOW wnd
, int x
, int y
)
991 rc
= DfWindowRect(wnd
);
992 if (!DfTestAttribute(wnd
, DF_NOCLIP
))
994 DFWINDOW pwnd
= DfGetParent(wnd
);
997 rc
= DfSubRectangle(rc
, DfClientRect(pwnd
));
998 pwnd
= DfGetParent(pwnd
);
1001 return DfInsideRect(x
, y
, rc
);
1004 BOOL
DfIsDerivedFrom(DFWINDOW wnd
, DFCLASS
class)
1006 DFCLASS tclass
= DfGetClass(wnd
);
1007 while (tclass
!= -1) {
1008 if (tclass
== class)
1010 tclass
= (DfClassDefs
[tclass
].base
);
1015 /* -- find the oldest document window ancestor of a window -- */
1016 DFWINDOW
DfGetAncestor(DFWINDOW wnd
)
1019 while (DfGetParent(wnd
) != NULL
) {
1020 if (DfGetClass(DfGetParent(wnd
)) == DF_APPLICATION
)
1022 wnd
= DfGetParent(wnd
);
1028 BOOL
DfIsVisible(DFWINDOW wnd
)
1030 while (wnd
!= NULL
) {
1033 wnd
= DfGetParent(wnd
);
1038 /* -- adjust a window's rectangle to clip it to its parent - */
1039 static DFRECT
ClipRect(DFWINDOW wnd
)
1042 rc
= DfWindowRect(wnd
);
1043 if (DfTestAttribute(wnd
, DF_SHADOW
)) {
1047 return DfClipRectangle(wnd
, rc
);
1050 /* -- get the video memory that is to be used by a window -- */
1051 static void GetVideoBuffer(DFWINDOW wnd
)
1058 ht
= DfRectBottom(rc
) - DfRectTop(rc
) + 1;
1059 wd
= DfRectRight(rc
) - DfRectLeft(rc
) + 1;
1060 wnd
->videosave
= DfRealloc(wnd
->videosave
, (ht
* wd
* sizeof(CHAR_INFO
)));
1061 DfGetVideo(rc
, wnd
->videosave
);
1064 /* -- put the video memory that is used by a window -- */
1065 static void PutVideoBuffer(DFWINDOW wnd
)
1067 if (wnd
->videosave
!= NULL
)
1071 DfStoreVideo(rc
, wnd
->videosave
);
1072 free(wnd
->videosave
);
1073 wnd
->videosave
= NULL
;
1077 /* ------- return TRUE if awnd is an ancestor of wnd ------- */
1078 BOOL
DfIsAncestor(DFWINDOW wnd
, DFWINDOW awnd
)
1080 while (wnd
!= NULL
) {
1083 wnd
= DfGetParent(wnd
);