(FILECREATED "17-Mar-86 16:18:17" {ERIS}<LISPCORE>SOURCES>ATTACHEDWINDOW.;21 94073  

      changes to:  (FNS ATTACHWINDOW)

      previous date: " 9-Jan-86 19:52:08" {ERIS}<LISPCORE>SOURCES>ATTACHEDWINDOW.;20)


(* Copyright (c) 1983, 1984, 1985, 1986 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT ATTACHEDWINDOWCOMS)

(RPAQQ ATTACHEDWINDOWCOMS 
       ((COMS (* User entries)
              (FNS ATTACHWINDOW ATTACHEDWINDOWS ALLATTACHEDWINDOWS DETACHWINDOW DETACHALLWINDOWS 
                   FREEATTACHEDWINDOW MAINWINDOW REMOVEWINDOW REPOSITIONATTACHEDWINDOWS))
        (FNS ATTACHEDWINDOWREGION ATTACHEDWINDOWTOTOPFN CENTERINHEIGHT CENTERINWIDTH CENTRALWINDOW 
             CLOSEATTACHEDWINDOWS DOATTACHEDWINDOWCOM DOATTACHEDWINDOWCOM2 DOMAINWINDOWCOMFN 
             EXPANDATTACHEDWINDOWS MAKEMAINWINDOW MAXATTACHEDWINDOWEXTENT MAXIMUMMAINWINDOWSIZE 
             MAXIMUMWINDOWSIZE MINATTACHEDWINDOWEXTENT MINIMUMMAINWINDOWSIZE MOVEATTACHEDWINDOWS 
             MOVEATTACHEDWINDOWTOPLACE OPENATTACHEDWINDOWS RESHAPEALLWINDOWS \TOTALPROPOSEDSIZE 
             SHRINKATTACHEDWINDOWS TOPATTACHEDWINDOWS UNMAKEMAINWINDOW UPIQUOTIENT WINDOWPOSITION 
             WINDOWSIZE \ALLOCMINIMUMSIZES \ALLOCSPACETOGROUPEDWINDOWS \TOTALFIXEDHEIGHT 
             \TOTALFIXEDWIDTH \ALLOCHEIGHTTOGROUPEDWINDOW \ALLOCWIDTHTOGROUPEDWINDOW \ATWGROUPSIZE 
             \BREAKAPARTATWSTRUCTURE \BUILDATWSTRUCTURE \LIMITBYMAX \LIMITBYMIN \MAXHEIGHTOFGROUP 
             \MAXWIDTHOFGROUP \RESHAPEATTACHEDWINDOWSAROUNDMAINW \SETGROUPMIN \SETWINFOXSIZE 
             \SETWINFOYSIZE \SHAREOFXTRAX \SHAREOFXTRAY)
        (FNS ATTACHMENU CREATEMENUEDWINDOW MENUWINDOW MENUWMINSIZEFN MENUWRESHAPEFN)
        (FNS GETPROMPTWINDOW \PROMPTWINDOW.OPENFN REATTACHPROMPTWINDOW REMOVEPROMPTWINDOW)
        (DECLARE: DONTCOPY DOEVAL@COMPILE (RECORDS RESHAPINGWINDOWDATA)
               (GLOBALVARS WindowMenu WindowTitleDisplayStream WBorder WindowMenuCommands))))



(* User entries)

