1 /* windMove.c -
2 *
3 * This file contains the functions which move windows around on
4 * the screen. It does not contain the functions that change the
5 * contents of the windows.
6 *
7 * *********************************************************************
8 * * Copyright (C) 1985, 1990 Regents of the University of California. *
9 * * Permission to use, copy, modify, and distribute this *
10 * * software and its documentation for any purpose and without *
11 * * fee is hereby granted, provided that the above copyright *
12 * * notice appear in all copies. The University of California *
13 * * makes no representations about the suitability of this *
14 * * software for any purpose. It is provided "as is" without *
15 * * express or implied warranty. Export of this software outside *
16 * * of the United States of America may require an export license. *
17 * *********************************************************************
18 */
19
20 #ifndef lint
21 static char rcsid[] __attribute__ ((unused)) = "$Header$";
22 #endif /* not lint */
23
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "utils/magic.h"
28 #include "textio/textio.h"
29 #include "utils/geometry.h"
30 #include "windows/windows.h"
31 #include "graphics/graphics.h"
32 #include "graphics/glyphs.h"
33 #include "windows/windInt.h"
34 #include "tiles/tile.h"
35 #include "utils/hash.h"
36 #include "database/database.h"
37 #include "utils/malloc.h"
38
39 /* The following own variable is used to pass information between
40 * WindReframe and windFindUnobscured.
41 */
42
43 static MagWindow *sharedW;
44
45 /*
46 * By default, new windows have scroll bars, border, a title caption,
47 * and allow standard window commands.
48 */
49 int WindDefaultFlags = WIND_SCROLLBARS | WIND_CAPTION |
50 WIND_BORDER | WIND_COMMANDS |
51 WIND_SCROLLABLE;
52
53 /*
54 * A mask of the current window IDs, as well as a limit on the number of
55 * windows we can create.
56 */
57
58 int windWindowMask = 0; /* One bit per window ID */
59 int windMaxWindows = 32; /* May be decreased via the WIND_MAX_WINDOWS() macro */
60 int windCurNumWindows = 0;
61
62
63 /*
64 * ----------------------------------------------------------------------------
65 * windUnlink --
66 *
67 * Unlink a window from the doubly linked list of windows.
68 *
69 * Results:
70 * None.
71 *
72 * Side effects:
73 * The window is unlinked.
74 * ----------------------------------------------------------------------------
75 */
76
77 void
windUnlink(w)78 windUnlink(w)
79 MagWindow *w;
80 {
81 ASSERT(w != (MagWindow *) NULL, "windUnlink");
82 ASSERT(windTopWindow != (MagWindow *) NULL, "windUnlink");
83 ASSERT(windBottomWindow != (MagWindow *) NULL, "windUnlink");
84 ASSERT(windTopWindow->w_prevWindow == (MagWindow *) NULL, "windUnlink");
85 ASSERT(windBottomWindow->w_nextWindow == (MagWindow *) NULL, "windUnlink");
86
87 if ( (windTopWindow == w) || (windBottomWindow == w) )
88 {
89 if (windTopWindow == w)
90 {
91 windTopWindow = w->w_nextWindow;
92 if (windTopWindow != (MagWindow *) NULL)
93 windTopWindow->w_prevWindow = (MagWindow *) NULL;
94 }
95 if (windBottomWindow == w)
96 {
97 windBottomWindow = w->w_prevWindow;
98 if (windBottomWindow != (MagWindow *) NULL)
99 windBottomWindow->w_nextWindow = (MagWindow *) NULL;
100 }
101 }
102 else
103 {
104 w->w_nextWindow->w_prevWindow = w->w_prevWindow;
105 w->w_prevWindow->w_nextWindow = w->w_nextWindow;
106 }
107
108 w->w_nextWindow = (MagWindow *) NULL;
109 w->w_prevWindow = (MagWindow *) NULL;
110 }
111
112 /*
113 * ----------------------------------------------------------------------------
114 *
115 * windFree --
116 *
117 * This local procedure does the dirty work of freeing up
118 * memory in a window.
119 *
120 * Results:
121 * None.
122 *
123 * Side effects:
124 * All storage associated with w is returned to the free pool.
125 *
126 * ----------------------------------------------------------------------------
127 */
128
129 void
windFree(w)130 windFree(w)
131 MagWindow *w;
132 {
133 windWindowMask &= ~(1 << w->w_wid);
134 windCurNumWindows--;
135 if (w->w_caption != (char *) NULL) freeMagic(w->w_caption);
136 if (w->w_iconname != (char *) NULL) freeMagic(w->w_iconname);
137 if (GrFreeBackingStorePtr != NULL) (*GrFreeBackingStorePtr)(w);
138 if (w->w_redrawAreas != (ClientData) NULL) {
139 DBFreePaintPlane( (Plane *) w->w_redrawAreas);
140 TiFreePlane( (Plane *) w->w_redrawAreas);
141 }
142 freeMagic( (char *) w);
143 }
144
145 /*
146 * ----------------------------------------------------------------------------
147 * WindSetWindowAreas --
148 *
149 * Given the location of the window on the screen, compute w->w_allArea
150 * and w->w_screenArea in the window's own coordinate system.
151 *
152 * Results:
153 * None.
154 *
155 * Side effects:
156 * Modifies w->w_allArea and w->w_screenArea.
157 * ----------------------------------------------------------------------------
158 */
159
160 void
WindSetWindowAreas(w)161 WindSetWindowAreas(w)
162 MagWindow *w;
163 {
164 switch ( WindPackageType )
165 {
166 case WIND_X_WINDOWS:
167 /* Windows have origin at lower-left corner */
168 w->w_allArea.r_xbot = w->w_allArea.r_ybot = 0;
169 w->w_allArea.r_xtop = w->w_frameArea.r_xtop - w->w_frameArea.r_xbot;
170 w->w_allArea.r_ytop = w->w_frameArea.r_ytop - w->w_frameArea.r_ybot;
171 break;
172
173 default:
174 /* Windows are all in the same coordinate system */
175 w->w_allArea = w->w_frameArea;
176 }
177 WindOutToIn(w, &w->w_allArea, &w->w_screenArea);
178 }
179
180
181 /*
182 * ----------------------------------------------------------------------------
183 * windSetWindowPosition --
184 *
185 * (deprecated function)
186 *
187 * Results:
188 * None.
189 *
190 * Side effects:
191 * None.
192 * ----------------------------------------------------------------------------
193 */
194
195 void
windSetWindowPosition(w)196 windSetWindowPosition(w)
197 MagWindow *w;
198 {
199 }
200
201 /*
202 * ----------------------------------------------------------------------------
203 * WindDelete --
204 *
205 * Delete a window.
206 *
207 * Results:
208 * TRUE if the window was deleted, FALSE otherwise.
209 *
210 * Side effects:
211 * The window disappears from the sreen. The window's client is notified
212 * that this is about to happen, and it may refuse to let it happen.
213 * ----------------------------------------------------------------------------
214 */
215
216 bool
WindDelete(w)217 WindDelete(w)
218 MagWindow *w;
219 {
220 clientRec *cr;
221
222 ASSERT(w != (MagWindow *) NULL, "WindDelete");
223
224 cr = (clientRec *) w->w_client;
225 if ( (cr->w_delete == NULL) || (*(cr->w_delete))(w) )
226 {
227 WindAreaChanged(w, &(w->w_allArea) );
228 if (GrDeleteWindowPtr != NULL) (*GrDeleteWindowPtr)(w);
229 windUnlink(w);
230 windReClip();
231 windFree(w);
232 return TRUE;
233 }
234 else
235 return FALSE;
236 }
237
238
239 /*
240 * ----------------------------------------------------------------------------
241 * WindCreate --
242 *
243 * Create a new window for the specified client.
244 *
245 * Results:
246 * A pointer to the new window, or NULL if one couldn't be created.
247 *
248 * Side effects:
249 * An empty window is created, and it is displayed.
250 * The new window is place on top of all the other
251 * windows.
252 * ----------------------------------------------------------------------------
253 */
254
255 MagWindow *
WindCreate(client,frameArea,isHint,argc,argv)256 WindCreate(client, frameArea, isHint, argc, argv)
257 WindClient client; /* The client that will control this window */
258 Rect *frameArea; /* The area that the window is to occupy */
259 bool isHint; /* TRUE if the above rectangle is only a
260 * hint and it is OK for a window package to
261 * override it to maintain a consistent
262 * user interface.
263 */
264 int argc; /* Passed to the client */
265 char *argv[];
266 {
267 MagWindow *w;
268 clientRec *cr;
269 bool OK;
270 int id;
271
272 if (windCurNumWindows + 1 > windMaxWindows) {
273 TxError("Can't have more than %d windows.\n", windMaxWindows);
274 return NULL;
275 }
276 windCurNumWindows++;
277
278 cr = (clientRec *) client;
279
280 /* initialize the window */
281 w = (MagWindow *) mallocMagic( sizeof(MagWindow) );
282 w->w_client = client;
283 w->w_flags = WindDefaultFlags;
284 w->w_clipAgainst = (LinkedRect *) NULL;
285 w->w_caption = (char *) NULL;
286 w->w_stippleOrigin.p_x = 0;
287 w->w_stippleOrigin.p_y = 0;
288 w->w_bbox = NULL;
289 w->w_grdata = (ClientData) NULL;
290 w->w_grdata2 = (ClientData) NULL;
291 w->w_backingStore = (ClientData)NULL;
292 w->w_redrawAreas = (ClientData) NULL;
293 w->w_surfaceID = (ClientData) NULL;
294 w->w_iconname = NULL;
295 for (id = 0; ((1 << id) & windWindowMask) != 0; id++) /* advance id */ ;
296 windWindowMask |= (1 << id);
297 w->w_wid = id;
298
299 /* locate window on the screen */
300 if (frameArea == (Rect *) NULL)
301 {
302 switch ( WindPackageType )
303 {
304 case WIND_X_WINDOWS:
305 /*
306 * Create default size window in upper left corner
307 * of screen.
308 */
309 w->w_frameArea.r_xbot = GrScreenRect.r_xbot;
310 w->w_frameArea.r_ytop = GrScreenRect.r_ytop;
311 w->w_frameArea.r_xtop =
312 (GrScreenRect.r_xtop - GrScreenRect.r_xbot) / 2;
313 w->w_frameArea.r_ybot =
314 (GrScreenRect.r_ytop - GrScreenRect.r_ybot) / 2;
315 break;
316
317 default:
318 w->w_frameArea = GrScreenRect;
319 }
320 }
321 else
322 w->w_frameArea = *frameArea;
323
324 WindSetWindowAreas(w);
325
326 /* now link the window in on top */
327 w->w_nextWindow = windTopWindow;
328 w->w_prevWindow = (MagWindow *) NULL;
329 if (windTopWindow == (MagWindow *) NULL)
330 windBottomWindow = w;
331 else
332 windTopWindow->w_prevWindow = w;
333 windTopWindow = w;
334
335 /* notify the client */
336 OK = ((cr->w_create == NULL) || (*(cr->w_create))(w, argc, argv));
337
338 #ifdef THREE_D
339 if (strcmp(cr->w_clientName, "wind3d"))
340 #endif
341
342 if (OK && (GrCreateWindowPtr != NULL))
343 OK = (*GrCreateWindowPtr)(w, (argc > 1) ? argv[1] : NULL);
344
345 if (OK)
346 {
347 WindSetWindowAreas(w);
348 windSetWindowPosition(w);
349 WindAreaChanged(w, &(w->w_allArea));
350 }
351 else
352 {
353 /* the client refused the new window */
354 windUnlink(w);
355 windFree(w);
356 w = (MagWindow *) NULL;
357 }
358 windReClip();
359 if ((GrCreateBackingStorePtr != NULL) && (w != NULL) &&
360 (!(w->w_flags & WIND_OBSCURED)))
361 (*GrCreateBackingStorePtr)(w);
362
363 return w;
364 }
365
366 /*
367 * ----------------------------------------------------------------------------
368 *
369 * WindOutToIn and WindInToOut --
370 *
371 * The two procedures on this page translate from window inside
372 * area (the area used to display the surface) to window
373 * outside area (the total area of the window including caption),
374 * and vice versa.
375 *
376 * Results:
377 * None.
378 *
379 * Side effects:
380 * Each procedure modifies its third parameter. WindOutToIn
381 * fills in the third parameter with the inside area of the
382 * window whose outside area is out, and WindInToOut does the
383 * opposite.
384 *
385 * ----------------------------------------------------------------------------
386 */
387
388 void
WindOutToIn(w,out,in)389 WindOutToIn(w, out, in)
390 MagWindow *w; /* Window under consideration */
391 Rect *out; /* Pointer to rectangle of outside area of
392 * a window.
393 */
394 Rect *in; /* Pointer to rectangle to be filled in with
395 * inside area corresponding to out.
396 */
397 {
398 *in = *out;
399 in->r_xbot += LEFT_BORDER(w);
400 in->r_xtop -= RIGHT_BORDER(w);
401 in->r_ybot += BOT_BORDER(w);
402 in->r_ytop -= TOP_BORDER(w);
403 }
404
WindInToOut(w,in,out)405 void WindInToOut(w, in, out)
406 MagWindow *w; /* Window under consideration */
407 Rect *in; /* Pointer to rectangle of outside area of
408 * a window.
409 */
410 Rect *out; /* Pointer to rectangle to be filled in with
411 * inside area corresponding to out.
412 */
413 {
414 *out = *in;
415 out->r_xbot -= LEFT_BORDER(w);
416 out->r_xtop += RIGHT_BORDER(w);
417 out->r_ybot -= BOT_BORDER(w);
418 out->r_ytop += TOP_BORDER(w);
419 }
420
421
422 /*
423 * ----------------------------------------------------------------------------
424 * WindUnder --
425 *
426 * Move a window underneath the rest.
427 *
428 * Results:
429 * None.
430 *
431 * Side effects:
432 * The window is moved so that it is underneath the rest. This will
433 * cause portions of uncovered windows to be redisplayed.
434 * ----------------------------------------------------------------------------
435 */
436
437 void
WindUnder(w)438 WindUnder(w)
439 MagWindow *w; /* the window to be moved */
440 {
441 Rect area;
442 MagWindow *w2;
443
444 switch ( WindPackageType )
445 {
446 case WIND_X_WINDOWS:
447 if ( GrUnderWindowPtr )
448 (*GrUnderWindowPtr)(w);
449 break;
450 default:
451 /* Mark for redisplay all the areas that this window
452 * currently obscures.
453 */
454
455 for (w2 = w->w_nextWindow; w2 != NULL; w2 = w2->w_nextWindow)
456 {
457 area = w2->w_allArea;
458 GeoClip(&area, &w->w_allArea);
459 if ((area.r_xbot <= area.r_xtop) && (area.r_ybot <= area.r_ytop))
460 WindAreaChanged(w, &area);
461 }
462
463 /* take the window out of the linked list */
464 windUnlink(w);
465
466 /* now link it back in at the bottom */
467 w->w_prevWindow = windBottomWindow;
468 if (windBottomWindow != (MagWindow *) NULL)
469 windBottomWindow->w_nextWindow = w;
470 else
471 windTopWindow = w;
472 windBottomWindow = w;
473
474 windReClip();
475 }
476 }
477
478
479 /*
480 * ----------------------------------------------------------------------------
481 * WindOver --
482 *
483 * Move a window so that it is over (on top of) the other windows.
484 *
485 * Results:
486 * None.
487 *
488 * Side effects:
489 * The window is moved to the top. This may obscure some other windows.
490 * The window that is moved will be redisplayed.
491 * ----------------------------------------------------------------------------
492 */
493
494 void
WindOver(w)495 WindOver(w)
496 MagWindow *w; /* the window to be moved */
497 {
498 LinkedRect *r;
499 Rect area;
500
501 switch ( WindPackageType )
502 {
503 case WIND_X_WINDOWS:
504 if ( GrOverWindowPtr )
505 (*GrOverWindowPtr)(w);
506 break;
507
508 default:
509 /* Mark for redisplay all of the areas of the screen that
510 * currently obscure this window.
511 */
512
513 for (r = w->w_clipAgainst; r != NULL; r = r->r_next)
514 {
515 area = r->r_r;
516 GeoClip(&area, &w->w_frameArea);
517 if ((area.r_xbot <= area.r_xtop) && (area.r_ybot <= area.r_ytop))
518 WindAreaChanged((MagWindow *) NULL, &area);
519 }
520
521 /* take the window out of the linked list */
522 windUnlink(w);
523
524 /* now link it back in at the top */
525 w->w_nextWindow = windTopWindow;
526 if (windTopWindow != (MagWindow *) NULL)
527 windTopWindow->w_prevWindow = w;
528 else
529 windBottomWindow = w;
530 windTopWindow = w;
531
532 windReClip();
533 }
534 }
535
536 /*
537 * ----------------------------------------------------------------------------
538 *
539 * windFindUnobscured --
540 *
541 * Locates one portion of a rectangle that is unobscured, if
542 * any part of the rectangle is unobscured. Used only by
543 * WindReframe.
544 *
545 * Results:
546 * Always returns TRUE.
547 *
548 * Side effects:
549 * The caller must place in the shared variable sharedW the
550 * name of a window, or NULL. That window, and all windows
551 * above it, are checked to see if any obscure area. If
552 * there is any unobscured part of area, it is placed in
553 * okArea. If several distinct parts of area are unobscured,
554 * one, but only one, of them will be placed in okArea.
555 *
556 * ----------------------------------------------------------------------------
557 */
558
559 int
windFindUnobscured(area,okArea)560 windFindUnobscured(area, okArea)
561 Rect *area; /* Area that may be obscured. */
562 Rect *okArea; /* Modified to contain one of the
563 * unobscured areas.
564 */
565 {
566 MagWindow *w;
567 w = sharedW;
568 if (w == NULL)
569 {
570 *okArea = *area;
571 return FALSE;
572 }
573 sharedW = w->w_prevWindow;
574 (void) GeoDisjoint(area, &w->w_frameArea,
575 windFindUnobscured, (ClientData) okArea);
576 return FALSE;
577 }
578
579 /*
580 * ----------------------------------------------------------------------------
581 * WindReframe --
582 *
583 * Change the size or location of a window.
584 *
585 * Results:
586 * None.
587 *
588 * Side effects:
589 * The window is moved, and areas of the screen are marked for
590 * redisplay. This routine tries to be tricky in order to avoid
591 * massive redisplay for small changes.
592 * ----------------------------------------------------------------------------
593 */
594
595 void
WindReframe(w,r,inside,move)596 WindReframe(w, r, inside, move)
597 MagWindow *w; /* the window to be reframed */
598 Rect *r; /* the new location in screen coordinates */
599 bool inside; /* TRUE if the rectangle is the screen location of
600 * the inside of the window, FALSE if the above
601 * rectangle includes border areas.
602 */
603 bool move; /* Move the coordinate system of the window the same
604 * amount as the lower left corner of the window?
605 */
606 {
607 Rect newFrameArea; /* New w_frameArea. */
608 Rect dontRedisplay; /* Used to record an area that does
609 * not have to be redisplayed.
610 */
611 int xmove, ymove; /* Distance window is moving. */
612 extern int windReframeFunc(); /* Forward declaration. */
613 clientRec *cr;
614
615 cr = (clientRec *) w->w_client;
616
617 /* Ensure that the new window size is not inside out and has some size to
618 * it. Compute the new w_frameArea (in newFrameArea).
619 */
620
621 GeoCanonicalRect(r, &newFrameArea);
622 if (inside) WindInToOut(w, &newFrameArea, &newFrameArea);
623
624 if ((w->w_flags & WIND_ISICONIC) == 0) {
625 /* Not iconic -- enforce a minimum size */
626 newFrameArea.r_xtop = MAX(newFrameArea.r_xtop,
627 newFrameArea.r_xbot + WIND_MIN_WIDTH);
628 newFrameArea.r_ytop = MAX(newFrameArea.r_ytop,
629 newFrameArea.r_ybot + WIND_MIN_HEIGHT);
630 }
631
632 /* Give the client a chance to modify the change. */
633 if (cr->w_reposition != NULL)
634 (*(cr->w_reposition))(w, &newFrameArea, FALSE);
635
636
637 /* If the window coordinates are moving, update the transform
638 * so that the lower-left corner of the window remains at the
639 * same location in surface coordinates.
640 */
641
642 if (move)
643 {
644 xmove = newFrameArea.r_xbot - w->w_frameArea.r_xbot;
645 w->w_origin.p_x += xmove << SUBPIXELBITS;
646 ymove = newFrameArea.r_ybot - w->w_frameArea.r_ybot;
647 w->w_origin.p_y += ymove << SUBPIXELBITS;
648 w->w_stippleOrigin.p_x += xmove;
649 w->w_stippleOrigin.p_y += ymove;
650 }
651
652 switch ( WindPackageType )
653 {
654 case WIND_X_WINDOWS:
655 break;
656
657 default:
658 /* Now comes the tricky part: figuring out what to redisplay.
659 * The simple way out is to force redisplay at both the old and
660 * new window positions. Naturally this code is going to be more
661 * ambitious. There are two steps. First, figure out what piece
662 * of the old window must be redisplayed, then move the window,
663 * then figure out what pieces of the new window must be redisplayed.
664 * If the window coordinates aren't moving, then any screen area
665 * common to the old and new positions needn't be redisplayed,
666 * since its contents won't change.
667 */
668
669 if (!move)
670 {
671 /* Compute the intersection of the old and new areas in
672 * dontRedisplay. Mark old areas outside of this common area as
673 * needing to be redisplayed.
674 */
675 WindOutToIn(w, &newFrameArea, &dontRedisplay);
676 GeoClip(&dontRedisplay, &w->w_screenArea);
677 (void) GeoDisjoint(&w->w_frameArea, &dontRedisplay, windReframeFunc,
678 (ClientData) w);
679 }
680 else
681 {
682 /* Record the entire old area as needing to be redisplayed. */
683
684 WindAreaChanged(w, &w->w_allArea);
685 dontRedisplay = w->w_allArea;
686 }
687 }
688
689 /* At this point, we've recorded any old area that needs to be
690 * redisplayed.
691 */
692
693 w->w_frameArea = newFrameArea;
694 WindSetWindowAreas(w);
695 windSetWindowPosition(w);
696 windFixSurfaceArea(w);
697 windReClip();
698
699 switch (WindPackageType)
700 {
701 case WIND_X_WINDOWS:
702 /* Regenerate backing store, if enabled */
703 if ((GrCreateBackingStorePtr != NULL) &&
704 (!(w->w_flags & WIND_OBSCURED)))
705 (*GrCreateBackingStorePtr)(w);
706 break;
707
708 default:
709 /* Now that the window has been moved, record any of the new area that
710 * has to be redisplayed.
711 */
712
713 (void) GeoDisjoint(&w->w_allArea, &dontRedisplay, windReframeFunc,
714 (ClientData) w);
715 }
716
717 /* Give the client a chance to do things like windMove().
718 */
719 if (cr->w_reposition != NULL)
720 (*(cr->w_reposition))(w, &newFrameArea, TRUE);
721 }
722
723 int
windReframeFunc(area,w)724 windReframeFunc(area, w)
725 Rect *area; /* Area to redisplay. */
726 MagWindow *w; /* Window in which to redisplay. */
727
728 {
729 WindAreaChanged(w, area);
730 return 0;
731 }
732
733 /*
734 * ----------------------------------------------------------------------------
735 *
736 * WindFullScreen --
737 *
738 * This procedure blows a window up so it's on top of all the others
739 * and is full-screen. Or, if the window was already full-screen,
740 * it is put back where it came from before it was made full-screen.
741 *
742 * Results:
743 * None.
744 *
745 * Side effects:
746 * The window's size and location are changed.
747 *
748 * ----------------------------------------------------------------------------
749 */
750
751 void
WindFullScreen(w)752 WindFullScreen(w)
753 MagWindow *w; /* Window to be blown up or shrunk back. */
754 {
755 int i;
756 MagWindow *w2;
757 Rect newFrameArea;
758 clientRec *cr;
759 int newDepth;
760
761 cr = (clientRec *) w->w_client;
762
763 /* Compute default new location. */
764
765 if (w->w_flags & WIND_FULLSCREEN)
766 newFrameArea = w->w_oldArea;
767 else
768 newFrameArea = GrScreenRect;
769
770 /* Give the client a chance to modify newFrameArea. */
771
772 if (cr->w_reposition != NULL)
773 (*(cr->w_reposition))(w, &newFrameArea, FALSE);
774
775 /*
776 * Now, actually modify the window and its position.
777 */
778
779 /* Compute new stuff. */
780
781 if (w->w_flags & WIND_FULLSCREEN)
782 {
783 newDepth = w->w_oldDepth;
784 w->w_flags &= ~WIND_FULLSCREEN;
785 }
786 else
787 {
788 newDepth = 0;
789 w->w_flags |= WIND_FULLSCREEN;
790
791 /* Record old depth and area. */
792
793 w->w_oldArea = w->w_frameArea;
794 w->w_oldDepth = 0;
795 for (w2 = windTopWindow; w2 != w; w2 = w2->w_nextWindow)
796 {
797 ASSERT(w2 != (MagWindow *) NULL, "WindFullScreen");
798 w->w_oldDepth += 1;
799 }
800 }
801
802
803 /* Change the view and screen location. */
804 w->w_frameArea = newFrameArea;
805 WindSetWindowAreas(w);
806 windSetWindowPosition(w);
807 WindMove(w, &w->w_surfaceArea);
808
809 /* Move the window to the proper depth. */
810 if (windTopWindow != (MagWindow *) NULL)
811 {
812 if (newDepth == 0)
813 {
814 switch ( WindPackageType )
815 {
816 case WIND_X_WINDOWS:
817 break;
818
819 default:
820 WindOver(w);
821 }
822 }
823 else
824 {
825 windUnlink(w);
826 w2 = windTopWindow;
827 for (i=1; i<newDepth; i++)
828 if (w2->w_nextWindow != NULL) w2 = w2->w_nextWindow;
829 w->w_nextWindow = w2->w_nextWindow;
830 w->w_prevWindow = w2;
831 w2->w_nextWindow = w;
832 if (w->w_nextWindow == NULL)
833 windBottomWindow = w;
834 else
835 w->w_nextWindow->w_prevWindow = w;
836 windReClip();
837 }
838 }
839
840 /* Notify the client. */
841 if (cr->w_reposition != NULL)
842 (*(cr->w_reposition))(w, &newFrameArea, TRUE);
843
844 /* Record new display areas. */
845 switch (WindPackageType)
846 {
847 case WIND_X_WINDOWS:
848 if (GrConfigureWindowPtr != NULL)
849 (*GrConfigureWindowPtr)(w);
850 if (GrCreateBackingStorePtr != NULL &&
851 (!(w->w_flags & WIND_OBSCURED)))
852 (*GrCreateBackingStorePtr)(w);
853 break;
854 default:
855 WindAreaChanged((MagWindow *) NULL, (Rect *) NULL);
856 }
857 }
858