Remove Wine-ism
[reactos.git] / rosapps / dflat32 / normal.c
1 /* ------------- normal.c ------------ */
2
3 #include "dflat.h"
4
5 #ifdef INCLUDE_MULTI_WINDOWS
6 static void PaintOverLappers(DFWINDOW wnd);
7 static void PaintUnderLappers(DFWINDOW wnd);
8 #endif
9
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);
18 #endif
19 static void dragborder(DFWINDOW, int, int);
20 static void sizeborder(DFWINDOW, int, int);
21 static int px = -1, py = -1;
22 static int diff;
23 static struct DfWindow dwnd = {DF_DUMMY, NULL, DfNormalProc,
24 {{-1},{-1},{-1},{-1}}};
25 static PCHAR_INFO Bsave;
26 static int Bht, Bwd;
27 BOOL DfWindowMoving;
28 BOOL DfWindowSizing;
29 /* -------- array of class definitions -------- */
30 DFCLASSDEFS DfClassDefs[] = {
31 #undef DfClassDef
32 #define DfClassDef(c,b,p,a) {b,p,a},
33 #include "classes.h"
34 };
35 DFWINDOW HiddenWindow;
36
37 /* --------- DFM_CREATE_WINDOW Message ---------- */
38 static void CreateWindowMsg(DFWINDOW wnd)
39 {
40 DfAppendWindow(wnd);
41 // DfClearAttribute(wnd, DF_VSCROLLBAR | DF_HSCROLLBAR);
42 if (DfTestAttribute(wnd, DF_SAVESELF) && DfIsVisible(wnd))
43 GetVideoBuffer(wnd);
44 }
45
46 /* --------- DFM_SHOW_WINDOW Message ---------- */
47 static void ShowWindowMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
48 {
49 if (DfGetParent(wnd) == NULL || DfIsVisible(DfGetParent(wnd)))
50 {
51 DFWINDOW cwnd;
52
53 if (DfTestAttribute(wnd, DF_SAVESELF) && wnd->videosave == NULL)
54 GetVideoBuffer(wnd);
55 DfSetVisible(wnd);
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);
60 while (cwnd != NULL)
61 {
62 if (cwnd->condition != DF_ISCLOSING)
63 DfSendMessage(cwnd, DFM_SHOW_WINDOW, p1, p2);
64 cwnd = DfNextWindow(cwnd);
65 }
66 }
67 }
68
69 /* --------- HIDE_WINDOW Message ---------- */
70 static void HideWindowMsg(DFWINDOW wnd)
71 {
72 if (DfIsVisible(wnd))
73 {
74 DfClearVisible(wnd);
75 /* --- paint what this window covered --- */
76 if (DfTestAttribute(wnd, DF_SAVESELF))
77 PutVideoBuffer(wnd);
78 #ifdef INCLUDE_MULTI_WINDOWS
79 else
80 PaintOverLappers(wnd);
81 #endif
82 }
83 }
84
85 /* --------- DFM_KEYBOARD Message ---------- */
86 static BOOL KeyboardMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
87 {
88 if (DfWindowMoving || DfWindowSizing) {
89 /* -- move or size a window with keyboard -- */
90 int x, y;
91 x=DfWindowMoving?DfGetLeft(&dwnd):DfGetRight(&dwnd);
92 y=DfWindowMoving?DfGetTop(&dwnd):DfGetBottom(&dwnd);
93 switch ((int)p1) {
94 case DF_ESC:
95 TerminateMoveSize();
96 return TRUE;
97 case DF_UP:
98 if (y)
99 --y;
100 break;
101 case DF_DN:
102 if (y < DfGetScreenHeight()-1)
103 y++;
104 break;
105 case DF_FWD:
106 if (x < DfGetScreenWidth()-1)
107 x++;
108 break;
109 case DF_BS:
110 if (x)
111 --x;
112 break;
113 case '\r':
114 DfSendMessage(wnd, DFM_BUTTON_RELEASED,x,y);
115 default:
116 return TRUE;
117 }
118 /* -- use the mouse functions to move/size - */
119 DfSendMessage(wnd, MOUSE_MOVED, x, y);
120 return TRUE;
121 }
122
123 switch ((int)p1)
124 {
125 case DF_F1:
126 DfSendMessage(wnd, DFM_COMMAND, DF_ID_HELP, 0);
127 return TRUE;
128
129 case ' ':
130 if ((int)p2 & DF_ALTKEY)
131 if (DfTestAttribute(wnd, DF_HASTITLEBAR))
132 if (DfTestAttribute(wnd, DF_CONTROLBOX))
133 DfBuildSystemMenu(wnd);
134 return TRUE;
135
136 case DF_CTRL_F4:
137 if (DfTestAttribute(wnd, DF_CONTROLBOX))
138 {
139 DfSendMessage(wnd, DFM_CLOSE_WINDOW, 0, 0);
140 DfSkipApplicationControls();
141 return TRUE;
142 }
143 break;
144
145 default:
146 break;
147 }
148
149 return FALSE;
150 }
151
152 /* --------- COMMAND Message ---------- */
153 static void CommandMsg(DFWINDOW wnd, DF_PARAM p1)
154 {
155 switch ((int)p1) {
156 case DF_ID_HELP:
157 DfDisplayHelp(wnd,DfClassNames[DfGetClass(wnd)]);
158 break;
159 #ifdef INCLUDE_RESTORE
160 case DF_ID_SYSRESTORE:
161 DfSendMessage(wnd, DFM_RESTORE, 0, 0);
162 break;
163 #endif
164 case DF_ID_SYSMOVE:
165 DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE,
166 (DF_PARAM) &dwnd);
167 DfSendMessage(wnd, DFM_CAPTURE_KEYBOARD, TRUE,
168 (DF_PARAM) &dwnd);
169 DfWindowMoving = TRUE;
170 dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
171 break;
172 case DF_ID_SYSSIZE:
173 DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE,
174 (DF_PARAM) &dwnd);
175 DfSendMessage(wnd, DFM_CAPTURE_KEYBOARD, TRUE,
176 (DF_PARAM) &dwnd);
177 DfWindowSizing = TRUE;
178 dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
179 break;
180 #ifdef INCLUDE_MINIMIZE
181 case DF_ID_SYSMINIMIZE:
182 DfSendMessage(wnd, DFM_MINIMIZE, 0, 0);
183 break;
184 #endif
185 #ifdef INCLUDE_MAXIMIZE
186 case DF_ID_SYSMAXIMIZE:
187 DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0);
188 break;
189 #endif
190 case DF_ID_SYSCLOSE:
191 DfSendMessage(wnd, DFM_CLOSE_WINDOW, 0, 0);
192 DfSkipApplicationControls();
193 break;
194 default:
195 break;
196 }
197 }
198
199 /* --------- DFM_SETFOCUS Message ---------- */
200 static void SetFocusMsg(DFWINDOW wnd, DF_PARAM p1)
201 {
202 DFRECT rc = {0,0,0,0};
203
204 if (p1 && wnd != NULL && DfInFocus != wnd)
205 {
206 DFWINDOW this, thispar;
207 DFWINDOW that = NULL, thatpar = NULL;
208
209 DFWINDOW cwnd = wnd, fwnd = DfGetParent(wnd);
210 /* ---- post focus in ancestors ---- */
211 while (fwnd != NULL)
212 {
213 fwnd->childfocus = cwnd;
214 cwnd = fwnd;
215 fwnd = DfGetParent(fwnd);
216 }
217 /* ---- de-post focus in self and children ---- */
218 fwnd = wnd;
219 while (fwnd != NULL)
220 {
221 cwnd = fwnd->childfocus;
222 fwnd->childfocus = NULL;
223 fwnd = cwnd;
224 }
225
226 this = wnd;
227 that = thatpar = DfInFocus;
228
229 /* ---- find common ancestor of prev focus and this window --- */
230 while (thatpar != NULL)
231 {
232 thispar = wnd;
233 while (thispar != NULL)
234 {
235 if (this == DfCaptureMouse || this == DfCaptureKeyboard)
236 {
237 /* ---- don't repaint if this window has capture ---- */
238 that = thatpar = NULL;
239 break;
240 }
241 if (thispar == thatpar)
242 {
243 /* ---- don't repaint if DF_SAVESELF window had focus ---- */
244 if (this != that && DfTestAttribute(that, DF_SAVESELF))
245 that = thatpar = NULL;
246 break;
247 }
248 this = thispar;
249 thispar = DfGetParent(thispar);
250 }
251 if (thispar != NULL)
252 break;
253 that = thatpar;
254 thatpar = DfGetParent(thatpar);
255 }
256 if (DfInFocus != NULL)
257 DfSendMessage(DfInFocus, DFM_SETFOCUS, FALSE, 0);
258 DfInFocus = wnd;
259 if (that != NULL && DfIsVisible(wnd))
260 {
261 rc = DfSubRectangle(DfWindowRect(that), DfWindowRect(this));
262 if (!DfValidRect(rc))
263 {
264 if (DfApplicationWindow != NULL)
265 {
266 DFWINDOW fwnd = DfFirstWindow(DfApplicationWindow);
267 while (fwnd != NULL)
268 {
269 if (!DfIsAncestor(wnd, fwnd))
270 {
271 rc = DfSubRectangle(DfWindowRect(wnd),DfWindowRect(fwnd));
272 if (DfValidRect(rc))
273 break;
274 }
275 fwnd = DfNextWindow(fwnd);
276 }
277 }
278 }
279 }
280 if (that != NULL && !DfValidRect(rc) && DfIsVisible(wnd))
281 {
282 DfSendMessage(wnd, DFM_BORDER, 0, 0);
283 this = NULL;
284 }
285 DfReFocus(wnd);
286 if (this != NULL)
287 DfSendMessage(this, DFM_SHOW_WINDOW, 0, 0);
288 }
289 else if (!p1 && DfInFocus == wnd)
290 {
291 /* clearing focus */
292 DfInFocus = NULL;
293 DfSendMessage(wnd, DFM_BORDER, 0, 0);
294 }
295 }
296
297 /* --------- DOUBLE_CLICK Message ---------- */
298 static void DoubleClickMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
299 {
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();
306 }
307 }
308 }
309
310 /* --------- DFM_LEFT_BUTTON Message ---------- */
311 static void LeftButtonMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
312 {
313 int mx = (int) p1 - DfGetLeft(wnd);
314 int my = (int) p2 - DfGetTop(wnd);
315 if (DfWindowSizing || DfWindowMoving)
316 return;
317 if (DfHitControlBox(wnd, mx, my)) {
318 DfBuildSystemMenu(wnd);
319 return;
320 }
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
330 else
331 /* --- hit the maximize box --- */
332 DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0);
333 #endif
334 return;
335 }
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);
341 return;
342 }
343 #endif
344 }
345 #ifdef INCLUDE_MAXIMIZE
346 if (wnd->condition == DF_ISMAXIMIZED)
347 return;
348 #endif
349 if (DfTestAttribute(wnd, DF_MOVEABLE)) {
350 DfWindowMoving = TRUE;
351 px = mx;
352 py = my;
353 diff = (int) mx;
354 DfSendMessage(wnd, DFM_CAPTURE_MOUSE, TRUE,
355 (DF_PARAM) &dwnd);
356 dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
357 }
358 return;
359 }
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)
365 return;
366 #endif
367 if (!DfTestAttribute(wnd, DF_SIZEABLE))
368 return;
369 #ifdef INCLUDE_MAXIMIZE
370 if (wnd->condition == DF_ISMAXIMIZED) {
371 if (DfGetParent(wnd) == NULL)
372 return;
373 if (DfTestAttribute(DfGetParent(wnd),DF_HASBORDER))
374 return;
375 /* ----- resizing a maximized window over a
376 borderless parent ----- */
377 wnd = DfGetParent(wnd);
378 }
379 #endif
380 DfWindowSizing = TRUE;
381 DfSendMessage(wnd, DFM_CAPTURE_MOUSE,
382 TRUE, (DF_PARAM) &dwnd);
383 dragborder(wnd, DfGetLeft(wnd), DfGetTop(wnd));
384 }
385 }
386
387 /* --------- MOUSE_MOVED Message ---------- */
388 static BOOL MouseMovedMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
389 {
390 if (DfWindowMoving) {
391 int leftmost = 0, topmost = 0,
392 bottommost = DfGetScreenHeight()-2,
393 rightmost = DfGetScreenWidth()-2;
394 int x = (int) p1 - diff;
395 int y = (int) p2;
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);
403 }
404 if (x < leftmost || x > rightmost ||
405 y < topmost || y > bottommost) {
406 x = max(x, leftmost);
407 x = min(x, rightmost);
408 y = max(y, topmost);
409 y = min(y, bottommost);
410 }
411
412 if (x != px || y != py) {
413 px = x;
414 py = y;
415 dragborder(wnd, x, y);
416 }
417 return TRUE;
418 }
419 if (DfWindowSizing) {
420 sizeborder(wnd, (int) p1, (int) p2);
421 return TRUE;
422 }
423 return FALSE;
424 }
425
426 #ifdef INCLUDE_MAXIMIZE
427 /* --------- DFM_MAXIMIZE Message ---------- */
428 static void MaximizeMsg(DFWINDOW wnd)
429 {
430 DFRECT rc = {0, 0, 0, 0};
431 DFRECT holdrc;
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;
449 }
450 #endif
451
452 #ifdef INCLUDE_MINIMIZE
453 /* --------- DFM_MINIMIZE Message ---------- */
454 static void MinimizeMsg(DFWINDOW wnd)
455 {
456 DFRECT rc;
457 DFRECT holdrc;
458
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)
469 DfSetNextFocus();
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;
477 }
478 #endif
479
480 #ifdef INCLUDE_RESTORE
481 /* --------- DFM_RESTORE Message ---------- */
482 static void RestoreMsg(DFWINDOW wnd)
483 {
484 DFRECT holdrc;
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,
492 wnd->RestoredRC.tp);
493 wnd->RestoredRC = holdrc;
494 DfSendMessage(wnd, DFM_DFM_SIZE, wnd->RestoredRC.rt,
495 wnd->RestoredRC.bt);
496 if (wnd != DfInFocus)
497 DfSendMessage(wnd, DFM_SETFOCUS, TRUE, 0);
498 else
499 DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
500 }
501 #endif
502
503 /* --------- DFM_MOVE Message ---------- */
504 static void MoveMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
505 {
506 DFWINDOW cwnd;
507 BOOL wasVisible = DfIsVisible(wnd);
508 int xdif = (int) p1 - wnd->rc.lf;
509 int ydif = (int) p2 - wnd->rc.tp;
510
511 if (xdif == 0 && ydif == 0)
512 return;
513 if (wasVisible)
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;
521
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);
526 }
527 if (wasVisible)
528 DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
529 }
530
531 /* --------- SIZE Message ---------- */
532 static void SizeMsg(DFWINDOW wnd, DF_PARAM p1, DF_PARAM p2)
533 {
534 BOOL wasVisible = DfIsVisible(wnd);
535 DFWINDOW cwnd;
536 DFRECT rc;
537 int xdif = (int) p1 - wnd->rc.rt;
538 int ydif = (int) p2 - wnd->rc.bt;
539
540 if (xdif == 0 && ydif == 0)
541 return;
542 if (wasVisible)
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;
548
549 if (wnd->condition == DF_SRESTORED)
550 wnd->RestoredRC = DfWindowRect(wnd);
551
552 #ifdef INCLUDE_MAXIMIZE
553 rc = DfClientRect(wnd);
554
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);
560 }
561
562 #endif
563 if (wasVisible)
564 DfSendMessage(wnd, DFM_SHOW_WINDOW, 0, 0);
565 }
566
567 /* --------- DFM_CLOSE_WINDOW Message ---------- */
568 static void CloseWindowMsg(DFWINDOW wnd)
569 {
570 DFWINDOW cwnd;
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 --- */
579
580 cwnd = DfLastWindow(wnd);
581 while (cwnd != NULL) {
582 if (DfInFocus == cwnd)
583 DfInFocus = wnd;
584 DfSendMessage(cwnd,DFM_CLOSE_WINDOW,0,0);
585 cwnd = DfLastWindow(wnd);
586 }
587
588 /* --- change focus if this window had it -- */
589 if (wnd == DfInFocus)
590 DfSetPrevFocus();
591 /* -- free memory allocated to this window - */
592 if (wnd->title != NULL)
593 free(wnd->title);
594 if (wnd->videosave != NULL)
595 free(wnd->videosave);
596 /* -- remove window from parent's list of children -- */
597 DfRemoveWindow(wnd);
598 if (wnd == DfInFocus)
599 DfInFocus = NULL;
600 free(wnd);
601 }
602
603 /* ---- Window-processing module for DF_NORMAL window class ---- */
604 int DfNormalProc(DFWINDOW wnd, DFMESSAGE msg, DF_PARAM p1, DF_PARAM p2)
605 {
606 switch (msg) {
607 case DFM_CREATE_WINDOW:
608 CreateWindowMsg(wnd);
609 break;
610 case DFM_SHOW_WINDOW:
611 ShowWindowMsg(wnd, p1, p2);
612 break;
613 case DFM_HIDE_WINDOW:
614 HideWindowMsg(wnd);
615 break;
616 case DFM_DISPLAY_HELP:
617 DfDisplayHelp(wnd, (char *)p1);
618 break;
619 case DFM_INSIDE_WINDOW:
620 return InsideWindow(wnd, (int) p1, (int) p2);
621 case DFM_KEYBOARD:
622 if (KeyboardMsg(wnd, p1, p2))
623 return TRUE;
624 /* ------- fall through ------- */
625 case DFM_ADDSTATUS:
626 case DFM_SHIFT_CHANGED:
627 if (DfGetParent(wnd) != NULL)
628 DfPostMessage(DfGetParent(wnd), msg, p1, p2);
629 break;
630 case DFM_PAINT:
631 if (DfIsVisible(wnd))
632 DfClearWindow(wnd, (DFRECT *)p1, ' ');
633 break;
634 case DFM_BORDER:
635 if (DfIsVisible(wnd))
636 {
637 if (DfTestAttribute(wnd, DF_HASBORDER))
638 DfRepaintBorder(wnd, (DFRECT *)p1);
639 else if (DfTestAttribute(wnd, DF_HASTITLEBAR))
640 DfDisplayTitle(wnd, (DFRECT *)p1);
641 }
642 break;
643 case DFM_COMMAND:
644 CommandMsg(wnd, p1);
645 break;
646 case DFM_SETFOCUS:
647 SetFocusMsg(wnd, p1);
648 break;
649 case DFM_DOUBLE_CLICK:
650 DoubleClickMsg(wnd, p1, p2);
651 break;
652 case DFM_LEFT_BUTTON:
653 LeftButtonMsg(wnd, p1, p2);
654 break;
655 case MOUSE_MOVED:
656 if (MouseMovedMsg(wnd, p1, p2))
657 return TRUE;
658 break;
659 case DFM_BUTTON_RELEASED:
660 if (DfWindowMoving || DfWindowSizing)
661 {
662 if (DfWindowMoving)
663 DfPostMessage(wnd,DFM_MOVE,dwnd.rc.lf,dwnd.rc.tp);
664 else
665 DfPostMessage(wnd, DFM_DFM_SIZE,dwnd.rc.rt,dwnd.rc.bt);
666 TerminateMoveSize();
667 }
668 break;
669 #ifdef INCLUDE_MAXIMIZE
670 case DFM_MAXIMIZE:
671 if (wnd->condition != DF_ISMAXIMIZED)
672 MaximizeMsg(wnd);
673 break;
674 #endif
675 #ifdef INCLUDE_MINIMIZE
676 case DFM_MINIMIZE:
677 if (wnd->condition != DF_ISMINIMIZED)
678 MinimizeMsg(wnd);
679 break;
680 #endif
681 #ifdef INCLUDE_RESTORE
682 case DFM_RESTORE:
683 if (wnd->condition != DF_SRESTORED) {
684 #ifdef INCLUDE_MAXIMIZE
685 if (wnd->oldcondition == DF_ISMAXIMIZED)
686 DfSendMessage(wnd, DFM_MAXIMIZE, 0, 0);
687 else
688 #endif
689 RestoreMsg(wnd);
690 }
691 break;
692 #endif
693 case DFM_MOVE:
694 MoveMsg(wnd, p1, p2);
695 break;
696 case DFM_DFM_SIZE: {
697 SizeMsg(wnd, p1, p2);
698 break;
699 }
700 case DFM_CLOSE_WINDOW:
701 CloseWindowMsg(wnd);
702 break;
703 default:
704 break;
705 }
706 return TRUE;
707 }
708 #ifdef INCLUDE_MINIMIZE
709 /* ---- compute lower right icon space in a rectangle ---- */
710 static DFRECT LowerRight(DFRECT prc)
711 {
712 DFRECT rc;
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;
717 return rc;
718 }
719 /* ----- compute a position for a minimized window icon ---- */
720 static DFRECT PositionIcon(DFWINDOW wnd)
721 {
722 DFWINDOW pwnd = DfGetParent(wnd);
723 DFRECT rc;
724 DfRectLeft(rc) = DfGetScreenWidth()-DF_ICONWIDTH;
725 DfRectTop(rc) = DfGetScreenHeight()-DF_ICONHEIGHT;
726 DfRectRight(rc) = DfGetScreenWidth()-1;
727 DfRectBottom(rc) = DfGetScreenHeight()-1;
728 if (pwnd != NULL) {
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) {
735 DFRECT rc1;
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) {
742 DfRectLeft(rc) =
743 DfRectRight(prc)-DF_ICONWIDTH;
744 DfRectRight(rc) =
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);
750 }
751 break;
752 }
753 }
754 cwnd = DfNextWindow(cwnd);
755 }
756 }
757 return rc;
758 }
759 #endif
760 /* ----- terminate the move or size operation ----- */
761 static void TerminateMoveSize(void)
762 {
763 px = py = -1;
764 diff = 0;
765 DfSendMessage(&dwnd, DFM_RELEASE_MOUSE, TRUE, 0);
766 DfSendMessage(&dwnd, DFM_RELEASE_KEYBOARD, TRUE, 0);
767 RestoreBorder(dwnd.rc);
768 DfWindowMoving = DfWindowSizing = FALSE;
769 }
770 /* ---- build a dummy window border for moving or sizing --- */
771 static void dragborder(DFWINDOW wnd, int x, int y)
772 {
773 RestoreBorder(dwnd.rc);
774 /* ------- build the dummy window -------- */
775 dwnd.rc.lf = x;
776 dwnd.rc.tp = y;
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);
784 SaveBorder(dwnd.rc);
785 DfRepaintBorder(&dwnd, NULL);
786 }
787 /* ---- write the dummy window border for sizing ---- */
788 static void sizeborder(DFWINDOW wnd, int rt, int bt)
789 {
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)));
799 }
800 rt = min(rt, rightmost);
801 bt = min(bt, bottommost);
802 rt = max(rt, leftmost);
803 bt = max(bt, topmost);
804
805 if (rt != px || bt != py)
806 RestoreBorder(dwnd.rc);
807
808 /* ------- change the dummy window -------- */
809 dwnd.ht = bt-dwnd.rc.tp+1;
810 dwnd.wd = rt-dwnd.rc.lf+1;
811 dwnd.rc.rt = rt;
812 dwnd.rc.bt = bt;
813 if (rt != px || bt != py) {
814 px = rt;
815 py = bt;
816 SaveBorder(dwnd.rc);
817 DfRepaintBorder(&dwnd, NULL);
818 }
819 }
820 #ifdef INCLUDE_MULTI_WINDOWS
821 /* ----- adjust a rectangle to include the shadow ----- */
822 static DFRECT adjShadow(DFWINDOW wnd)
823 {
824 DFRECT rc;
825 rc = wnd->rc;
826 if (DfTestAttribute(wnd, DF_SHADOW)) {
827 if (DfRectRight(rc) < DfGetScreenWidth()-1)
828 DfRectRight(rc)++;
829 if (DfRectBottom(rc) < DfGetScreenHeight()-1)
830 DfRectBottom(rc)++;
831 }
832 return rc;
833 }
834 /* --- repaint a rectangular subsection of a window --- */
835 static void PaintOverLap(DFWINDOW wnd, DFRECT rc)
836 {
837 if (DfIsVisible(wnd)) {
838 int isBorder, isTitle, isData;
839 isBorder = isTitle = FALSE;
840 isData = TRUE;
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);
852 }
853 else if (DfTestAttribute(wnd, DF_HASTITLEBAR))
854 isTitle = DfRectTop(rc) == 0 &&
855 DfRectRight(rc) > 0 &&
856 DfRectLeft(rc)<DfWindowWidth(wnd)-DfBorderAdj(wnd);
857
858 if (DfRectLeft(rc) >= DfWindowWidth(wnd)-DfBorderAdj(wnd))
859 isData = FALSE;
860 if (DfRectTop(rc) >= DfWindowHeight(wnd)-DfBottomBorderAdj(wnd))
861 isData = FALSE;
862 if (DfTestAttribute(wnd, DF_HASBORDER)) {
863 if (DfRectRight(rc) == 0)
864 isData = FALSE;
865 if (DfRectBottom(rc) == 0)
866 isData = FALSE;
867 }
868 if (DfTestAttribute(wnd, DF_SHADOW))
869 isBorder |= DfRectRight(rc) == DfWindowWidth(wnd) ||
870 DfRectBottom(rc) == DfWindowHeight(wnd);
871 if (isData)
872 DfSendMessage(wnd, DFM_PAINT, (DF_PARAM) &rc, TRUE);
873 if (isBorder)
874 DfSendMessage(wnd, DFM_BORDER, (DF_PARAM) &rc, 0);
875 else if (isTitle)
876 DfDisplayTitle(wnd, &rc);
877 }
878 }
879 /* ------ paint the part of a window that is overlapped
880 by another window that is being hidden ------- */
881 static void PaintOver(DFWINDOW wnd)
882 {
883 DFRECT wrc, rc;
884 wrc = adjShadow(HiddenWindow);
885 rc = adjShadow(wnd);
886 rc = DfSubRectangle(rc, wrc);
887 if (DfValidRect(rc))
888 PaintOverLap(wnd, DfRelativeWindowRect(wnd, rc));
889 }
890 /* --- paint the overlapped parts of all children --- */
891 static void PaintOverChildren(DFWINDOW pwnd)
892 {
893 DFWINDOW cwnd = DfFirstWindow(pwnd);
894 while (cwnd != NULL) {
895 if (cwnd != HiddenWindow) {
896 PaintOver(cwnd);
897 PaintOverChildren(cwnd);
898 }
899 cwnd = DfNextWindow(cwnd);
900 }
901 }
902 /* -- recursive overlapping paint of parents -- */
903 static void PaintOverParents(DFWINDOW wnd)
904 {
905 DFWINDOW pwnd = DfGetParent(wnd);
906 if (pwnd != NULL) {
907 PaintOverParents(pwnd);
908 PaintOver(pwnd);
909 PaintOverChildren(pwnd);
910 }
911 }
912 /* - paint the parts of all windows that a window is over - */
913 static void PaintOverLappers(DFWINDOW wnd)
914 {
915 HiddenWindow = wnd;
916 PaintOverParents(wnd);
917 }
918 /* --- paint those parts of a window that are overlapped --- */
919 static void PaintUnderLappers(DFWINDOW wnd)
920 {
921 DFWINDOW hwnd = DfNextWindow(wnd);
922 while (hwnd != NULL) {
923 /* ------- test only at document window level ------ */
924 DFWINDOW pwnd = DfGetParent(hwnd);
925 /* if (pwnd == NULL || DfGetClass(pwnd) == DF_APPLICATION) */ {
926 /* ---- don't bother testing self ----- */
927 if (DfIsVisible(hwnd) && hwnd != wnd) {
928 /* --- see if other window is descendent --- */
929 while (pwnd != NULL) {
930 if (pwnd == wnd)
931 break;
932 pwnd = DfGetParent(pwnd);
933 }
934 /* ----- don't test descendent overlaps ----- */
935 if (pwnd == NULL) {
936 /* -- see if other window is ancestor --- */
937 pwnd = DfGetParent(wnd);
938 while (pwnd != NULL) {
939 if (pwnd == hwnd)
940 break;
941 pwnd = DfGetParent(pwnd);
942 }
943 /* --- don't test ancestor overlaps --- */
944 if (pwnd == NULL) {
945 HiddenWindow = DfGetAncestor(hwnd);
946 DfClearVisible(HiddenWindow);
947 PaintOver(wnd);
948 DfSetVisible(HiddenWindow);
949 }
950 }
951 }
952 }
953 hwnd = DfNextWindow(hwnd);
954 }
955 /* --------- repaint all children of this window
956 the same way ----------- */
957 hwnd = DfFirstWindow(wnd);
958 while (hwnd != NULL) {
959 PaintUnderLappers(hwnd);
960 hwnd = DfNextWindow(hwnd);
961 }
962 }
963 #endif /* #ifdef INCLUDE_MULTI_WINDOWS */
964
965 /* --- save video area to be used by dummy window border --- */
966 static void SaveBorder(DFRECT rc)
967 {
968 Bht = DfRectBottom(rc) - DfRectTop(rc) + 1;
969 Bwd = DfRectRight(rc) - DfRectLeft(rc) + 1;
970 Bsave = DfRealloc(Bsave, Bht * Bwd * sizeof(CHAR_INFO));
971
972 DfGetVideo(rc,Bsave);
973 }
974 /* ---- restore video area used by dummy window border ---- */
975 static void RestoreBorder(DFRECT rc)
976 {
977 if (Bsave != NULL)
978 {
979 DfStoreVideo(rc, Bsave);
980 free(Bsave);
981 Bsave = NULL;
982 }
983 }
984 /* ----- test if screen coordinates are in a window ---- */
985 static BOOL InsideWindow(DFWINDOW wnd, int x, int y)
986 {
987 DFRECT rc;
988 rc = DfWindowRect(wnd);
989 if (!DfTestAttribute(wnd, DF_NOCLIP))
990 {
991 DFWINDOW pwnd = DfGetParent(wnd);
992 while (pwnd != NULL)
993 {
994 rc = DfSubRectangle(rc, DfClientRect(pwnd));
995 pwnd = DfGetParent(pwnd);
996 }
997 }
998 return DfInsideRect(x, y, rc);
999 }
1000
1001 BOOL DfIsDerivedFrom(DFWINDOW wnd, DFCLASS class)
1002 {
1003 DFCLASS tclass = DfGetClass(wnd);
1004 while (tclass != -1) {
1005 if (tclass == class)
1006 return TRUE;
1007 tclass = (DfClassDefs[tclass].base);
1008 }
1009 return FALSE;
1010 }
1011
1012 /* -- find the oldest document window ancestor of a window -- */
1013 DFWINDOW DfGetAncestor(DFWINDOW wnd)
1014 {
1015 if (wnd != NULL) {
1016 while (DfGetParent(wnd) != NULL) {
1017 if (DfGetClass(DfGetParent(wnd)) == DF_APPLICATION)
1018 break;
1019 wnd = DfGetParent(wnd);
1020 }
1021 }
1022 return wnd;
1023 }
1024
1025 BOOL DfIsVisible(DFWINDOW wnd)
1026 {
1027 while (wnd != NULL) {
1028 if (isHidden(wnd))
1029 return FALSE;
1030 wnd = DfGetParent(wnd);
1031 }
1032 return TRUE;
1033 }
1034
1035 /* -- adjust a window's rectangle to clip it to its parent - */
1036 static DFRECT ClipRect(DFWINDOW wnd)
1037 {
1038 DFRECT rc;
1039 rc = DfWindowRect(wnd);
1040 if (DfTestAttribute(wnd, DF_SHADOW)) {
1041 DfRectBottom(rc)++;
1042 DfRectRight(rc)++;
1043 }
1044 return DfClipRectangle(wnd, rc);
1045 }
1046
1047 /* -- get the video memory that is to be used by a window -- */
1048 static void GetVideoBuffer(DFWINDOW wnd)
1049 {
1050 DFRECT rc;
1051 int ht;
1052 int wd;
1053
1054 rc = ClipRect(wnd);
1055 ht = DfRectBottom(rc) - DfRectTop(rc) + 1;
1056 wd = DfRectRight(rc) - DfRectLeft(rc) + 1;
1057 wnd->videosave = DfRealloc(wnd->videosave, (ht * wd * sizeof(CHAR_INFO)));
1058 DfGetVideo(rc, wnd->videosave);
1059 }
1060
1061 /* -- put the video memory that is used by a window -- */
1062 static void PutVideoBuffer(DFWINDOW wnd)
1063 {
1064 if (wnd->videosave != NULL)
1065 {
1066 DFRECT rc;
1067 rc = ClipRect(wnd);
1068 DfStoreVideo(rc, wnd->videosave);
1069 free(wnd->videosave);
1070 wnd->videosave = NULL;
1071 }
1072 }
1073
1074 /* ------- return TRUE if awnd is an ancestor of wnd ------- */
1075 BOOL DfIsAncestor(DFWINDOW wnd, DFWINDOW awnd)
1076 {
1077 while (wnd != NULL) {
1078 if (wnd == awnd)
1079 return TRUE;
1080 wnd = DfGetParent(wnd);
1081 }
1082 return FALSE;
1083 }
1084
1085 /* EOF */