(DEFINEQ

(ATTACHWINDOW
  [LAMBDA (WINDOWTOATTACH MAINWINDOW EDGE POSITIONONEDGE WINDOWCOMACTION)
                                                                           (* rrb 
                                                                           "17-Mar-86 14:01")
            
            (* attaches a window to another window.
            EDGE is one of LEFT, RIGHT, TOP or BOTTOM.
            POSITIONONEDGE is one of NIL {means reshape window to fit new main window 
            size}, {left or bottom}, {center} or {right or top}.)

    (PROG (MAINW ATTACHW)
          (SETQ MAINW (INSURE.WINDOW MAINWINDOW))
          (SETQ ATTACHW (INSURE.WINDOW WINDOWTOATTACH))
          (COND
             ((MEMB MAINW (ALLATTACHEDWINDOWS ATTACHW))
              (ERROR "attempt to create a loop in window attachment" ATTACHW)
              (RETURN)))
          (SELECTQ EDGE
              ((LEFT RIGHT TOP BOTTOM))
              (NIL (SETQ EDGE (QUOTE TOP)))
              (\ILLEGAL.ARG EDGE))
          (SELECTQ POSITIONONEDGE
              ((JUSTIFY CENTER LEFT RIGHT TOP BOTTOM))
              (NIL (SETQ POSITIONONEDGE (QUOTE JUSTIFY)))
              (\ILLEGAL.ARG POSITIONONEDGE))
          (MAKEMAINWINDOW MAINW)
          (WINDOWADDPROP MAINW (QUOTE ATTACHEDWINDOWS)
                 ATTACHW)
          (WINDOWPROP ATTACHW (QUOTE WHEREATTACHED)
                 (CONS EDGE POSITIONONEDGE))
          (WINDOWPROP ATTACHW (QUOTE MAINWINDOW)
                 MAINW)
          (WINDOWPROP ATTACHW (QUOTE TOTOPFN)
                 (FUNCTION ATTACHEDWINDOWTOTOPFN))                         (* put a property on 
                                                                           the window that will be 
                                                                           noticed by DOWINDOWCOM 
                                                                           to decide what to do 
                                                                           with window command 
                                                                           requests.)
          (WINDOWPROP ATTACHW (QUOTE DOWINDOWCOMFN)
                 (FUNCTION DOATTACHEDWINDOWCOM))
          [SELECTQ WINDOWCOMACTION
              (MAIN (WINDOWPROP ATTACHW (QUOTE PASSTOMAINCOMS)
                           T))
              (HERE                                                        (* leave it alone)
                    (WINDOWPROP ATTACHW (QUOTE PASSTOMAINCOMS)
                           NIL))
              (LOCALCLOSE                                                  (* set up so that 
                                                                           closing is handled 
                                                                           locally and detaches 
                                                                           the window.)
                          (WINDOWADDPROP ATTACHW (QUOTE CLOSEFN)
                                 (FUNCTION DETACHWINDOW))
                          (WINDOWPROP ATTACHW (QUOTE PASSTOMAINCOMS)
                                 (QUOTE (MOVEW SHAPEW SHRINKW BURYW))))
              (WINDOWPROP ATTACHW (QUOTE PASSTOMAINCOMS)
                     (QUOTE (CLOSEW MOVEW SHAPEW SHRINKW BURYW]
          (MOVEATTACHEDWINDOWTOPLACE ATTACHW MAINW EDGE POSITIONONEDGE)
          (RETURN MAINW])

(ATTACHEDWINDOWS
  [LAMBDA (WINDOW COM)                                       (* jow "26-Aug-85 12:02")

          (* Returns the list of windows attached to this window. COM can be a window command, only the attached windows who 
	  allow this COM to be applied to them from above will be returned. An attached window can have a ALLOWMAINCOMS prop, 
	  which is a list of allowable commands. If ALLOWMAINCOMS is NIL, all commands are allowed. If COM is not given, all 
	  attached windows are returned.)


    (for ATTW in (WINDOWPROP WINDOW (QUOTE ATTACHEDWINDOWS)) collect ATTW
       when (OR (NOT (WINDOWPROP ATTW (QUOTE REJECTMAINCOMS)))
		(NOT COM)
		(NOT (MEMB COM (WINDOWPROP ATTW (QUOTE REJECTMAINCOMS])

(ALLATTACHEDWINDOWS
  [LAMBDA (MAINW)                                            (* rrb "30-NOV-83 16:29")
                                                             (* returns a list of all of the windows attached to 
							     MAINW or any of its attached windows.)
    (PROG ((ATWS (ATTACHEDWINDOWS MAINW)))
          (RETURN (COND
		    (ATWS (APPEND ATWS (for ATW in ATWS join (ALLATTACHEDWINDOWS ATW])

(DETACHWINDOW
  [LAMBDA (WINDOWTODETACH)                                   (* bvm: "11-Nov-84 15:48")
                                                             (* detaches a window from its main window.)
    (PROG ((WHEREAT (WINDOWPROP WINDOWTODETACH (QUOTE WHEREATTACHED)
				NIL))
	   (MAINW (WINDOWPROP WINDOWTODETACH (QUOTE MAINWINDOW)
			      NIL))
	   ATWINS PWINDOW OLDFN)
          (OR MAINW (RETURN NIL))
          (WINDOWDELPROP MAINW (QUOTE ATTACHEDWINDOWS)
			 WINDOWTODETACH)
          (COND
	    ((NOT (ATTACHEDWINDOWS MAINW))
	      (UNMAKEMAINWINDOW MAINW)))
          (SELECTQ (SETQ OLDFN (WINDOWPROP WINDOWTODETACH (QUOTE DOWINDOWCOMFN)
					   NIL))
		   ((DOMAINWINDOWCOMFN DOATTACHEDWINDOWCOM))
		   (WINDOWPROP WINDOWTODETACH (QUOTE DOWINDOWCOMFN)
			       OLDFN))                       (* Remove window's TOTOPFN and DOWINDOWCOMFN if they 
							     were the ones that ATTACHWINDOW put there)
          (SELECTQ (SETQ OLDFN (WINDOWPROP WINDOWTODETACH (QUOTE TOTOPFN)
					   NIL))
		   (ATTACHEDWINDOWTOTOPFN)
		   (WINDOWPROP WINDOWTODETACH (QUOTE TOTOPFN)
			       OLDFN))
          (RETURN WHEREAT])

(DETACHALLWINDOWS
  [LAMBDA (MAINWINDOW)                                       (* bvm: "11-Nov-84 16:19")
    (REMOVEPROMPTWINDOW MAINWINDOW)                          (* Do this separately so that prompt window is 
							     "permanently" removed, not just locally closed)
    (for W in (WINDOWPROP MAINWINDOW (QUOTE ATTACHEDWINDOWS))
       do (DETACHWINDOW W)
	  (CLOSEW W])

(FREEATTACHEDWINDOW
  [LAMBDA (WINDOW)                                           (* jow "16-Aug-85 14:35")

          (* frees an attached window and snuggles any other attached windows closer to the main window.
	  Only the windows that allowed MOVEW will be snuggled.)


    (LET* [(MAINWINDOW (MAINWINDOW WINDOW))
	   [ATWINS (COPY (ATTACHEDWINDOWS MAINWINDOW (QUOTE MOVEW]
	   (REGION (WINDOWPROP WINDOW (QUOTE REGION)))
	   (BOTTOM (fetch (REGION BOTTOM) of REGION))
	   (HEIGHT (fetch (REGION HEIGHT) of REGION))
	   (EDGE (CAR (WINDOWPROP WINDOW (QUOTE WHEREATTACHED]
          (DETACHWINDOW WINDOW)
          (SELECTQ EDGE
		   [TOP (for ATWIN in ATWINS when (IGREATERP (fetch (REGION BOTTOM)
								of (WINDOWPROP ATWIN (QUOTE REGION)))
							     BOTTOM)
			   do (RELMOVEW ATWIN (create POSITION
						      XCOORD ← 0
						      YCOORD ←(IMINUS HEIGHT]
		   [BOTTOM (for ATWIN in ATWINS when (ILESSP (fetch (REGION BOTTOM)
								of (WINDOWPROP ATWIN (QUOTE REGION)))
							     BOTTOM)
			      do (RELMOVEW ATWIN (create POSITION
							 XCOORD ← 0
							 YCOORD ← HEIGHT]
		   NIL])

(MAINWINDOW
  [LAMBDA (WINDOW RECURSEFLG)                                (* rrb "20-Aug-84 09:45")

          (* * returns the main window of a window. If recurseflg is T, continues until it finds a window not attached to 
	  any other.)


    (PROG ((WIN (\INSUREWINDOW WINDOW))
	   MAINW)
          (COND
	    ([NULL (SETQ MAINW (WINDOWPROP WIN (QUOTE MAINWINDOW]
	      (RETURN WIN))
	    ((NULL RECURSEFLG)
	      (RETURN MAINW)))
      LP  (COND
	    ([NULL (SETQ WIN (WINDOWPROP MAINW (QUOTE MAINWINDOW]
	      (RETURN MAINW))
	    (T (SETQ MAINW WIN)
	       (GO LP])

(REMOVEWINDOW
  [LAMBDA (WINDOW)                                           (* jow "16-Aug-85 14:37")
                                                             (* Closes an attached window and then calls 
							     FREEATTACHEDWINDOW to snuggle up other windows)
    (CLOSEW WINDOW)
    (FREEATTACHEDWINDOW WINDOW])

(REPOSITIONATTACHEDWINDOWS
  [LAMBDA (WINDOW)                                           (* jow "16-Aug-85 14:57")

          (* can be a main window's RESHAPEFN. used when some attached windows don't want to be reshaped, but do want to be 
	  repositioned after a reshape.)


    (for ATTW in (ATTACHEDWINDOWS WINDOW (QUOTE MOVEW)) do (MOVEATTACHEDWINDOWTOPLACE ATTW WINDOW])
)
(DEFINEQ

(ATTACHEDWINDOWREGION
  [LAMBDA (MAINW COM)                                        (* jow "15-Aug-85 13:08")

          (* returns the region of the area taken up by a window and all of its attached windows. COM can be the command that 
	  this region is being calculated for, and is passed to ATTACHEDWINDOWS so windows can except themselves.)


    (PROG [(REG (WINDOWPROP MAINW (QUOTE REGION]
          [for ATWIN in (ATTACHEDWINDOWS MAINW COM) do (SETQ REG (UNIONREGIONS REG (WINDOWREGION
										 ATWIN]
          (RETURN REG])

(ATTACHEDWINDOWTOTOPFN
  [LAMBDA (WINDOW)                                           (* rrb "26-OCT-83 14:09")
                                                             (* This function causes both the main window and its 
							     attached windows to be visible when either is selected)
    (PROG (W)
          (COND
	    ([WINDOWP (SETQ W (WINDOWPROP WINDOW (QUOTE MAINWINDOW]
	      (TOTOPW W])

(CENTERINHEIGHT
  [LAMBDA (HEIGHTTOCENTER RELATIVETOREGION)                  (* rrb "15-NOV-83 13:45")
                                                             (* returns the bottom coordinate that a height needs to 
							     be centered relative to a region.)
    (PLUS (fetch (REGION LEFT) of RELATIVETOREGION)
	  (IQUOTIENT (DIFFERENCE (fetch (REGION HEIGHT) of RELATIVETOREGION)
				 HEIGHTTOCENTER)
		     2])

(CENTERINWIDTH
  [LAMBDA (WIDTHTOCENTER RELATIVETOREGION)                   (* rrb "15-NOV-83 13:21")
                                                             (* returns the left coordinate that a width needs to be 
							     centered relative to a region.)
    (PLUS (fetch (REGION LEFT) of RELATIVETOREGION)
	  (IQUOTIENT (DIFFERENCE (fetch (REGION WIDTH) of RELATIVETOREGION)
				 WIDTHTOCENTER)
		     2])

(CENTRALWINDOW
  [LAMBDA (WINDOW)                                           (* rrb "30-Dec-83 13:59")
                                                             (* returns the window that is a main window to this one 
							     and is not itself attached to any other.)
    (PROG (MAINW)
      LP  (COND
	    ((SETQ MAINW (WINDOWPROP WINDOW (QUOTE MAINWINDOW)))
	      (SETQ WINDOW MAINW)
	      (GO LP)))
          (RETURN WINDOW])

(CLOSEATTACHEDWINDOWS
  [LAMBDA (WINDOW)                                           (* jow "15-Aug-85 13:02")
                                                             (* propagates closing to attached windows.)
    (for ATTACHEDWINDOW in (ATTACHEDWINDOWS WINDOW (QUOTE CLOSEW))
       do (CLOSEW ATTACHEDWINDOW)
	  (WINDOWPROP ATTACHEDWINDOW (QUOTE MAINWINDOW)
		      NIL])

(DOATTACHEDWINDOWCOM
  [LAMBDA (ATTACHEDW)                                        (* jow " 7-Sep-85 23:03")

          (* a right button function for attached windows that brings up the window command menu and then, depending upon the 
	  command selected, either passes the command to the main window or performs it on the attached window.
	  The commands in the windowprop PASSTOMAINCOMS are passed to the central window. Others are applied to ATTACHEDW.)


    (COND
      [(WINDOWP ATTACHEDW)
	(PROG (COM)
	      (TOTOPW ATTACHEDW)
	      (RETURN (COND
			([SETQ COM
			    (MENU (COND
				    ((type? MENU WindowMenu)
				      WindowMenu)
				    (T (SETQ WindowMenu
					 (create MENU
						 ITEMS ← WindowMenuCommands
						 CHANGEOFFSETFLG ←(QUOTE Y)
						 MENUOFFSET ←(create POSITION
								     XCOORD ← -1
								     YCOORD ← 0)
						 WHENHELDFN ←(FUNCTION PPROMPT3)
						 WHENUNHELDFN ←(FUNCTION CLRPROMPT)
						 CENTERFLG ← T]
			  (if [OR (EQ (WINDOWPROP ATTACHEDW (QUOTE PASSTOMAINCOMS))
				      T)
				  (MEMB COM (WINDOWPROP ATTACHEDW (QUOTE PASSTOMAINCOMS]
			      then (APPLY* COM (CENTRALWINDOW ATTACHEDW))
			    else (APPLY* COM ATTACHEDW))
			  T]
      ((NULL ATTACHEDW)
	(DOBACKGROUNDCOM])

(DOATTACHEDWINDOWCOM2
  [LAMBDA (ATTACHEDW)                                        (* rrb "28-Mar-84 11:25")
                                                             (* a right button function for attached windows that 
							     want to handle CLOSE locally.)
    (DOATTACHEDWINDOWCOM ATTACHEDW T])

(DOMAINWINDOWCOMFN
  [LAMBDA (ATTACHEDW)                                        (* rrb "10-Dec-83 14:57")
                                                             (* applies the right button function of the main 
							     window.)
    (PROG (MAINW)
          (RETURN (APPLY* (OR (WINDOWPROP (SETQ MAINW (WINDOWPROP ATTACHEDW (QUOTE MAINWINDOW)))
					  (QUOTE RIGHTBUTTONFN))
			      (FUNCTION DOWINDOWCOM))
			  MAINW])

(EXPANDATTACHEDWINDOWS
  [LAMBDA (WINDOW)                                           (* jow "15-Aug-85 13:03")
                                                             (* propagates expanding to attached windows.)
                                                             (* doesn't allow the attached window functions to stop 
							     the expanding.)
    (for ATTACHEDWINDOW in (ATTACHEDWINDOWS WINDOW (QUOTE EXPANDW))
       do (DOUSERFNS (WINDOWPROP ATTACHEDWINDOW (QUOTE EXPANDFN))
		     ATTACHEDWINDOW)                         (* the expandfn may have opened the window.)
	  (OR (OPENWP ATTACHEDWINDOW)
	      (\OPENW1 ATTACHEDWINDOW])

(MAKEMAINWINDOW
  [LAMBDA (MAINWINDOW)                                       (* jow "15-Aug-85 13:23")
                                                             (* puts the necessary functions on a window to 
							     propagate its activities to all of its attached 
							     windows.)
                                                             (* has functions for moving, reshaping, totoping)
    (WINDOWADDPROP MAINWINDOW (QUOTE TOTOPFN)
		   (FUNCTION TOPATTACHEDWINDOWS))
    (WINDOWADDPROP MAINWINDOW (QUOTE CLOSEFN)
		   (FUNCTION CLOSEATTACHEDWINDOWS))
    (WINDOWADDPROP MAINWINDOW (QUOTE OPENFN)
		   (FUNCTION OPENATTACHEDWINDOWS))
    (WINDOWADDPROP MAINWINDOW (QUOTE SHRINKFN)
		   (FUNCTION SHRINKATTACHEDWINDOWS))
    (WINDOWADDPROP MAINWINDOW (QUOTE EXPANDFN)
		   (FUNCTION EXPANDATTACHEDWINDOWS))
    (WINDOWPROP MAINWINDOW (QUOTE CALCULATEREGIONFN)
		(FUNCTION ATTACHEDWINDOWREGION))
    [PROG [(OLDMINSIZE (WINDOWPROP MAINWINDOW (QUOTE MINSIZE)))
	   (OLDMAXSIZE (WINDOWPROP MAINWINDOW (QUOTE MAXSIZE]
                                                             (* move this windows minsize function and maxsize onto 
							     a different place.)
          (COND
	    ((AND OLDMINSIZE (NEQ OLDMINSIZE (FUNCTION MINATTACHEDWINDOWEXTENT)))
	      (WINDOWPROP MAINWINDOW (QUOTE MAINWINDOWMINSIZE)
			  OLDMINSIZE)))
          (COND
	    ((AND OLDMAXSIZE (NEQ OLDMAXSIZE (FUNCTION MAXATTACHEDWINDOWEXTENT)))
	      (WINDOWPROP MAINWINDOW (QUOTE MAINWINDOWMAXSIZE)
			  OLDMAXSIZE]
    (WINDOWPROP MAINWINDOW (QUOTE MINSIZE)
		(FUNCTION MINATTACHEDWINDOWEXTENT))
    (WINDOWPROP MAINWINDOW (QUOTE MAXSIZE)
		(FUNCTION MAXATTACHEDWINDOWEXTENT))
    (WINDOWADDPROP MAINWINDOW (QUOTE MOVEFN)
		   (FUNCTION MOVEATTACHEDWINDOWS))
    (WINDOWPROP MAINWINDOW (QUOTE DOSHAPEFN)
		(FUNCTION RESHAPEALLWINDOWS])

(MAXATTACHEDWINDOWEXTENT
  [LAMBDA (MAINW)                                            (* bvm: "29-Dec-83 15:57")
                                                             (* returns the maximum extent of a window computing it 
							     from the attached windows if necessary.)
    (PROG ((ATWS (ATTACHEDWINDOWS MAINW))
	   (EXTENT (MAXIMUMMAINWINDOWSIZE MAINW))
	   TL TC TR RT RC RB BR BC BL LB LC LT)
          [COND
	    ((NULL ATWS)
	      (RETURN EXTENT))
	    ((NULL EXTENT)                                   (* if the main window is willing to expand, start with a
							     large maximum)
	      (RETURN (SETQ EXTENT (CONS 64000 64000]
          [SETQ TL (SETQ TC (SETQ TR (CDR EXTENT]
          [SETQ RT (SETQ RC (SETQ RB (CAR EXTENT]
          (SETQ BR (SETQ BC (SETQ BL 0)))
          (SETQ LB (SETQ LC (SETQ LT 0)))
          (bind ATWHERE WHERECODE ATWDTH ATWHGHT for ATW in ATWS
	     do                                              (* go through the attached windows keeping track of 
							     their effect on the extent.)
		(SETQ EXTENT (MAXIMUMWINDOWSIZE ATW))
		(SETQ ATWDTH (OR (CAR EXTENT)
				 64000))
		(SETQ ATWHGHT (OR (CDR EXTENT)
				  64000))
		(SETQ WHERECODE (SELECTQ [CDR (SETQ ATWHERE (WINDOWPROP ATW (QUOTE WHEREATTACHED]
					 (JUSTIFY (QUOTE JUSTIFY))
					 (CENTER 0)
					 ((LEFT BOTTOM)
					   -1)
					 1))
		(SELECTQ (CAR ATWHERE)
			 (TOP [COND
				((GREATERP ATWDTH (DIFFERENCE RT LT))

          (* check to see if min width pushes the width. This could push either way and is actually not right because a 
	  later window on the left or right top could use this extra.)


				  (SETQ RT (PLUS ATWDTH LT]
			      (SELECTQ WHERECODE
				       [JUSTIFY (SETQ TL (SETQ TC (SETQ TR
						      (PLUS (MAX TL TC TR)
							    ATWHGHT]
				       (-1 (SETQ TL (PLUS TL ATWHGHT)))
				       (0 (SETQ TC (PLUS TC ATWHGHT)))
				       (1 (SETQ TR (PLUS TR ATWHGHT)))
				       (SHOULDNT)))
			 (RIGHT [COND
				  ((GREATERP ATWHGHT (DIFFERENCE TR BR))
				    (SETQ TR (PLUS ATWHGHT BR]
				(SELECTQ WHERECODE
					 [JUSTIFY (SETQ RT (SETQ RC (SETQ RB
							(PLUS (MAX RT RC RB)
							      ATWDTH]
					 (1 (SETQ RT (PLUS RT ATWDTH)))
					 (0 (SETQ RC (PLUS RC ATWDTH)))
					 (-1 (SETQ RB (PLUS RB ATWDTH)))
					 (SHOULDNT)))
			 (LEFT [COND
				 ((GREATERP ATWHGHT (DIFFERENCE TL BL))
				   (SETQ TL (PLUS ATWHGHT BL]
			       (SELECTQ WHERECODE
					[JUSTIFY (SETQ LT (SETQ LC (SETQ LB
						       (DIFFERENCE (MIN LT LC LB)
								   ATWDTH]
					(1 (SETQ LT (DIFFERENCE LT ATWDTH)))
					(0 (SETQ LC (DIFFERENCE LC ATWDTH)))
					(-1 (SETQ LB (DIFFERENCE LB ATWDTH)))
					(SHOULDNT)))
			 (BOTTOM [COND
				   ((GREATERP ATWDTH (DIFFERENCE RB LB))
				     (SETQ RB (PLUS ATWDTH LB]
				 (SELECTQ WHERECODE
					  [JUSTIFY (SETQ BL (SETQ BC (SETQ BR
							 (DIFFERENCE (MIN BL BC BR)
								     ATWHGHT]
					  (-1 (SETQ BL (DIFFERENCE BL ATWHGHT)))
					  (0 (SETQ BC (DIFFERENCE BC ATWHGHT)))
					  (1 (SETQ BR (DIFFERENCE BR ATWHGHT)))
					  (SHOULDNT)))
			 (SHOULDNT)))
          (RETURN (CONS (DIFFERENCE (MAX RT RC RB)
				    (MIN LT LC LB))
			(DIFFERENCE (MAX TL TC TR)
				    (MIN BL BC BR])

(MAXIMUMMAINWINDOWSIZE
  [LAMBDA (WINDOW)                                           (* bvm: "29-Dec-83 15:46")
                                                             (* returns the maximum extent of a main window)
    (PROG [(EXT (WINDOWPROP WINDOW (QUOTE MAINWINDOWMAXSIZE]
          [COND
	    ((NULL EXT)
	      (RETURN NIL))
	    ((LITATOM EXT)
	      (SETQ EXT (APPLY* EXT WINDOW]
          [COND
	    [(AND (NUMBERP (CAR EXT))
		  (NUMBERP (CDR EXT]
	    (T (SETQ EXT (ERROR "Illegal maximum size property" EXT]
          (RETURN EXT])

(MAXIMUMWINDOWSIZE
  [LAMBDA (WINDOW)                                           (* rrb "19-Mar-84 14:23")
                                                             (* returns the maximum extent of a window)
    (PROG [(EXT (WINDOWPROP WINDOW (QUOTE MAXSIZE]
          [COND
	    ((NULL EXT)
	      (RETURN NIL))
	    ((LITATOM EXT)
	      (SETQ EXT (APPLY* EXT WINDOW]
          [COND
	    [(AND (OR (NULL (CAR EXT))
		      (NUMBERP (CAR EXT)))
		  (OR (NULL (CDR EXT))
		      (NUMBERP (CDR EXT]
	    (EXT (SETQ EXT (ERROR "Illegal extent property" EXT]
          (RETURN EXT])

(MINATTACHEDWINDOWEXTENT
  [LAMBDA (MAINW)                                            (* rrb "15-Dec-83 10:16")
                                                             (* returns the extent of a window computing it from the 
							     attached windows if necessary.)
    (PROG ((ATWS (ATTACHEDWINDOWS MAINW))
	   (EXTENT (MINIMUMMAINWINDOWSIZE MAINW))
	   TL TC TR RT RC RB BR BC BL LB LC LT)
          (COND
	    ((NULL ATWS)
	      (RETURN EXTENT)))
          [SETQ TL (SETQ TC (SETQ TR (CDR EXTENT]
          [SETQ RT (SETQ RC (SETQ RB (CAR EXTENT]
          (SETQ BR (SETQ BC (SETQ BL 0)))
          (SETQ LB (SETQ LC (SETQ LT 0)))
          (bind ATWHERE WHERECODE ATWDTH ATWHGHT for ATW in ATWS
	     do                                              (* go through the attached windows keeping track of 
							     their effect on the extent.)
		(SETQ EXTENT (MINIMUMWINDOWSIZE ATW))
		(SETQ ATWDTH (CAR EXTENT))
		(SETQ ATWHGHT (CDR EXTENT))
		(SETQ WHERECODE (SELECTQ [CDR (SETQ ATWHERE (WINDOWPROP ATW (QUOTE WHEREATTACHED]
					 (JUSTIFY (QUOTE JUSTIFY))
					 (CENTER 0)
					 ((LEFT BOTTOM)
					   -1)
					 1))
		(SELECTQ (CAR ATWHERE)
			 (TOP [COND
				((GREATERP ATWDTH (DIFFERENCE RT LT))

          (* check to see if min width pushes the width. This could push either way and is actually not right because a 
	  later window on the left or right top could use this extra.)


				  (SETQ RT (PLUS ATWDTH LT]
			      (SELECTQ WHERECODE
				       [JUSTIFY (SETQ TL (SETQ TC (SETQ TR
						      (PLUS (MAX TL TC TR)
							    ATWHGHT]
				       (-1 (SETQ TL (PLUS TL ATWHGHT)))
				       (0 (SETQ TC (PLUS TC ATWHGHT)))
				       (1 (SETQ TR (PLUS TR ATWHGHT)))
				       (SHOULDNT)))
			 (RIGHT [COND
				  ((GREATERP ATWHGHT (DIFFERENCE TR BR))
				    (SETQ TR (PLUS ATWHGHT BR]
				(SELECTQ WHERECODE
					 [JUSTIFY (SETQ RT (SETQ RC (SETQ RB
							(PLUS (MAX RT RC RB)
							      ATWDTH]
					 (1 (SETQ RT (PLUS RT ATWDTH)))
					 (0 (SETQ RC (PLUS RC ATWDTH)))
					 (-1 (SETQ RB (PLUS RB ATWDTH)))
					 (SHOULDNT)))
			 (LEFT [COND
				 ((GREATERP ATWHGHT (DIFFERENCE TL BL))
				   (SETQ TL (PLUS ATWHGHT BL]
			       (SELECTQ WHERECODE
					[JUSTIFY (SETQ LT (SETQ LC (SETQ LB
						       (DIFFERENCE (MIN LT LC LB)
								   ATWDTH]
					(1 (SETQ LT (DIFFERENCE LT ATWDTH)))
					(0 (SETQ LC (DIFFERENCE LC ATWDTH)))
					(-1 (SETQ LB (DIFFERENCE LB ATWDTH)))
					(SHOULDNT)))
			 (BOTTOM [COND
				   ((GREATERP ATWDTH (DIFFERENCE RB LB))
				     (SETQ RB (PLUS ATWDTH LB]
				 (SELECTQ WHERECODE
					  [JUSTIFY (SETQ BL (SETQ BC (SETQ BR
							 (DIFFERENCE (MIN BL BC BR)
								     ATWHGHT]
					  (-1 (SETQ BL (DIFFERENCE BL ATWHGHT)))
					  (0 (SETQ BC (DIFFERENCE BC ATWHGHT)))
					  (1 (SETQ BR (DIFFERENCE BR ATWHGHT)))
					  (SHOULDNT)))
			 (SHOULDNT)))
          (RETURN (CONS (DIFFERENCE (MAX RT RC RB)
				    (MIN LT LC LB))
			(DIFFERENCE (MAX TL TC TR)
				    (MIN BL BC BR])

(MINIMUMMAINWINDOWSIZE
  [LAMBDA (WINDOW)                                           (* rrb "13-Dec-83 10:15")
                                                             (* returns the minimum extent of a window)
    (PROG ((EXT (WINDOWPROP WINDOW (QUOTE MAINWINDOWMINSIZE)))
	   (MinWindowWidth 26))
          [COND
	    [(NULL EXT)
	      (SETQ EXT (CONS MinWindowWidth (HEIGHTIFWINDOW (FONTPROP WINDOW (QUOTE HEIGHT))
							     (WINDOWPROP WINDOW (QUOTE TITLE]
	    ((LITATOM EXT)
	      (SETQ EXT (APPLY* EXT WINDOW]
          [COND
	    [(AND (NUMBERP (CAR EXT))
		  (NUMBERP (CDR EXT]
	    (T (SETQ EXT (ERROR "Illegal extent property" EXT]
          (RETURN EXT])

(MOVEATTACHEDWINDOWS
  [LAMBDA (WINDOW NEWPOS)                                    (* jow "15-Aug-85 13:23")
                                                             (* propagates moving to attached windows.)
    (PROG [(DELTA (PTDIFFERENCE NEWPOS (WINDOWPOSITION WINDOW]
          (for ATTACHEDWINDOW in (ATTACHEDWINDOWS WINDOW (QUOTE MOVEW))
	     do (MOVEW ATTACHEDWINDOW (PTPLUS (WINDOWPOSITION ATTACHEDWINDOW)
					      DELTA])

(MOVEATTACHEDWINDOWTOPLACE
  [LAMBDA (ATWIN MAINW EDGE POSONEDGE)                       (* DECLARATIONS: (RECORD ATTACHEDWINDATA 
							     ((EDGE . WHEREONEDGE) WID . HGHT)))
                                                             (* jow " 7-Sep-85 22:18")
                                                             (* moves a window to the place it should be relative to
							     MAINW and reshapes it if it is JUSTIFY.)
    (PROG (MAINWEXTENT EXTENT ATMINWIDTH ATMINHEIGHT ATWHGHT ATWDTH TL TC TR RT RC RB BR BC BL LB LC 
		       LT)
          [COND
	    ((NULL EDGE)
	      (SETQ EDGE (WINDOWPROP ATWIN (QUOTE WHEREATTACHED)))
	      (SETQ POSONEDGE (CDR EDGE))
	      (SETQ EDGE (CAR EDGE]                          (* calculate the minimum so that this window won't be 
							     reshaped smaller than its minimum.)
          [SETQ ATMINHEIGHT (CDR (SETQ ATMINWIDTH (MINIMUMWINDOWSIZE ATWIN]
          (SETQ ATMINWIDTH (CAR ATMINWIDTH))
          (SETQ POSONEDGE (SELECTQ POSONEDGE
				   (JUSTIFY (QUOTE JUSTIFY))
				   (CENTER 0)
				   ((LEFT BOTTOM)
				     -1)
				   1))
          (SETQ MAINWEXTENT (WINDOWPROP MAINW (QUOTE REGION)))

          (* the extent of a group of windows is thought of as its maximum extent along each edge and each position on that 
	  edge eg. top-left, top-center, top-right. A justify takes the maximum of the three positions along that edge.)


          [SETQ TL (SETQ TC (SETQ TR (fetch (REGION TOP) of MAINWEXTENT]
          [SETQ RT (SETQ RC (SETQ RB (fetch (REGION RIGHT) of MAINWEXTENT]
          [SETQ BR (SETQ BC (SETQ BL (fetch (REGION BOTTOM) of MAINWEXTENT]
          [SETQ LB (SETQ LC (SETQ LT (fetch (REGION LEFT) of MAINWEXTENT]
          (bind ATWHERE ATPOSONEDGE ATWREG for ATW in (ATTACHEDWINDOWS MAINW)
	     until (EQ ATW ATWIN)
	     do                                              (* go through the attached windows keeping track of 
							     their effect on the position.
							     Only consider windows attached to MAINW before ATWIN.)
		(SETQ ATWREG (WINDOWREGION ATW))
		(SETQ ATWHGHT (fetch (REGION HEIGHT) of ATWREG))
		(SETQ ATWDTH (fetch (REGION WIDTH) of ATWREG))
		(SETQ ATPOSONEDGE (SELECTQ [CDR (SETQ ATWHERE (WINDOWPROP ATW (QUOTE WHEREATTACHED]
					   (JUSTIFY (QUOTE JUSTIFY))
					   (CENTER 0)
					   ((LEFT BOTTOM)
					     -1)
					   1))
		(SELECTQ (CAR ATWHERE)
			 (TOP (SELECTQ ATPOSONEDGE
				       [JUSTIFY (SETQ TL (SETQ TC (SETQ TR
						      (PLUS (MAX TL TC TR)
							    ATWHGHT]
				       (-1 (SETQ TL (PLUS TL ATWHGHT)))
				       (0 (SETQ TC (PLUS TC ATWHGHT)))
				       (1 (SETQ TR (PLUS TR ATWHGHT)))
				       (SHOULDNT)))
			 (RIGHT (SELECTQ ATPOSONEDGE
					 [JUSTIFY (SETQ RT (SETQ RC (SETQ RB
							(PLUS (MAX RT RC RB)
							      ATWDTH]
					 (1 (SETQ RT (PLUS RT ATWDTH)))
					 (0 (SETQ RC (PLUS RC ATWDTH)))
					 (-1 (SETQ RB (PLUS RB ATWDTH)))
					 (SHOULDNT)))
			 (LEFT (SELECTQ ATPOSONEDGE
					[JUSTIFY (SETQ LT (SETQ LC (SETQ LB
						       (DIFFERENCE (MIN LT LC LB)
								   ATWDTH]
					(1 (SETQ LT (DIFFERENCE LT ATWDTH)))
					(0 (SETQ LC (DIFFERENCE LC ATWDTH)))
					(-1 (SETQ LB (DIFFERENCE LB ATWDTH)))
					(SHOULDNT)))
			 (BOTTOM (SELECTQ ATPOSONEDGE
					  [JUSTIFY (SETQ BL (SETQ BC (SETQ BR
							 (DIFFERENCE (MAX BL BC BR)
								     ATWHGHT]
					  (-1 (SETQ BL (DIFFERENCE BL ATWHGHT)))
					  (0 (SETQ BC (DIFFERENCE BC ATWHGHT)))
					  (1 (SETQ BR (DIFFERENCE BR ATWHGHT)))
					  (SHOULDNT)))
			 (SHOULDNT)))                        (* now position the window)
          (SETQ EXTENT (WINDOWREGION ATWIN))
          (SETQ ATWHGHT (fetch (REGION HEIGHT) of EXTENT))
          (SETQ ATWDTH (fetch (REGION WIDTH) of EXTENT))
          (COND
	    ((EQ POSONEDGE (QUOTE JUSTIFY))
	      (SHAPEW ATWIN (SELECTQ EDGE
				     (TOP (CREATEREGION LT (ADD1 (MAX TL TC TR))
							(IMAX (ADD1 (DIFFERENCE RT LT))
							      ATMINWIDTH)
							ATWHGHT))
				     (RIGHT (CREATEREGION (ADD1 (MAX RT RC RB))
							  BR ATWDTH (IMAX (ADD1 (DIFFERENCE TR BR))
									  ATMINHEIGHT)))
				     (LEFT (CREATEREGION (DIFFERENCE (MIN LT LC LB)
								     ATWDTH)
							 BL ATWDTH (IMAX (ADD1 (DIFFERENCE TL BL))
									 ATMINHEIGHT)))
				     (BOTTOM (CREATEREGION LB (DIFFERENCE (MIN BL BC BR)
									  ATWHGHT)
							   (IMAX (ADD1 (DIFFERENCE RB LB))
								 ATMINWIDTH)
							   ATWHGHT))
				     NIL)))
	    (T (SELECTQ EDGE
			[TOP (SELECTQ POSONEDGE
				      (1 (MOVEW ATWIN (ADD1 (DIFFERENCE RT ATWDTH))
						(ADD1 TR)))
				      (0 (MOVEW ATWIN (CENTERINWIDTH ATWDTH MAINWEXTENT)
						(ADD1 TC)))
				      (MOVEW ATWIN LT (ADD1 TL]
			(RIGHT (SELECTQ POSONEDGE
					[1 (MOVEW ATWIN (ADD1 RT)
						  (ADD1 (DIFFERENCE TR ATWHGHT]
					(0 (MOVEW ATWIN (ADD1 RC)
						  (CENTERINHEIGHT ATWHGHT MAINWEXTENT)))
					(MOVEW ATWIN (ADD1 RB)
					       BR)))
			(LEFT (SELECTQ POSONEDGE
				       [1 (MOVEW ATWIN (DIFFERENCE LT ATWDTH)
						 (ADD1 (DIFFERENCE TL ATWHGHT]
				       (0 (MOVEW ATWIN (DIFFERENCE LC ATWDTH)
						 (CENTERINHEIGHT ATWHGHT MAINWEXTENT)))
				       (MOVEW ATWIN (DIFFERENCE LB ATWDTH)
					      BL)))
			[BOTTOM (SELECTQ POSONEDGE
					 (1 (MOVEW ATWIN (ADD1 (DIFFERENCE RB ATWDTH))
						   (DIFFERENCE BR ATWHGHT)))
					 (0 (MOVEW ATWIN (CENTERINWIDTH ATWDTH MAINWEXTENT)
						   (DIFFERENCE BC ATWHGHT)))
					 (MOVEW ATWIN LB (DIFFERENCE BL ATWHGHT]
			NIL])

(OPENATTACHEDWINDOWS
  [LAMBDA (WINDOW)                                           (* jow "15-Aug-85 13:03")
                                                             (* propagates opening to attached windows.)
    (for ATTACHEDWINDOW in (ATTACHEDWINDOWS WINDOW (QUOTE OPENW))
       do                                                    (* reestablish the link from the attached window and 
							     the main window.)
	  (WINDOWPROP ATTACHEDWINDOW (QUOTE MAINWINDOW)
		      WINDOW)
	  (OPENW ATTACHEDWINDOW])

(RESHAPEALLWINDOWS
  [LAMBDA (MAINW NEWREGION)                                  (* rrb " 8-Jan-86 11:36")
                                                             (* reshapes all of the windows in a group.)
                                                             (* calculate all of the attached window sizes)
    (PROG ((ATWINS (ATTACHEDWINDOWS MAINW (QUOTE SHAPEW)))
	     (MWXOFF 0)
	     (MWYOFF 0)
	     (NEWWIDTH (fetch (REGION WIDTH) of NEWREGION))
	     (NEWHEIGHT (fetch (REGION HEIGHT) of NEWREGION))
	     FIXEDVAR TOTALNOWSIZE EXPANSIONWIDTH EXPANSIONHEIGHT NEWEXPANDABLEWIDTH 
	     NEWEXPANDABLEHEIGHT ATWINSINFO EXCESS NOW)
	    [COND
	      ((NULL ATWINS)
		(RETURN (SHAPEW1 MAINW NEWREGION]
	    (SETQ TOTALNOWSIZE (WINDOWSIZE MAINW))

          (* calculate the amount of the total size that is available to change. This ignores the case where a window can 
	  only expand 5 but its share would be 10 but it is easy and better than nothing.)


	    (SETQ ATWINSINFO (\BUILDATWSTRUCTURE MAINW ATWINS))
	    (\ALLOCMINIMUMSIZES ATWINSINFO 0 0)
	    [SETQ EXPANSIONWIDTH (IDIFFERENCE (CAR TOTALNOWSIZE)
						  (SETQ FIXEDVAR (\TOTALFIXEDWIDTH ATWINSINFO]
	    (SETQ NEWEXPANDABLEWIDTH (IMAX (DIFFERENCE NEWWIDTH FIXEDVAR)
					       0))
	    [SETQ EXPANSIONHEIGHT (IDIFFERENCE (CDR TOTALNOWSIZE)
						   (SETQ FIXEDVAR (\TOTALFIXEDHEIGHT ATWINSINFO]
	    (SETQ NEWEXPANDABLEHEIGHT (IMAX (DIFFERENCE NEWHEIGHT FIXEDVAR)
						0))

          (* make a pass through allocating each window a portion of the space that is in excess of the minimum.
	  In this pass, the grouped windows are treated as a whole.)


	    (for ATWINFO in ATWINSINFO
	       do (\SETWINFOXSIZE ATWINFO (\SHAREOFXTRAX ATWINFO NEWEXPANDABLEWIDTH 
							       EXPANSIONWIDTH))
		    (\SETWINFOYSIZE ATWINFO (\SHAREOFXTRAY ATWINFO NEWEXPANDABLEHEIGHT 
							       EXPANSIONHEIGHT)))
                                                             (* now go through allocate the space within the groups
							     of windows.)
	    (for ATWINFO in ATWINSINFO when (LISTP (fetch (RESHAPINGWINDOWDATA ATTACHEDW)
							      of ATWINFO))
	       do (\ALLOCSPACETOGROUPEDWINDOWS ATWINFO))

          (* calculate how much of the available space was actually allocated. This is necessary because some of the windows 
	  may have reached their maximum and hence left some space not used. The extra is given to the main window.
	  The main window is shaped first so that user reshape functions can determine its size and shape as they do their 
	  thing.)


	    (SETQ TOTALNOWSIZE (\TOTALPROPOSEDSIZE ATWINSINFO))
	    [COND
	      ((NEQ (SETQ EXCESS (IDIFFERENCE NEWWIDTH (CAR TOTALNOWSIZE)))
		      0)                                     (* Feed the excess width to any windows that will take
							     it, starting with the main window)
		(for ATWINFO in ATWINSINFO
		   do (SETQ EXCESS (IDIFFERENCE EXCESS
						      (IDIFFERENCE
							(\SETWINFOXSIZE
							  ATWINFO
							  (IPLUS (SETQ NOW (fetch (
RESHAPINGWINDOWDATA ATXSIZE) of ATWINFO))
								   EXCESS))
							NOW)))
		   repeatuntil (EQ EXCESS 0]
	    [COND
	      ((NEQ (SETQ EXCESS (IDIFFERENCE NEWHEIGHT (CDR TOTALNOWSIZE)))
		      0)                                     (* Feed the excess height to any windows that will 
							     take it, starting with the main window)
		(for ATWINFO in ATWINSINFO
		   do (SETQ EXCESS (IDIFFERENCE EXCESS
						      (IDIFFERENCE
							(\SETWINFOYSIZE
							  ATWINFO
							  (IPLUS (SETQ NOW (fetch (
RESHAPINGWINDOWDATA ATYSIZE) of ATWINFO))
								   EXCESS))
							NOW)))
		   repeatuntil (EQ EXCESS 0]
	    (PROG ((MAINWIDTH (fetch (RESHAPINGWINDOWDATA ATXSIZE) of (CAR ATWINSINFO)))
		     (MAINHEIGHT (fetch (RESHAPINGWINDOWDATA ATYSIZE) of (CAR ATWINSINFO)))
		     WHEREONEDGE)
		    (for ATWINFO in ATWINSINFO
		       do                                  (* Calculate new position of main window inside the 
							     total region)
			    (SELECTQ (fetch (RESHAPINGWINDOWDATA ATEDGE) of ATWINFO)
				       [BOTTOM (add MWYOFF (fetch (RESHAPINGWINDOWDATA ATYSIZE)
								of ATWINFO))
					       (COND
						 ((MEMB (SETQ WHEREONEDGE (fetch (
RESHAPINGWINDOWDATA ATWHEREONEDGE) of ATWINFO))
							  (QUOTE (RIGHT CENTER)))
                                                             (* check if the attached window is wider than the main
							     window if the attachment is on the right or centered.)
						   (SETQ MWXOFF
						     (IMAX MWXOFF
							     (IQUOTIENT (DIFFERENCE
									    (fetch (
RESHAPINGWINDOWDATA ATXSIZE) of ATWINFO)
									    MAINWIDTH)
									  (COND
									    ((EQ WHEREONEDGE
										   (QUOTE CENTER))
									      2)
									    (T 1]
				       [LEFT (add MWXOFF (fetch (RESHAPINGWINDOWDATA ATXSIZE)
							      of ATWINFO))
					     (COND
					       ((MEMB (SETQ WHEREONEDGE (fetch (
RESHAPINGWINDOWDATA ATWHEREONEDGE) of ATWINFO))
							(QUOTE (TOP CENTER)))
                                                             (* check if the attached window is wider than the main
							     window if the attachment is on the right or centered.)
						 (SETQ MWYOFF
						   (IMAX MWYOFF (IQUOTIENT
							     (DIFFERENCE (fetch (
RESHAPINGWINDOWDATA ATYSIZE) of ATWINFO)
									   MAINHEIGHT)
							     (COND
							       ((EQ WHEREONEDGE (QUOTE CENTER))
								 2)
							       (T 1]
				       NIL)))
	    [SHAPEW1 MAINW (CREATEREGION (IPLUS MWXOFF (fetch (REGION LEFT) of NEWREGION))
					     (IPLUS MWYOFF (fetch (REGION BOTTOM) of NEWREGION))
					     (fetch (RESHAPINGWINDOWDATA ATXSIZE)
						of (CAR ATWINSINFO))
					     (fetch (RESHAPINGWINDOWDATA ATYSIZE)
						of (CAR ATWINSINFO]
                                                             (* reshape all of the attached windows according to 
							     the calculated new sizes.)
	    (\RESHAPEATTACHEDWINDOWSAROUNDMAINW MAINW (\BREAKAPARTATWSTRUCTURE (CDR ATWINSINFO])

(\TOTALPROPOSEDSIZE
  [LAMBDA (ATWSINFO PWIDTH PHEIGHT)                          (* rrb " 9-Dec-83 16:12")
                                                             (* determines the width of the windows that do not 
							     change their size.)
    (COND
      [ATWSINFO (PROG (THISWID THISHEIGHT THISMINWIDTH THISMINHEIGHT (ATW (CAR ATWSINFO))
			       (RESTATWS (CDR ATWSINFO)))
		      (SETQ THISMINWIDTH (fetch (RESHAPINGWINDOWDATA ATMINX) of ATW))
		      (SETQ THISMINHEIGHT (fetch (RESHAPINGWINDOWDATA ATMINY) of ATW))
		      (SETQ THISWID (fetch (RESHAPINGWINDOWDATA ATXSIZE) of ATW))
		      (SETQ THISHEIGHT (fetch (RESHAPINGWINDOWDATA ATYSIZE) of ATW))
		      (RETURN (SELECTQ (fetch (RESHAPINGWINDOWDATA ATEDGE) of ATW)
				       ((LEFT RIGHT)
					 (\TOTALPROPOSEDSIZE RESTATWS (IPLUS PWIDTH THISWID)
							     (IMAX PHEIGHT THISMINHEIGHT)))
				       ((TOP BOTTOM)
					 (\TOTALPROPOSEDSIZE RESTATWS (IMAX PWIDTH THISMINWIDTH)
							     (IPLUS PHEIGHT THISHEIGHT)))
				       (PROGN                (* this is the main window.)
					      (\TOTALPROPOSEDSIZE RESTATWS THISWID THISHEIGHT]
      (T (CONS PWIDTH PHEIGHT])

(SHRINKATTACHEDWINDOWS
  [LAMBDA (WINDOW)                                           (* jow "15-Aug-85 13:03")
                                                             (* propagates shrinking to attached windows.)
                                                             (* doesn't actually shrink, just closes and evaluates 
							     the shrink functions.)
    (for ATTACHEDWINDOW in (ATTACHEDWINDOWS WINDOW (QUOTE SHRINKW))
       do (DOUSERFNS (WINDOWPROP ATTACHEDWINDOW (QUOTE SHRINKFN))
		     ATTACHEDWINDOW)
	  (\CLOSEW1 ATTACHEDWINDOW])

(TOPATTACHEDWINDOWS
  [LAMBDA (WINDOW)                                           (* jow "14-Aug-85 17:12")
                                                             (* propagates totoping to attached windows.)
    (for ATTACHEDWINDOW in (ATTACHEDWINDOWS WINDOW (QUOTE TOTOPW))
       do (TOTOPW ATTACHEDWINDOW T)
	  (TOPATTACHEDWINDOWS ATTACHEDWINDOW])

(UNMAKEMAINWINDOW
  [LAMBDA (MAINWINDOW)                                       (* rrb "21-NOV-83 14:37")
                                                             (* the last attached window has been detached, clear any
							     relevant window properties.)
    (WINDOWDELPROP MAINWINDOW (QUOTE TOTOPFN)
		   (FUNCTION TOPATTACHEDWINDOWS))
    (WINDOWDELPROP MAINWINDOW (QUOTE CLOSEFN)
		   (FUNCTION CLOSEATTACHEDWINDOWS))
    (WINDOWDELPROP MAINWINDOW (QUOTE OPENFN)
		   (FUNCTION OPENATTACHEDWINDOWS))
    (WINDOWDELPROP MAINWINDOW (QUOTE SHRINKFN)
		   (FUNCTION SHRINKATTACHEDWINDOWS))
    (WINDOWDELPROP MAINWINDOW (QUOTE EXPANDFN)
		   (FUNCTION EXPANDATTACHEDWINDOWS))
    (WINDOWPROP MAINWINDOW (QUOTE CALCULATEREGIONFN)
		NIL)
    (WINDOWDELPROP MAINWINDOW (QUOTE MOVEFN)
		   (FUNCTION MOVEATTACHEDWINDOWS))
    (WINDOWPROP MAINWINDOW (QUOTE DOSHAPEFN)
		NIL])

(UPIQUOTIENT
  [LAMBDA (N DIVISOR)                                        (* rrb "20-NOV-83 13:41")
                                                             (* returns the smallest integer such that DIVISOR * that
							     number is greater than or equal to N.)
    (IQUOTIENT (IPLUS N (SUB1 DIVISOR))
	       DIVISOR])

(WINDOWPOSITION
  [LAMBDA (WINDOW)                                           (* rrb "27-OCT-83 15:41")
    (PROG [(REG (WINDOWPROP WINDOW (QUOTE REGION]
          (RETURN (create POSITION
			  XCOORD ←(fetch (REGION LEFT) of REG)
			  YCOORD ←(fetch (REGION BOTTOM) of REG])

(WINDOWSIZE
  [LAMBDA (WINDOW)                                           (* rrb " 6-Dec-83 17:45")
                                                             (* returns the size (WIDTH . HEIGHT) of a window and its
							     attached windows if any.)
    (PROG ((EXT (WINDOWREGION WINDOW)))                      (* this will give the wrong answer if the attached 
							     windows have been moved and have gaps between them.)
          (RETURN (CONS (fetch (REGION WIDTH) of EXT)
			(fetch (REGION HEIGHT) of EXT])

(\ALLOCMINIMUMSIZES
  [LAMBDA (ATWSINFO INTMINWIDTH INTMINHEIGHT NOWWIDTH NOWHEIGHT)
                                                             (* rrb " 7-Jan-86 14:37")

          (* allocates to each window in the list of window structures ATWSINFO the minimum space it should get based on the 
	  minimums of all of the other windows in ATWSINFO)

                                                             (* returns the minimum size dictated by the first 
							     window on ATWSINFO)
    (COND
      [ATWSINFO (PROG ((ATW (CAR ATWSINFO))
			 (THISMINWIDTH INTMINWIDTH)
			 (THISMINHEIGHT INTMINHEIGHT)
			 EXTSIZE EDGE WINDOWPILE RESTATWS FIXEDVAR EXPANSIONWIDTH NEWEXPANDABLEWIDTH 
			 NEWWIDTH EXPANSIONHEIGHT NEWEXPANDABLEHEIGHT NEWHEIGHT)
		        (SETQ RESTATWS ATWSINFO)
		        (SELECTQ (fetch (RESHAPINGWINDOWDATA ATEDGE) of ATW)
				   ((LEFT RIGHT)

          (* collect a list of windows that fit on the sides. This is so that any excess size imposed by windows further out 
	  can be allocated among all of the windows piled together.)


				     (for WININFO in RESTATWS
					until [NOT (FMEMB (fetch (RESHAPINGWINDOWDATA ATEDGE)
								   of WININFO)
								(QUOTE (LEFT RIGHT]
					do (SETQ THISMINHEIGHT (IMAX THISMINHEIGHT
									   (fetch (
RESHAPINGWINDOWDATA ATMINY) of WININFO)))                  (* calculate the current size of this pile of 
							     windows.)
					     (SETQ NOWHEIGHT (IMAX NOWHEIGHT (fetch
									 (RESHAPINGWINDOWDATA ATNOWY)
										    of WININFO)))
					     (SETQ NOWWIDTH (IPLUS NOWWIDTH (fetch
									 (RESHAPINGWINDOWDATA ATNOWX)
										   of WININFO)))
					     (SETQ THISMINWIDTH (IPLUS THISMINWIDTH
									   (fetch (
RESHAPINGWINDOWDATA ATMINX) of WININFO)))
					     (SETQ WINDOWPILE (CONS WININFO WINDOWPILE))
					     (SETQ RESTATWS (CDR RESTATWS)))
                                                             (* calculate the dimensions imposed by the minimum 
							     sizes of windows further out on the attached window 
							     list.)
				     [SETQ NEWWIDTH (CAR (SETQ EXTSIZE
							       (\ALLOCMINIMUMSIZES RESTATWS 
										     THISMINWIDTH 
										    THISMINHEIGHT 
										     NOWWIDTH 
										     NOWHEIGHT]
				     (SETQ NEWHEIGHT (CDR EXTSIZE))
                                                             (* compute how much of the current width can be 
							     expanded.)
				     [SETQ EXPANSIONWIDTH (IDIFFERENCE NOWWIDTH (SETQ FIXEDVAR
									     (\TOTALFIXEDWIDTH
									       WINDOWPILE]
				     (SETQ NEWEXPANDABLEWIDTH (IMAX (DIFFERENCE NEWWIDTH 
										      FIXEDVAR)
									0))
                                                             (* allocate to each window on this level of the pile 
							     its share.)
				     (for WININFO in WINDOWPILE
					do (\SETWINFOXSIZE WININFO (\SHAREOFXTRAX WININFO 
									       NEWEXPANDABLEWIDTH 
										   EXPANSIONWIDTH))
					     (\SETWINFOYSIZE WININFO NEWHEIGHT))
				     (RETURN (CONS (IDIFFERENCE NEWWIDTH
								      (for WININFO in WINDOWPILE
									 sum 
                                                             (* determine how much was actually allocated to the 
							     windows in the pile and give the rest to the initial 
							     window.)
									       (fetch (
RESHAPINGWINDOWDATA ATXSIZE) of WININFO)))
						       NEWHEIGHT)))
				   [(TOP BOTTOM)

          (* collect a list of windows that fit on the sides. This is so that any excess size imposed by windows further out 
	  can be allocated among all of the windows piled together.)


				     (for WININFO in RESTATWS
					until [NOT (FMEMB (fetch (RESHAPINGWINDOWDATA ATEDGE)
								   of WININFO)
								(QUOTE (TOP BOTTOM]
					do (SETQ THISMINHEIGHT (IPLUS THISMINHEIGHT
									    (fetch (
RESHAPINGWINDOWDATA ATMINY) of WININFO)))
					     (SETQ NOWHEIGHT (IPLUS NOWHEIGHT
									(fetch (RESHAPINGWINDOWDATA
										   ATNOWY)
									   of WININFO)))
					     (SETQ NOWWIDTH (IMAX NOWWIDTH (fetch (
RESHAPINGWINDOWDATA ATNOWX) of WININFO)))
					     (SETQ THISMINWIDTH (IMAX THISMINWIDTH
									  (fetch (
RESHAPINGWINDOWDATA ATMINX) of WININFO)))
					     (SETQ WINDOWPILE (CONS WININFO WINDOWPILE))
					     (SETQ RESTATWS (CDR RESTATWS)))
                                                             (* calculate the dimensions imposed by the minimum 
							     sizes of windows further out on the attached window 
							     list.)
				     [SETQ NEWWIDTH (CAR (SETQ EXTSIZE
							       (\ALLOCMINIMUMSIZES RESTATWS 
										     THISMINWIDTH 
										    THISMINHEIGHT 
										     NOWWIDTH 
										     NOWHEIGHT]
				     (SETQ NEWHEIGHT (CDR EXTSIZE))
                                                             (* compute how much of the current height can be 
							     expanded.)
				     [SETQ EXPANSIONHEIGHT (IDIFFERENCE NOWHEIGHT (SETQ 
									      FIXEDVAR (
										\TOTALFIXEDHEIGHT
										WINDOWPILE]
				     (SETQ NEWEXPANDABLEHEIGHT (IMAX (DIFFERENCE NEWHEIGHT 
										       FIXEDVAR)
									 0))
                                                             (* allocate to each window on this level of the pile 
							     its share.)
				     (for WININFO in WINDOWPILE
					do (\SETWINFOXSIZE WININFO NEWWIDTH)
					     (\SETWINFOYSIZE WININFO (\SHAREOFXTRAY WININFO 
									      NEWEXPANDABLEHEIGHT 
										  EXPANSIONHEIGHT)))
				     (RETURN (CONS NEWWIDTH (IDIFFERENCE
							 NEWHEIGHT
							 (for WININFO in WINDOWPILE
							    sum 
                                                             (* determine how much was actually allocated to the 
							     windows in the pile and give the rest to the initial 
							     window.)
								  (fetch (RESHAPINGWINDOWDATA
									     ATYSIZE)
								     of WININFO]
				   (PROGN                  (* this is the main window.)
					    (SETQ EXTSIZE (\ALLOCMINIMUMSIZES
						(CDR ATWSINFO)
						(fetch (RESHAPINGWINDOWDATA ATMINX) of ATW)
						(fetch (RESHAPINGWINDOWDATA ATMINY) of ATW)
						(fetch (RESHAPINGWINDOWDATA ATNOWX) of ATW)
						(fetch (RESHAPINGWINDOWDATA ATNOWY) of ATW)))
					    (\SETWINFOXSIZE ATW (CAR EXTSIZE))
					    (\SETWINFOYSIZE ATW (CDR EXTSIZE]
      (T (CONS INTMINWIDTH INTMINHEIGHT])

(\ALLOCSPACETOGROUPEDWINDOWS
  [LAMBDA (WGROUPINFO)                                       (* rrb " 9-Dec-83 15:15")
                                                             (* allocates space to the windows on EXTBUCKETS.)
    (SELECTQ (fetch (RESHAPINGWINDOWDATA ATEDGE) of WGROUPINFO)
	     ((LEFT RIGHT)                                   (* allocate in X)
	       (\ALLOCWIDTHTOGROUPEDWINDOW WGROUPINFO))
	     (\ALLOCHEIGHTTOGROUPEDWINDOW WGROUPINFO])

(\TOTALFIXEDHEIGHT
  [LAMBDA (ATWSINFO)                                         (* bvm: "12-Apr-84 12:30")
                                                             (* determines the height of the windows that do not 
							     change their size.)
    (bind (MAXEDW ← 0)
	  THISMINHEIGHT for ATW in ATWSINFO when (AND [NOT (AND (EQ (fetch (RESHAPINGWINDOWDATA
									     ATWHEREONEDGE)
								       of ATW)
								    (QUOTE JUSTIFY))
								(FMEMB (fetch (RESHAPINGWINDOWDATA
										ATEDGE)
									  of ATW)
								       (QUOTE (LEFT RIGHT]
						      (EQ (SETQ THISMINHEIGHT (fetch (
RESHAPINGWINDOWDATA ATMINY) of ATW))
							  (fetch (RESHAPINGWINDOWDATA ATMAXY)
							     of ATW)))
       sum THISMINHEIGHT])

(\TOTALFIXEDWIDTH
  [LAMBDA (ATWSINFO)                                         (* bvm: "12-Apr-84 12:30")

          (* determines the width of the windows that do not change their size. A window that is JUSTIFIED and is on the TOP
	  or BOTTOM is not counted since it will be stretched as needed.)


    (bind (MAXEDW ← 0)
	  THISMINWIDTH for ATW in ATWSINFO when (AND [NOT (AND (EQ (fetch (RESHAPINGWINDOWDATA 
										    ATWHEREONEDGE)
								      of ATW)
								   (QUOTE JUSTIFY))
							       (FMEMB (fetch (RESHAPINGWINDOWDATA
									       ATEDGE)
									 of ATW)
								      (QUOTE (TOP BOTTOM]
						     (EQ (SETQ THISMINWIDTH (fetch (
RESHAPINGWINDOWDATA ATMINX) of ATW))
							 (fetch (RESHAPINGWINDOWDATA ATMAXX)
							    of ATW)))
       sum THISMINWIDTH])

(\ALLOCHEIGHTTOGROUPEDWINDOW
  [LAMBDA (WGROUPINFO)                                       (* rrb "15-Dec-83 10:19")

          (* allocates height to a collection of window all of which are attached to the top, or bottom edge but at 
	  different places on the edge. EXTBUCKET is a list of those window at the left center and right of the edge.
	  Also sets the width field in the window information structure.)


    (PROG ((EXTBUCKET (for WHEREONEDGE in (QUOTE (LEFT CENTER RIGHT))
			 collect (for ATW in (fetch (RESHAPINGWINDOWDATA ATTACHEDW) of WGROUPINFO)
				    when (EQ (fetch (RESHAPINGWINDOWDATA ATWHEREONEDGE) of ATW)
					     WHEREONEDGE)
				    collect ATW)))
	   (TOTALNOWSIZE (fetch (RESHAPINGWINDOWDATA ATNOWY) of WGROUPINFO))
	   [TOTALXTRA (IDIFFERENCE (fetch (RESHAPINGWINDOWDATA ATYSIZE) of WGROUPINFO)
				   (\TOTALFIXEDHEIGHT (fetch (RESHAPINGWINDOWDATA ATTACHEDW)
							 of WGROUPINFO]
	   SHARE HEIGHTS MAXHEIGHT NOWSIZE MAXSIZE NEWSIZE XTRA)
          [SETQ HEIGHTS (for ATWS in EXTBUCKET collect (for ATW in ATWS
							  sum 
                                                             (* leave the width the same. Possibly this should expand
							     but calculation depends on width of other windows 
							     attached next to this one.)
							      (\SETWINFOXSIZE ATW
									      (fetch (
RESHAPINGWINDOWDATA ATNOWX) of ATW))
							      (\SETWINFOYSIZE ATW
									      (\SHAREOFXTRAY ATW 
											TOTALXTRA 
										     TOTALNOWSIZE]
          (SETQ MAXHEIGHT (APPLY (FUNCTION MAX)
				 HEIGHTS))                   (* keep track of the width as part of the sizing.)
                                                             (* allocate extra to places which are not maximum yet.)
          (for ATWS in EXTBUCKET as HEIGHT in HEIGHTS unless (NULL ATWS)
	     do (COND
		  ((NEQ HEIGHT MAXHEIGHT)
		    (SETQ XTRA (IDIFFERENCE MAXHEIGHT HEIGHT))
		    (until (OR (NULL ATWS)
			       (EQ 0 XTRA))
		       do (SETQ SHARE (UPIQUOTIENT XTRA (LENGTH ATWS))) 

          (* UPIQUOTIENT is used to make sure that all of the space is allocated. Having the shares be greater than the 
	  total means that before the share is given to the window, a check must be made to see that the space in fact 
	  exists. This is done by the IMAX in calculating NEWSIZE.)



          (* THIS ALGORITHM HAS THE BAD PROPERTY THAT THE FIRST N-1 windows might get one point too much and cause the last 
	  window to be N-2 points smaller than it would be in the perfect case.)


			  (for ATW in ATWS do (COND
						((EQ (SETQ NOWSIZE (fetch (RESHAPINGWINDOWDATA 
											  ATYSIZE)
								      of ATW))
						     (SETQ MAXSIZE (fetch (RESHAPINGWINDOWDATA ATMAXY)
								      of ATW)))
                                                             (* window has reached max, remove it from getting more 
							     space.)
						  (SETQ ATWS (REMOVE ATW ATWS)))
						((PROGN      (* NEWSIZE needs to be calculated whether MAXSIZE exists
							     or not.)
							(SETQ NEWSIZE (PLUS (IMAX SHARE XTRA)
									    NOWSIZE))
							(AND MAXSIZE (LESSP MAXSIZE NEWSIZE)))
                                                             (* add only enough to reach maximum.)
						  (SETQ XTRA (IDIFFERENCE XTRA (IDIFFERENCE MAXSIZE 
											  NOWSIZE)))
						  (SETQ ATWS (REMOVE ATW ATWS))
						  (replace (RESHAPINGWINDOWDATA ATYSIZE)
						     of ATW with MAXSIZE))
						(T (SETQ XTRA (IDIFFERENCE XTRA (IDIFFERENCE NEWSIZE 
											  NOWSIZE)))
						   (replace (RESHAPINGWINDOWDATA ATYSIZE)
						      of ATW with NEWSIZE])

(\ALLOCWIDTHTOGROUPEDWINDOW
  [LAMBDA (WGROUPINFO)                                       (* rrb "15-Dec-83 10:19")

          (* allocates width to a collection of window all of which are attached to the left or right edge but at different 
	  places on the edge. EXTBUCKET is a list of those window at the top, center and bottom of the edge.)


    (PROG ((EXTBUCKET (for WHEREONEDGE in (QUOTE (TOP CENTER BOTTOM))
			 collect (for ATW in (fetch (RESHAPINGWINDOWDATA ATTACHEDW) of WGROUPINFO)
				    when (EQ (fetch (RESHAPINGWINDOWDATA ATWHEREONEDGE) of ATW)
					     WHEREONEDGE)
				    collect ATW)))
	   (TOTALNOWSIZE (fetch (RESHAPINGWINDOWDATA ATNOWX) of WGROUPINFO))
	   (TOTALXTRA (fetch (RESHAPINGWINDOWDATA ATXSIZE) of WGROUPINFO))
	   SHARE WIDTHS MAXWIDTH NOWSIZE MAXSIZE NEWSIZE XTRA)
          [SETQ WIDTHS (for ATWS in EXTBUCKET collect (for ATW in ATWS
							 sum 
                                                             (* leave height the same as it was.
							     Could expand if neighbors weren't too big but haven't 
							     bothered.)
							     (\SETWINFOYSIZE ATW (fetch (
RESHAPINGWINDOWDATA ATNOWY) of ATW))
							     (\SETWINFOXSIZE ATW
									     (\SHAREOFXTRAX ATW 
											TOTALXTRA 
										     TOTALNOWSIZE]
          (SETQ MAXWIDTH (APPLY (FUNCTION MAX)
				WIDTHS))                     (* keep track of the width as part of the sizing.)
                                                             (* allocate extra to places which are not maximum yet.)
          (for ATWS in EXTBUCKET as WIDTH in WIDTHS unless (NULL ATWS)
	     do (COND
		  ((NEQ WIDTH MAXWIDTH)
		    (SETQ XTRA (IDIFFERENCE MAXWIDTH WIDTH))
		    (until (OR (NULL ATWS)
			       (EQ 0 XTRA))
		       do (SETQ SHARE (UPIQUOTIENT XTRA (LENGTH ATWS))) 

          (* UPIQUOTIENT is used to make sure that all of the space is allocated. Having the shares be greater than the 
	  total means that before the share is given to the window, a check must be made to see that the space in fact 
	  exists. This is done by the IMAX in calculating NEWSIZE.)



          (* THIS ALGORITHM HAS THE BAD PROPERTY THAT THE FIRST N-1 windows might get one point too much and cause the last 
	  window to be N-2 points smaller than it would be in the perfect case.)


			  (for ATW in ATWS do (COND
						((EQ (SETQ NOWSIZE (fetch (RESHAPINGWINDOWDATA 
											  ATXSIZE)
								      of ATW))
						     (SETQ MAXSIZE (fetch (RESHAPINGWINDOWDATA ATMAXX)
								      of ATW)))
                                                             (* window has reached max, remove it from getting more 
							     space.)
						  (SETQ ATWS (REMOVE ATW ATWS)))
						((PROGN      (* NEWSIZE needs to be calculated whether MAXSIZE exists
							     or not.)
							(SETQ NEWSIZE (PLUS (IMAX SHARE XTRA)
									    NOWSIZE))
							(AND MAXSIZE (LESSP MAXSIZE NEWSIZE)))
                                                             (* add only enough to reach maximum.)
						  (SETQ XTRA (IDIFFERENCE XTRA (IDIFFERENCE MAXSIZE 
											  NOWSIZE)))
						  (SETQ ATWS (REMOVE ATW ATWS))
						  (replace (RESHAPINGWINDOWDATA ATXSIZE)
						     of ATW with MAXSIZE))
						(T (SETQ XTRA (IDIFFERENCE XTRA (IDIFFERENCE NEWSIZE 
											  NOWSIZE)))
						   (replace (RESHAPINGWINDOWDATA ATXSIZE)
						      of ATW with NEWSIZE])

(\ATWGROUPSIZE
  [LAMBDA (ATWS)                                             (* rrb " 8-Jan-86 11:48")
                                                             (* returns the size of a group of attached window 
							     information structures.)
    (COND
      [ATWS (PROG [(EXTREGION (WINDOWREGION (fetch (RESHAPINGWINDOWDATA ATTACHEDW)
						   of (CAR ATWS]
		    (for ATW in (CDR ATWS) do (SETQ EXTREGION
							(UNIONREGIONS (WINDOWREGION
									  (fetch (
RESHAPINGWINDOWDATA ATTACHEDW) of ATW))
									EXTREGION)))
		    (RETURN (CONS (fetch (REGION WIDTH) of EXTREGION)
				      (fetch (REGION HEIGHT) of EXTREGION]
      (T (CONS 0 0])

(\BREAKAPARTATWSTRUCTURE
  [LAMBDA (ATWLST)                                           (* rrb "14-Dec-83 12:45")
                                                             (* breaks apart the window grouping that are in ATWLST)
    (for ATW in ATWLST join (COND
			      [(APPEND (LISTP (fetch (RESHAPINGWINDOWDATA ATTACHEDW) of ATW]
			      (T (CONS ATW])

(\BUILDATWSTRUCTURE
  [LAMBDA (MAINW ATTACHEDWINDOWS)                            (* bvm: "29-Dec-83 15:58")
                                                             (* builds a structure which has place holders for each 
							     window or collection of windows on an edge.)
    (PROG ((EDGEBUCKETLIST (for SIDE in (QUOTE (TOP RIGHT BOTTOM LEFT)) collect (CONS SIDE NIL)))
	   EDGEBUCKET WHEREAT ATWINFO WHEREONEDGE PLACEHOLDERATW)
          (RETURN (CONS (LIST MAINW NIL (MINIMUMMAINWINDOWSIZE MAINW)
			      (MAXIMUMMAINWINDOWSIZE MAINW)
			      (CONS 0 0)
			      (CONS [fetch (REGION WIDTH) of (SETQ WHEREAT (WINDOWPROP MAINW
										       (QUOTE REGION]
				    (fetch (REGION HEIGHT) of WHEREAT)))
			(for ATWIN in ATTACHEDWINDOWS
			   join                              (* collect all of the information about an attached 
							     window and leave a place for its determined size.)
				(SETQ WHEREAT (WINDOWPROP ATWIN (QUOTE WHEREATTACHED)))
				(SETQ EDGEBUCKET (FASSOC (CAR WHEREAT)
							 EDGEBUCKETLIST))
				(SETQ ATWINFO (LIST ATWIN WHEREAT (MINIMUMWINDOWSIZE ATWIN)
						    (MAXIMUMWINDOWSIZE ATWIN)
						    (CONS 0 0)
						    (WINDOWSIZE ATWIN)))
				[COND
				  ((EQ (SETQ WHEREONEDGE (fetch ATWHEREONEDGE of ATWINFO))
				       (QUOTE JUSTIFY))

          (* when a window that fits all the way across is encountered, set the fields in the group information structure 
	  and clear it. Then return the structure for this window.)


				    (COND
				      ((CDR EDGEBUCKET)      (* compute the group mins from the windows that don't 
							     fit all the way across on this edge.)
					(\SETGROUPMIN (CDR EDGEBUCKET))
					(RPLACD EDGEBUCKET NIL)))
				    (CONS ATWINFO))
				  (T 

          (* if this window doesn't fit all the way across, put it in the group that is being formed for this edge.
	  If there isn't a group yet, form one and return it so that it will take this place in the structure.)


				     (COND
				       ((CDR EDGEBUCKET)     (* group already exists)
					 (NCONC1 (CADR EDGEBUCKET)
						 ATWINFO)
					 NIL)
				       (T                    (* make a with dummy value in its fields and return it 
							     to save its place in the attached window list.)
					  (SETQ PLACEHOLDERATW (LIST (LIST ATWINFO)
								     WHEREAT
								     (CONS 0 0)
								     (CONS NIL NIL)
								     (CONS 0 0)
								     (CONS 0 0)))
					  (RPLACD EDGEBUCKET PLACEHOLDERATW)
					  (LIST PLACEHOLDERATW]
			   finally (for old EDGEBUCKET in EDGEBUCKETLIST
				      do                     (* allocate space for those groups that don't have any 
							     windows outside them that fit all the way across.)
					 (COND
					   ((CDR EDGEBUCKET)
                                                             (* compute the group mins from the windows that don't 
							     fit all the way across on this edge.)
					     (\SETGROUPMIN (CDR EDGEBUCKET))
					     (RPLACD EDGEBUCKET NIL])

(\LIMITBYMAX
  [LAMBDA (N MAX)                                            (* limits the size of N to MAX)
    (COND
      (MAX (IMIN N MAX))
      (T N])

(\LIMITBYMIN
  [LAMBDA (N MIN)                                            (* bvm: "10-Nov-84 15:14")
                                                             (* limits the size of N to MIN)
    (COND
      (MIN (IMAX N MIN))
      (T N])

(\MAXHEIGHTOFGROUP
  [LAMBDA (ATWINFOS)                                         (* rrb "14-Dec-83 12:22")

          (* returns the largest minimum height of a group of windows all of which are on the same edge.
	  It must look at each position on the edge {left center right} and sum over the elements that are on that 
	  position.)


    (for WHEREONEDGE in (QUOTE (LEFT CENTER RIGHT)) largest (for ATW in ATWINFOS
							       when (EQ (fetch (RESHAPINGWINDOWDATA
										 ATWHEREONEDGE)
									   of ATW)
									WHEREONEDGE)
							       sum (fetch (RESHAPINGWINDOWDATA ATMINY)
								      of ATW))
       finally (RETURN $$EXTREME])

(\MAXWIDTHOFGROUP
  [LAMBDA (ATWINFOS)                                         (* rrb "15-Dec-83 10:21")

          (* returns the largest minimum width of a group of windows all of which are on the same edge.
	  It must look at each position on the edge {top center bottom} and sum over the elements that are on that 
	  position.)


    (for WHEREONEDGE in (QUOTE (TOP CENTER BOTTOM)) largest (for ATW in ATWINFOS
							       when (EQ (fetch (RESHAPINGWINDOWDATA
										 ATWHEREONEDGE)
									   of ATW)
									WHEREONEDGE)
							       sum (fetch (RESHAPINGWINDOWDATA ATMINX)
								      of ATW))
       finally (RETURN $$EXTREME])

(\RESHAPEATTACHEDWINDOWSAROUNDMAINW
  [LAMBDA (MAINW ATWINSINFO)                                 (* rrb " 3-Oct-84 16:33")
    (PROG ((MAINWEXTENT (WINDOWPROP MAINW (QUOTE REGION)))
	   EXTENT ATWHGHT ATWDTH TL TC TR RT RC RB BR BC BL LB LC LT)
          [SETQ TL (SETQ TC (SETQ TR (fetch (REGION TOP) of MAINWEXTENT]
          [SETQ RT (SETQ RC (SETQ RB (fetch (REGION RIGHT) of MAINWEXTENT]
          [SETQ BR (SETQ BC (SETQ BL (fetch (REGION BOTTOM) of MAINWEXTENT]
          [SETQ LB (SETQ LC (SETQ LT (fetch (REGION LEFT) of MAINWEXTENT]
          (bind ATWHERE ATW TEMP for ATWINFO in ATWINSINFO
	     do                                              (* go through the attached windows shaping them and 
							     keeping track of their effect on the position.)
		[SETQ EXTENT (WINDOWREGION (SETQ ATW (fetch (RESHAPINGWINDOWDATA ATTACHEDW)
							of ATWINFO]
		(SETQ ATWHGHT (fetch (REGION HEIGHT) of EXTENT))
		(SETQ ATWDTH (fetch (REGION WIDTH) of EXTENT))
		(SETQ ATWHERE (SELECTQ (fetch (RESHAPINGWINDOWDATA ATWHEREONEDGE) of ATWINFO)
				       (JUSTIFY (QUOTE JUSTIFY))
				       (CENTER 0)
				       ((LEFT BOTTOM)
					 -1)
				       1))
		(SHAPEW ATW (SELECTQ (fetch (RESHAPINGWINDOWDATA ATEDGE) of ATWINFO)
				     (TOP                    (* use new height)
					  (SETQ ATWHGHT (fetch (RESHAPINGWINDOWDATA ATYSIZE)
							   of ATWINFO))
					  (SELECTQ ATWHERE
						   [JUSTIFY (PROG1 (CREATEREGION
								     LT
								     (ADD1 (SETQ TEMP
									     (MAX TL TC TR)))
								     (ADD1 (DIFFERENCE RT LT))
								     ATWHGHT)
								   (SETQ TL (SETQ TC
								       (SETQ TR (PLUS TEMP ATWHGHT]
						   [-1 (PROG1 (CREATEREGION LT (ADD1 TL)
									    ATWDTH ATWHGHT)
							      (SETQ TL (PLUS TL ATWHGHT]
						   [0 (PROG1 (CREATEREGION (CENTERINWIDTH ATWDTH 
										      MAINWEXTENT)
									   (ADD1 TC)
									   ATWDTH ATWHGHT)
							     (SETQ TC (PLUS TC ATWHGHT]
						   [1 (PROG1 (CREATEREGION (ADD1 (DIFFERENCE RT 
											   ATWDTH))
									   (ADD1 TR)
									   ATWDTH ATWHGHT)
							     (SETQ TR (PLUS TR ATWHGHT]
						   (SHOULDNT)))
				     (RIGHT (SETQ ATWDTH (fetch (RESHAPINGWINDOWDATA ATXSIZE)
							    of ATWINFO))
					    (SELECTQ ATWHERE
						     [JUSTIFY (PROG1 (CREATEREGION
								       (ADD1 (SETQ TEMP
									       (MAX RT RC RB)))
								       BR ATWDTH
								       (ADD1 (DIFFERENCE TR BR)))
								     (SETQ RT (SETQ RC
									 (SETQ RB (PLUS TEMP ATWDTH]
						     [1 (PROG1 (CREATEREGION (ADD1 RT)
									     (ADD1 (DIFFERENCE TR 
											  ATWHGHT))
									     ATWDTH ATWHGHT)
							       (SETQ RT (PLUS RT ATWDTH]
						     [0 (PROG1 (CREATEREGION (ADD1 RC)
									     (CENTERINHEIGHT ATWHGHT 
										      MAINWEXTENT)
									     ATWDTH ATWHGHT)
							       (SETQ RC (PLUS RC ATWDTH]
						     [-1 (PROG1 (CREATEREGION (ADD1 RB)
									      BR ATWDTH ATWHGHT)
								(SETQ RB (PLUS RB ATWDTH]
						     (SHOULDNT)))
				     (LEFT (SETQ ATWDTH (fetch (RESHAPINGWINDOWDATA ATXSIZE)
							   of ATWINFO))
					   (SELECTQ ATWHERE
						    [JUSTIFY (CREATEREGION [SETQ LT
									     (SETQ LC
									       (SETQ LB
										 (DIFFERENCE
										   (MIN LT LC LB)
										   ATWDTH]
									   BL ATWDTH
									   (ADD1 (DIFFERENCE TL BL]
						    (1 (CREATEREGION (SETQ LT (DIFFERENCE LT ATWDTH))
								     (ADD1 (DIFFERENCE TL ATWHGHT))
								     ATWDTH ATWHGHT))
						    (0 (CREATEREGION (SETQ LC (DIFFERENCE LC ATWDTH))
								     (CENTERINHEIGHT ATWHGHT 
										     MAINWEXTENT)
								     ATWDTH ATWHGHT))
						    (-1 (CREATEREGION (SETQ LB (DIFFERENCE LB ATWDTH))
								      BL ATWDTH ATWHGHT))
						    (SHOULDNT)))
				     (BOTTOM (SETQ ATWHGHT (fetch (RESHAPINGWINDOWDATA ATYSIZE)
							      of ATWINFO))
					     (SELECTQ ATWHERE
						      (JUSTIFY (CREATEREGION
								 LB
								 [SETQ BL
								   (SETQ BC
								     (SETQ BR
								       (DIFFERENCE (MIN BL BC BR)
										   ATWHGHT]
								 (ADD1 (DIFFERENCE RB LB))
								 ATWHGHT))
						      (-1 (CREATEREGION LB (SETQ BL (DIFFERENCE
									    BL ATWHGHT))
									ATWDTH ATWHGHT))
						      (0 (CREATEREGION (CENTERINWIDTH ATWDTH 
										      MAINWEXTENT)
								       (SETQ BC (DIFFERENCE BC 
											  ATWHGHT))
								       ATWDTH ATWHGHT))
						      (1 (CREATEREGION (ADD1 (DIFFERENCE RB ATWDTH))
								       (SETQ BR (DIFFERENCE BR 
											  ATWHGHT))
								       ATWDTH ATWHGHT))
						      (SHOULDNT)))
				     (SHOULDNT])

(\SETGROUPMIN
  [LAMBDA (GROUPATWINFO)                                     (* rrb "14-Dec-83 12:23")
                                                             (* sets the minimum of a group of attached windows.)
                                                             (* the CAR is the list of information structures of the 
							     members of the group.)
                                                             (* set the size of the whole group so that the 
							     proportional calculation can go through.)

          (* also sets the maximum in the dimension in which the group can expand if everyone in the group has a limit.
	  This information is used to determine allocation shares in the case where the group has its maximum size, no more 
	  space will be given to it.)


    (PROG [(GROUPSIZE (\ATWGROUPSIZE (CAR GROUPATWINFO]
          (replace (RESHAPINGWINDOWDATA ATNOWX) of GROUPATWINFO with (CAR GROUPSIZE))
          (replace (RESHAPINGWINDOWDATA ATNOWY) of GROUPATWINFO with (CDR GROUPSIZE)))
    (SELECTQ (fetch (RESHAPINGWINDOWDATA ATEDGE) of GROUPATWINFO)
	     [(LEFT RIGHT)
	       (replace (RESHAPINGWINDOWDATA ATMINX) of GROUPATWINFO with (\MAXWIDTHOFGROUP
									    (CAR GROUPATWINFO)))
	       (replace (RESHAPINGWINDOWDATA ATMINY) of GROUPATWINFO
		  with (for ATW in (CAR GROUPATWINFO) largest (fetch (RESHAPINGWINDOWDATA ATMINY)
								 of ATW)
			  finally (RETURN $$EXTREME)))
	       (replace (RESHAPINGWINDOWDATA ATMAXX) of GROUPATWINFO
		  with (PROG ((TMAX 0)
			      (CMAX 0)
			      (BMAX 0)
			      THISMAX)
			     (RETURN (for ATW in (CAR GROUPATWINFO)
					do [COND
					     ((NULL (SETQ THISMAX (fetch (RESHAPINGWINDOWDATA ATMAXX)
								     of ATW)))
                                                             (* if any of the windows in the group doesn't have a 
							     max, the group doesn't either.)
					       (RETURN NIL))
					     (T (SELECTQ (fetch (RESHAPINGWINDOWDATA ATWHEREONEDGE)
							    of ATW)
							 (TOP (SETQ TMAX (IPLUS TMAX THISMAX)))
							 (CENTER (SETQ CMAX (IPLUS CMAX THISMAX)))
							 (SETQ BMAX (IPLUS BMAX THISMAX]
					finally (RETURN (IMAX TMAX CMAX BMAX]
	     [(TOP BOTTOM)
	       (replace (RESHAPINGWINDOWDATA ATMINX) of GROUPATWINFO
		  with (for ATW in (CAR GROUPATWINFO) largest (fetch (RESHAPINGWINDOWDATA ATMINX)
								 of ATW)
			  finally (RETURN $$EXTREME)))
	       (replace (RESHAPINGWINDOWDATA ATMINY) of GROUPATWINFO with (\MAXHEIGHTOFGROUP
									    (CAR GROUPATWINFO)))
	       (replace (RESHAPINGWINDOWDATA ATMAXY) of GROUPATWINFO
		  with (PROG ((LMAX 0)
			      (CMAX 0)
			      (RMAX 0)
			      THISMAX)
			     (RETURN (for ATW in (CAR GROUPATWINFO)
					do [COND
					     ((NULL (SETQ THISMAX (fetch (RESHAPINGWINDOWDATA ATMAXY)
								     of ATW)))
                                                             (* if any of the windows in the group doesn't have a 
							     max, the group doesn't either.)
					       (RETURN NIL))
					     (T (SELECTQ (fetch (RESHAPINGWINDOWDATA ATWHEREONEDGE)
							    of ATW)
							 (LEFT (SETQ LMAX (IPLUS LMAX THISMAX)))
							 (CENTER (SETQ CMAX (IPLUS CMAX THISMAX)))
							 (SETQ RMAX (IPLUS RMAX THISMAX]
					finally (RETURN (IMAX LMAX CMAX RMAX]
	     (SHOULDNT])

(\SETWINFOXSIZE
  [LAMBDA (WINFO PROPOSEDSIZE)                               (* bvm: "10-Nov-84 15:14")
                                                             (* sets the X size of a window information structure, 
							     limiting by the maximum and returns the value put in.)
    (replace (RESHAPINGWINDOWDATA ATXSIZE) of WINFO with (\LIMITBYMIN (\LIMITBYMAX
									PROPOSEDSIZE
									(fetch (RESHAPINGWINDOWDATA
										 ATMAXX)
									   of WINFO))
								      (fetch (RESHAPINGWINDOWDATA
									       ATMINX)
									 of WINFO])

(\SETWINFOYSIZE
  [LAMBDA (WINFO PROPOSEDSIZE)                               (* bvm: "10-Nov-84 15:17")
                                                             (* sets the Y size of a window information structure, 
							     limiting by the maximum and returns the value put in.)
                                                             (* bvm: Used to say (IMAX this 0), but that is 
							     asymmetric with \SETWINFOXSIZE and the \LIMITBYMIN 
							     should catch it anyway)
    (replace (RESHAPINGWINDOWDATA ATYSIZE) of WINFO with (\LIMITBYMIN (\LIMITBYMAX
									PROPOSEDSIZE
									(fetch (RESHAPINGWINDOWDATA
										 ATMAXY)
									   of WINFO))
								      (fetch (RESHAPINGWINDOWDATA
									       ATMINY)
									 of WINFO])

(\SHAREOFXTRAX
  [LAMBDA (WINFO TOTALNEWSIZE TOTALOLDSIZE)                  (* bvm: "10-Nov-84 15:14")
                                                             (* returns the proportion of space in X that a window 
							     should get base on its size before the reshape.)
    (IMAX (IQUOTIENT (ITIMES (fetch (RESHAPINGWINDOWDATA ATNOWX) of WINFO)
			     TOTALNEWSIZE)
		     TOTALOLDSIZE)
	  (fetch (RESHAPINGWINDOWDATA ATXSIZE) of WINFO])

(\SHAREOFXTRAY
  [LAMBDA (WINFO TOTALNEWSIZE TOTALOLDSIZE)                  (* rrb " 7-Jan-86 17:04")
                                                             (* returns the proportion of space in Y that a window 
							     should get based on its size before the reshape.)
    (COND
      ((EQ TOTALOLDSIZE 0)
	0)
      (T (IMAX (IQUOTIENT (ITIMES (fetch (RESHAPINGWINDOWDATA ATNOWY) of WINFO)
					TOTALNEWSIZE)
			      TOTALOLDSIZE)
		 (fetch (RESHAPINGWINDOWDATA ATYSIZE) of WINFO])
)
(DEFINEQ

(ATTACHMENU
  [LAMBDA (MENU MAINWINDOW EDGE POSITIONONEDGE NOOPENFLG)    (* rrb "27-Jun-84 11:19")
                                                             (* this function associates a menu with a window.)
    (PROG (MENUWINDOW)                                       (* VERTFLG is non-NIL if the menu is to be layed out 
							     above or below the main window.)
          [SETQ MENUWINDOW (MENUWINDOW MENU (FMEMB EDGE (QUOTE (LEFT RIGHT]
          (ATTACHWINDOW MENUWINDOW MAINWINDOW EDGE POSITIONONEDGE T)
          (OR NOOPENFLG (NOT (OPENWP MAINWINDOW))
	      (OPENW MENUWINDOW))
          (RETURN MENUWINDOW])

(CREATEMENUEDWINDOW
  [LAMBDA (MENU WINDOWTITLE LOCATION WINDOWSPEC)             (* bvm: "12-Apr-84 16:59")

          (* This function is used to create a MAIN window MENU pair. MENU specifies the menu content and may be a menu, a 
	  list of items. WINDOWTITLE is a string specifying a title for the main window. LOCATION specifies the placement of
	  the window (TOP BOTTOM LEFT RIGHT); WINDOWSPEC is a REGION. If it is NIL, a new window will be created.)


    (PROG ((VERTFLG (COND
		      ((NULL LOCATION)                       (* Default LOCATION is TOP)
			(SETQ LOCATION (QUOTE TOP))
			NIL)
		      ((FMEMB LOCATION (QUOTE (LEFT RIGHT)))
			T)))
	   WINDOW MENUW MENUWIDTH MENUHEIGHT WHOLEREGION MINTOTALHEIGHT MINTOTALWIDTH)
          (COND
	    [(LISTP MENU)
	      (SETQ MENU (create MENU
				 ITEMS ← MENU
				 CENTERFLG ← T
				 TITLE ←(COND
				   ((AND WINDOWTITLE VERTFLG)
                                                             (* If the menu is on the side continue the title bar 
							     even if the menu has no title)
				     " "]
	    ((type? MENU MENU))
	    (T (\ILLEGAL.ARG MENU)))
          [COND
	    ((NULL (fetch MENUROWS of MENU))
	      (replace MENUROWS of MENU with (COND
					       (VERTFLG (LENGTH (fetch (MENU ITEMS) of MENU)))
					       (T 1]
          (SETQ MENUW (MENUWINDOW MENU VERTFLG))
          (SETQ MINTOTALWIDTH (SETQ MENUWIDTH (fetch (MENU IMAGEWIDTH) of MENU)))
          (SETQ MINTOTALHEIGHT (SETQ MENUHEIGHT (fetch (MENU IMAGEHEIGHT) of MENU)))
          (SELECTQ LOCATION
		   [(TOP BOTTOM)
		     (add MINTOTALHEIGHT (FONTPROP (DEFAULTFONT (QUOTE DISPLAY))
						   (QUOTE HEIGHT))
			  (COND
			    (WINDOWTITLE (FONTPROP WindowTitleDisplayStream (QUOTE HEIGHT)))
			    (T 0]
		   ((LEFT RIGHT)
		     (add MINTOTALWIDTH (TIMES 2 WBorder)))
		   NIL)

          (* The window may be specified by the user. A region or an existing window may be supplied by the caller.
	  In any case the size may have to be adjusted so that titles and and menu fit)


          [SETQ WHOLEREGION (COND
	      ((NULL WINDOWSPEC)
		(PROMPTPRINT "Specify a region for " (OR WINDOWTITLE "the window"))
		(PROG1 (GETREGION MINTOTALWIDTH MINTOTALHEIGHT)
		       (CLRPROMPT)))
	      [(REGIONP WINDOWSPEC)
		(create REGION using WINDOWSPEC WIDTH ←(IMAX MINTOTALWIDTH (fetch (REGION WIDTH)
									      of WINDOWSPEC))
				     HEIGHT ←(IMAX MINTOTALHEIGHT (fetch (REGION HEIGHT)
								     of WINDOWSPEC]
	      (T (\ILLEGAL.ARG WINDOWSPEC]                   (* Now set up the menu)
          (SELECTQ LOCATION
		   ((TOP BOTTOM)                             (* Shrink height of region by menu-occupied space to get
							     main window region)
		     (COND
		       ((EQ LOCATION (QUOTE BOTTOM))
			 (add (fetch (REGION BOTTOM) of WHOLEREGION)
			      MENUHEIGHT)))
		     (replace (REGION HEIGHT) of WHOLEREGION with (IDIFFERENCE (fetch (REGION HEIGHT)
										  of WHOLEREGION)
									       MENUHEIGHT)))
		   ((LEFT RIGHT)
		     (COND
		       ((EQ LOCATION (QUOTE LEFT))
			 (add (fetch (REGION LEFT) of WHOLEREGION)
			      MENUWIDTH)))
		     (replace (REGION WIDTH) of WHOLEREGION with (IDIFFERENCE (fetch (REGION WIDTH)
										 of WHOLEREGION)
									      MENUWIDTH)))
		   NIL)
          [ATTACHWINDOW MENUW (SETQ WINDOW (CREATEW WHOLEREGION WINDOWTITLE))
			LOCATION
			(COND
			  (VERTFLG (QUOTE TOP))
			  (T (QUOTE JUSTIFY]
          (OPENW WINDOW)
          (OPENW MENUW)
          (RETURN WINDOW])

(MENUWINDOW
  [LAMBDA (MENU VERTFLG)                                     (* rrb "27-Jun-84 10:37")
                                                             (* this function creates a window that has menu in it.
							     The window has appropriate reshape, minsize and maxsize 
							     functions.)
    (PROG (WINDOW)
          [COND
	    ((LISTP MENU)                                    (* assume its an item list)
	      (SETQ MENU (create MENU
				 ITEMS ← MENU
				 CENTERFLG ← T]
          (COND
	    [(type? MENU MENU)                               (* check to make sure the number of rows and columns are
							     set up.)
	      (COND
		((fetch MENUROWS of MENU))
		((fetch MENUCOLUMNS of MENU))
		(VERTFLG (replace (MENU MENUCOLUMNS) of MENU with 1))
		(T (replace (MENU MENUROWS) of MENU with 1]
	    (T (ERROR "arg not MENU" MENU)))                 (* update the menu image in case any of its fields were 
							     changed above.)
          (COND
	    ((NOT (NUMBERP (fetch (MENU MENUOUTLINESIZE) of MENU)))
	      (replace (MENU MENUOUTLINESIZE) of MENU with 0)))
          (UPDATE/MENU/IMAGE MENU)                           (* Now build the menu window)
          (SETQ WINDOW (ADDMENU MENU (CREATEW (CREATEREGION 0 0 (WIDTHIFWINDOW (fetch (MENU 
										       IMAGEWIDTH)
										  of MENU)
									       1)
							    (HEIGHTIFWINDOW (fetch (MENU IMAGEHEIGHT)
									       of MENU)
									    NIL 1))
					      NIL 1 T)
				NIL T))
          (WINDOWPROP WINDOW (QUOTE MINSIZE)
		      (FUNCTION MENUWMINSIZEFN))
          (WINDOWPROP WINDOW (QUOTE MAXSIZE)
		      (FUNCTION MENUWMINSIZEFN))
          (WINDOWADDPROP WINDOW (QUOTE RESHAPEFN)
			 (FUNCTION MENUWRESHAPEFN))
          (RETURN WINDOW])

(MENUWMINSIZEFN
  [LAMBDA (MENUW)                                            (* rrb "30-Dec-83 13:48")
                                                             (* returns the minimum size of a menu window.)
    (PROG ([MENU (CAR (WINDOWPROP MENUW (QUOTE MENU]
	   TITLERELATEDVAR BORDERSIZE OUTLINESIZE MINWIDTH)
          (SETQ BORDERSIZE (ITIMES (fetch (MENU MENUBORDERSIZE) of MENU)
				   2))
          (SETQ OUTLINESIZE (ITIMES (IPLUS (fetch (MENU MENUOUTLINESIZE) of MENU)
					   (WINDOWPROP MENUW (QUOTE BORDER)))
				    2))
          (SETQ MINWIDTH (ITIMES (IPLUS (MAXMENUITEMWIDTH MENU)
					BORDERSIZE 2)
				 (fetch (MENU MENUCOLUMNS) of MENU)))
                                                             (* The minimum width of the window takes into account 
							     the contents of the menu and its title)
          [COND
	    ((SETQ TITLERELATEDVAR (fetch (MENU TITLE) of MENU))
	      (SETQ MINWIDTH (IMAX MINWIDTH (STRINGWIDTH TITLERELATEDVAR (SETQ TITLERELATEDVAR
							   (MENUTITLEFONT MENU]
          (RETURN (CONS (IPLUS MINWIDTH OUTLINESIZE)
			(IPLUS OUTLINESIZE (ITIMES (fetch (MENU MENUROWS) of MENU)
						   (IPLUS BORDERSIZE (MAXMENUITEMHEIGHT MENU)))
			       (COND
				 (TITLERELATEDVAR (FONTPROP TITLERELATEDVAR (QUOTE HEIGHT)))
				 (T 0])

(MENUWRESHAPEFN
  [LAMBDA (WINDOW OLDIMAGE OLDREGION)                        (* hdj " 6-Feb-85 15:50")
                                                             (* This function takes care of size adjustments 
							     whenever the main window is reshaped.)
    (PROG ([MENU (CAR (WINDOWPROP WINDOW (QUOTE MENU]
	   INTREGION USABLEWIDTH USABLEHEIGHT NROWS NCOLUMNS XTRWIDTH XTRHEIGHT BORDER)
          (OR MENU (RETURN))
          (DELETEMENU MENU NIL WINDOW)
          (SETQ BORDER (ITIMES 2 (fetch (MENU MENUOUTLINESIZE) of MENU)))
          (SETQ USABLEWIDTH (IDIFFERENCE (fetch (REGION WIDTH) of (SETQ INTREGION (DSPCLIPPINGREGION
								      NIL WINDOW)))
					 BORDER))
          [SETQ USABLEHEIGHT (IDIFFERENCE (fetch (REGION HEIGHT) of INTREGION)
					  (COND
					    ((fetch (MENU TITLE) of MENU)
					      (IPLUS (FONTPROP (MENUTITLEFONT MENU)
							       (QUOTE HEIGHT))
						     BORDER))
					    (T BORDER]       (* calculate the largest item size that fits and the 
							     amount left over.)
          (SETQ XTRWIDTH (IDIFFERENCE USABLEWIDTH (ITIMES [replace ITEMWIDTH of MENU
							     with (IQUOTIENT USABLEWIDTH
									     (SETQ NCOLUMNS
									       (fetch MENUCOLUMNS
										  of MENU]
							  NCOLUMNS)))
          (SETQ XTRHEIGHT (IDIFFERENCE USABLEHEIGHT (ITIMES [replace ITEMHEIGHT of MENU
							       with (IQUOTIENT USABLEHEIGHT
									       (SETQ NROWS
										 (fetch MENUROWS
										    of MENU]
							    NROWS)))
          (UPDATE/MENU/IMAGE MENU)                           (* black out the window so the extra part of the window
							     will not stand out.)
          (DSPFILL NIL BLACKSHADE (QUOTE REPLACE)
		   WINDOW)                                   (* put the menu image centered in the window)
          (ADDMENU MENU WINDOW (create POSITION
				       XCOORD ←(IQUOTIENT XTRWIDTH 2)
				       YCOORD ←(IQUOTIENT XTRHEIGHT 2)))
          (SHOWSHADEDITEMS MENU WINDOW)
          (RETURN WINDOW])
)
(DEFINEQ

(GETPROMPTWINDOW
  [LAMBDA (MAINWINDOW #LINES FONT DONTCREATE)                (* bvm: "11-Nov-84 16:48")

          (* makes sure that MAINWINDOW has an attached promptwindow and returns it. If one already exists, it is shaped to be
	  at least #LINES high. If FONT is NIL, the font of the main window is used for the promptwindow.)


    (PROG ((PWINDOWPROP (WINDOWPROP MAINWINDOW (QUOTE PROMPTWINDOW)))
	   PWINDOW WIDTH HEIGHT OBSCUREDHEIGHT)
          [COND
	    (DONTCREATE (RETURN (CAR PWINDOWPROP)))
	    [PWINDOWPROP (SETQ PWINDOW (CAR PWINDOWPROP))
			 (COND
			   ((NOT (OPENWP PWINDOW))
			     (REATTACHPROMPTWINDOW MAINWINDOW PWINDOW)))
			 (COND
			   ((AND #LINES (IGREATERP #LINES (CDR PWINDOWPROP)))
                                                             (* Window exists, but not big enough)
			     [SHAPEW PWINDOW (create REGION
						using (WINDOWPROP PWINDOW (QUOTE REGION))
						      HEIGHT ←(SETQ HEIGHT
							(HEIGHTIFWINDOW (TIMES #LINES
									       (FONTPROP
										 (DSPFONT NIL PWINDOW)
										 (QUOTE HEIGHT]
			     (RPLACD PWINDOWPROP #LINES)     (* Fall through to check visibility)
			     )
			   (T (RETURN PWINDOW]
	    (T (SETQ PWINDOW (CREATEW [create REGION
					      LEFT ← 0
					      BOTTOM ← 0
					      WIDTH ←(fetch (REGION WIDTH) of (WINDOWREGION 
										       MAINWINDOW))
					      HEIGHT ←(SETQ HEIGHT
						(HEIGHTIFWINDOW (TIMES (OR #LINES (SETQ #LINES 1))
								       (FONTPROP
									 (OR FONT (SETQ FONT
									       (DSPFONT NIL 
										       MAINWINDOW)))
									 (QUOTE HEIGHT]
				      NIL NIL T))
	       (DSPSCROLL T PWINDOW)
	       (DSPFONT FONT PWINDOW)
	       (WINDOWPROP PWINDOW (QUOTE PAGEFULLFN)
			   (QUOTE NILL))
	       (REATTACHPROMPTWINDOW MAINWINDOW PWINDOW)
	       (WINDOWPROP MAINWINDOW (QUOTE PROMPTWINDOW)
			   (CONS PWINDOW #LINES))
	       (WINDOWPROP PWINDOW (QUOTE OPENFN)
			   (FUNCTION \PROMPTWINDOW.OPENFN]
          [COND
	    ((ILESSP [SETQ OBSCUREDHEIGHT (IDIFFERENCE SCREENHEIGHT (fetch (REGION TOP)
								       of (WINDOWPROP PWINDOW
										      (QUOTE REGION]
		     0)                                      (* Promptwindow off screen at top, so slip window group
							     down to make it visible)
	      (RELMOVEW MAINWINDOW (create POSITION
					   XCOORD ← 0
					   YCOORD ← OBSCUREDHEIGHT]
          (WINDOWPROP PWINDOW (QUOTE MINSIZE)
		      (CONS 0 HEIGHT))
          (WINDOWPROP PWINDOW (QUOTE MAXSIZE)
		      (CONS 64000 HEIGHT))
          (OPENW PWINDOW)
          (RETURN PWINDOW])

(\PROMPTWINDOW.OPENFN
  [LAMBDA (WINDOW)                                           (* bvm: "11-Nov-84 15:52")

          (* * Called when WINDOW is opened. WINDOW had been closed, and hence detached, from its main window, but perhaps 
	  somebody still had a handle on it and is now printing to it. Look for an open window whose promptwindow is this 
	  window.)


    (OR (WINDOWPROP WINDOW (QUOTE MAINWINDOW))
	(for MAINW in (OPENWINDOWS) bind PWINDOWPROP when (AND (SETQ PWINDOWPROP (WINDOWPROP
								   MAINW
								   (QUOTE PROMPTWINDOW)))
							       (EQ (CAR PWINDOWPROP)
								   WINDOW))
	   do (RETURN (REATTACHPROMPTWINDOW MAINW WINDOW])

(REATTACHPROMPTWINDOW
  [LAMBDA (MAINWINDOW PWINDOW)                               (* bvm: "11-Nov-84 15:50")
    (ATTACHWINDOW PWINDOW MAINWINDOW (QUOTE TOP)
		  (QUOTE JUSTIFY)
		  (QUOTE LOCALCLOSE])

(REMOVEPROMPTWINDOW
  [LAMBDA (MAINWINDOW)                                     (* rrb "23-Oct-85 13:56")
    (PROG (PWINDOW)
	LP  [COND
	      ((SETQ PWINDOW (WINDOWPROP MAINWINDOW (QUOTE PROMPTWINDOW)
					     NIL))
		(WINDOWDELPROP (SETQ PWINDOW (CAR PWINDOW))
				 (QUOTE OPENFN)
				 (FUNCTION \PROMPTWINDOW.OPENFN))
		(DETACHWINDOW PWINDOW)
		(RETURN (CLOSEW PWINDOW]
	    (COND
	      ((NEQ MAINWINDOW (SETQ MAINWINDOW (MAINWINDOW MAINWINDOW)))
		(GO LP])
)
(DECLARE: DONTCOPY DOEVAL@COMPILE 
[DECLARE: EVAL@COMPILE 

(RECORD RESHAPINGWINDOWDATA (ATTACHEDW (ATEDGE . ATWHEREONEDGE)
                                       (ATMINX . ATMINY)
                                       (ATMAXX . ATMAXY)
                                       (ATXSIZE . ATYSIZE)
                                       (ATNOWX . ATNOWY)))
]

(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS WindowMenu WindowTitleDisplayStream WBorder WindowMenuCommands)
)
)
(PUTPROPS ATTACHEDWINDOW COPYRIGHT ("Xerox Corporation" 1983 1984 1985 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (1983 10975 (ATTACHWINDOW 1993 . 5395) (ATTACHEDWINDOWS 5397 . 6194) (ALLATTACHEDWINDOWS
 6196 . 6643) (DETACHWINDOW 6645 . 7910) (DETACHALLWINDOWS 7912 . 8342) (FREEATTACHEDWINDOW 8344 . 
9619) (MAINWINDOW 9621 . 10211) (REMOVEWINDOW 10213 . 10556) (REPOSITIONATTACHEDWINDOWS 10558 . 10973)
) (10976 79245 (ATTACHEDWINDOWREGION 10986 . 11580) (ATTACHEDWINDOWTOTOPFN 11582 . 12000) (
CENTERINHEIGHT 12002 . 12455) (CENTERINWIDTH 12457 . 12904) (CENTRALWINDOW 12906 . 13358) (
CLOSEATTACHEDWINDOWS 13360 . 13781) (DOATTACHEDWINDOWCOM 13783 . 15153) (DOATTACHEDWINDOWCOM2 15155 . 
15480) (DOMAINWINDOWCOMFN 15482 . 15926) (EXPANDATTACHEDWINDOWS 15928 . 16647) (MAKEMAINWINDOW 16649
 . 18705) (MAXATTACHEDWINDOWEXTENT 18707 . 21985) (MAXIMUMMAINWINDOWSIZE 21987 . 22546) (
MAXIMUMWINDOWSIZE 22548 . 23142) (MINATTACHEDWINDOWEXTENT 23144 . 26184) (MINIMUMMAINWINDOWSIZE 26186
 . 26871) (MOVEATTACHEDWINDOWS 26873 . 27365) (MOVEATTACHEDWINDOWTOPLACE 27367 . 33643) (
OPENATTACHEDWINDOWS 33645 . 34212) (RESHAPEALLWINDOWS 34214 . 40851) (\TOTALPROPOSEDSIZE 40853 . 42074
) (SHRINKATTACHEDWINDOWS 42076 . 42686) (TOPATTACHEDWINDOWS 42688 . 43083) (UNMAKEMAINWINDOW 43085 . 
43979) (UPIQUOTIENT 43981 . 44323) (WINDOWPOSITION 44325 . 44627) (WINDOWSIZE 44629 . 45190) (
\ALLOCMINIMUMSIZES 45192 . 52149) (\ALLOCSPACETOGROUPEDWINDOWS 52151 . 52642) (\TOTALFIXEDHEIGHT 52644
 . 53448) (\TOTALFIXEDWIDTH 53450 . 54305) (\ALLOCHEIGHTTOGROUPEDWINDOW 54307 . 58175) (
\ALLOCWIDTHTOGROUPEDWINDOW 58177 . 61798) (\ATWGROUPSIZE 61800 . 62559) (\BREAKAPARTATWSTRUCTURE 62561
 . 62951) (\BUILDATWSTRUCTURE 62953 . 66081) (\LIMITBYMAX 66083 . 66244) (\LIMITBYMIN 66246 . 66511) (
\MAXHEIGHTOFGROUP 66513 . 67229) (\MAXWIDTHOFGROUP 67231 . 67945) (\RESHAPEATTACHEDWINDOWSAROUNDMAINW 
67947 . 73202) (\SETGROUPMIN 73204 . 76759) (\SETWINFOXSIZE 76761 . 77370) (\SETWINFOYSIZE 77372 . 
78202) (\SHAREOFXTRAX 78204 . 78696) (\SHAREOFXTRAY 78698 . 79243)) (79246 89079 (ATTACHMENU 79256 . 
79911) (CREATEMENUEDWINDOW 79913 . 83600) (MENUWINDOW 83602 . 85472) (MENUWMINSIZEFN 85474 . 86819) (
MENUWRESHAPEFN 86821 . 89077)) (89080 93495 (GETPROMPTWINDOW 89090 . 91967) (\PROMPTWINDOW.OPENFN 
91969 . 92713) (REATTACHPROMPTWINDOW 92715 . 92945) (REMOVEPROMPTWINDOW 92947 . 93493)))))
STOP