2 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3 * Portions Copyright (c) 1991 David I. Bell
5 * Non-Win32 API helper routines for window showing/hiding/exposing
11 /* Redraw all windows*/
15 /* redraw all windows except desktop window*/
16 MwExposeArea(rootwp, 0, 0, rootwp->winrect.right,
17 rootwp->winrect.bottom);
19 /* redraw desktop window*/
20 PostMessage(rootwp, WM_PAINT, 0, 0L);
24 * Hide the window to make it and its children invisible on the screen.
25 * This is a recursive routine which increments the unmapcount values for
26 * this window and all of its children, and causes exposure events for
27 * windows which are newly uncovered.
30 MwHideWindow(HWND hwnd,BOOL bChangeFocus, BOOL bSendMsg)
33 HWND pwp; /* parent window */
34 HWND sibwp; /* sibling window */
35 HWND childwp; /* child window */
40 ++mwpaintNC; /* experimental NC paint handling*/
42 /* send hide message if currently visible*/
43 if(bSendMsg && wp->unmapcount == 0)
44 SendMessage(wp, WM_SHOWWINDOW, FALSE, 0L);
48 for (childwp = wp->children; childwp; childwp = childwp->siblings)
49 MwHideWindow(childwp, bChangeFocus, bSendMsg);
56 if (bChangeFocus && wp == focuswp)
57 SetFocus(rootwp->children? rootwp->children: rootwp);
60 * If the parent window is still unmapped, then we are all done.
62 if (wp->parent->unmapcount)
66 * Clear the area in the parent for this window, causing an
67 * exposure event for it.
70 MwClearWindow(pwp, wp->winrect.left - pwp->winrect.left,
71 wp->winrect.top - pwp->winrect.top,
72 wp->winrect.right - wp->winrect.left,
73 wp->winrect.bottom - wp->winrect.top, TRUE);
76 * Finally clear and redraw all parts of our lower sibling
77 * windows that were covered by this window.
80 while (sibwp->siblings) {
81 sibwp = sibwp->siblings;
82 MwExposeArea(sibwp, wp->winrect.left, wp->winrect.top,
83 wp->winrect.right - wp->winrect.left,
84 wp->winrect.bottom - wp->winrect.top);
89 * Map the window to possibly make it and its children visible on the screen.
90 * This is a recursive routine which decrements the unmapcount values for
91 * this window and all of its children, and causes exposure events for
92 * those windows which become visible.
95 MwShowWindow(HWND hwnd, BOOL bSendMsg)
102 ++mwpaintNC; /* experimental NC paint handling*/
107 if (wp->unmapcount == 0) {
108 SendMessage(wp, WM_SHOWWINDOW, TRUE, 0L);
109 MwCheckMouseWindow();
114 * If the window just became visible,
115 * then draw its border, clear it to the background color, and
116 * generate an exposure event.
118 if (wp->unmapcount == 0) {
119 /*MwDrawBorder(wp);*/
120 MwClearWindow(wp, 0, 0, wp->winrect.right - wp->winrect.left,
121 wp->winrect.bottom - wp->winrect.top, TRUE);
125 * Do the same thing for the children.
127 for (wp = wp->children; wp; wp = wp->siblings)
128 MwShowWindow(wp, bSendMsg);
132 * Raise a window to the highest level among its siblings.
135 MwRaiseWindow(HWND hwnd)
141 if (!wp || wp == rootwp)
144 ++mwpaintNC; /* experimental NC paint handling*/
147 * If this is already the highest window then we are done.
149 prevwp = wp->parent->children;
154 * Find the sibling just before this window so we can unlink it.
155 * Also, determine if any sibling ahead of us overlaps the window.
156 * Remember that for exposure events.
159 while (prevwp->siblings != wp) {
160 overlap |= MwCheckOverlap(prevwp, wp);
161 prevwp = prevwp->siblings;
163 overlap |= MwCheckOverlap(prevwp, wp);
166 * Now unlink the window and relink it in at the front of the
169 prevwp->siblings = wp->siblings;
170 wp->siblings = wp->parent->children;
171 wp->parent->children = wp;
174 * Finally redraw the window if necessary.
177 /*MwDrawBorder(wp);*/
178 MwExposeArea(wp, wp->winrect.left, wp->winrect.top,
179 wp->winrect.right - wp->winrect.left,
180 wp->winrect.bottom - wp->winrect.top);
185 * Lower a window to the lowest level among its siblings.
188 MwLowerWindow(HWND hwnd)
192 HWND sibwp; /* sibling window */
193 HWND expwp; /* siblings being exposed */
195 if (!wp || wp == rootwp || !wp->siblings)
198 ++mwpaintNC; /* experimental NC paint handling*/
201 * Find the sibling just before this window so we can unlink us.
203 prevwp = wp->parent->children;
205 while (prevwp->siblings != wp)
206 prevwp = prevwp->siblings;
210 * Remember the first sibling that is after us, so we can
211 * generate exposure events for the remaining siblings. Then
212 * walk down the sibling chain looking for the last sibling.
214 expwp = wp->siblings;
216 while (sibwp->siblings)
217 sibwp = sibwp->siblings;
220 * Now unlink the window and relink it in at the end of the
224 wp->parent->children = wp->siblings;
226 prevwp->siblings = wp->siblings;
227 sibwp->siblings = wp;
232 * Finally redraw the sibling windows which this window covered
233 * if they overlapped our window.
235 while (expwp && (expwp != wp)) {
236 if (MwCheckOverlap(wp, expwp))
237 MwExposeArea(expwp, wp->winrect.left, wp->winrect.top,
238 wp->winrect.right - wp->winrect.left,
239 wp->winrect.bottom - wp->winrect.top);
240 expwp = expwp->siblings;
245 * Check to see if the first window overlaps the second window.
248 MwCheckOverlap(HWND topwp, HWND botwp)
259 if (topwp->unmapcount || botwp->unmapcount)
262 minx1 = topwp->winrect.left;
263 miny1 = topwp->winrect.top;
264 maxx1 = topwp->winrect.right - 1;
265 maxy1 = topwp->winrect.bottom - 1;
267 minx2 = botwp->winrect.left;
268 miny2 = botwp->winrect.top;
269 maxx2 = botwp->winrect.right - 1;
270 maxy2 = botwp->winrect.bottom - 1;
272 if (minx1 > maxx2 || minx2 > maxx1 || miny1 > maxy2 || miny2 > maxy1)
279 * Clear the specified area of a window and possibly make an exposure event.
280 * This sets the area window to its background color. If the exposeflag is
281 * nonzero, then this also creates an exposure event for the window.
284 MwClearWindow(HWND wp, MWCOORD x, MWCOORD y, MWCOORD width, MWCOORD height,
291 * Reduce the arguments so that they actually lie within the window.
301 if (x + width > wp->winrect.right - wp->winrect.left)
302 width = (wp->winrect.right - wp->winrect.left) - x;
303 if (y + height > wp->winrect.bottom - wp->winrect.top)
304 height = (wp->winrect.bottom - wp->winrect.top) - y;
307 * Now see if the region is really in the window. If not, then
310 if (x >= (wp->winrect.right - wp->winrect.left) ||
311 y >= (wp->winrect.bottom - wp->winrect.top) ||
312 width <= 0 || height <= 0)
316 * Now do the exposure if required.
319 MwDeliverExposureEvent(wp, x, y, width, height);
323 * Handle the exposing of the specified absolute region of the screen,
324 * starting with the specified window. That window and all of its
325 * children will be redrawn and/or exposure events generated if they
326 * overlap the specified area. This is a recursive routine.
329 MwExposeArea(HWND wp, MWCOORD rootx, MWCOORD rooty, MWCOORD width,
335 ++mwpaintNC; /* experimental NC paint handling*/
338 * First see if the area overlaps the window including the border.
339 * If not, then there is nothing more to do.
341 if (rootx >= wp->winrect.right || rooty >= wp->winrect.bottom ||
342 (rootx + width) <= wp->winrect.left ||
343 (rooty + height) <= wp->winrect.top)
348 * The area does overlap the window. See if the area overlaps
349 * the border, and if so, then redraw it.
351 if (rootx < wp->winrect.left || rooty < wp->winrect.top ||
352 (rootx + width) > wp->winrect.right ||
353 (rooty + height) > wp->winrect.bottom)
358 * Now clear the window itself in the specified area,
359 * which might cause an exposure event.
361 MwClearWindow(wp, rootx - wp->winrect.left, rooty - wp->winrect.top,
362 width, height, TRUE);
365 * Now do the same for all the children.
367 for (wp = wp->children; wp; wp = wp->siblings)
368 MwExposeArea(wp, rootx, rooty, width, height);