(FILECREATED "24-Sep-86 14:03:16" {ERIS}<LISPCORE>SOURCES>ATTACHEDWINDOW.;23 135381 

      changes to:  (FNS MINIMUMMAINWINDOWSIZE)

      previous date: " 2-May-86 16:01:14" {ERIS}<LISPCORE>SOURCES>ATTACHEDWINDOW.;22)


(* 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.EXPAND \PROMPTWINDOW.SET.HEIGHT \PROMPTWINDOW.OPENFN 
             \PROMPTWINDOW.PAGEFULLFN 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 "24-Sep-86 14:03")
                                                             (* returns the minimum extent of a 
                                                             window)
    (PROG [(EXT (WINDOWPROP WINDOW (QUOTE MAINWINDOWMINSIZE]
          [COND
             [(NULL EXT)
              (SETQ EXT (CONS 26 (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: " 2-May-86 15:27")
          
          (* 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 HEIGHT PAGEFULLFN)
          [COND
             (DONTCREATE (RETURN (CAR PWINDOWPROP]
          [SETQ FONT (COND
                        (FONT (FONTCREATE FONT))
                        (T (DSPFONT NIL (OR (CAR PWINDOWPROP)
                                            MAINWINDOW]
          (COND
             [#LINES (COND
                        ((EQ #LINES T)                       (* Infinitely expandable window)
                         (SETQ PAGEFULLFN (FUNCTION \PROMPTWINDOW.PAGEFULLFN))
                         (SETQ #LINES 1))
                        [(STRINGP #LINES)                    (* Big enough for this string)
                         (LET ([MAINWIDTH (fetch (REGION WIDTH) of (OR (CAR PWINDOWPROP)
                                                                       (WINDOWREGION MAINWINDOW]
                               (STRWIDTH (STRINGWIDTH #LINES FONT)))
                              (SETQ #LINES (IQUOTIENT (IPLUS STRWIDTH (SUB1 MAINWIDTH))
                                                  MAINWIDTH]
                        ((FIXP #LINES))
                        (T (\ILLEGAL.ARG #LINES]
             (T (SETQ #LINES 1)))
          (COND
             [PWINDOWPROP (SETQ PWINDOW (CAR PWINDOWPROP))
                    (COND
                       ((NOT (OPENWP PWINDOW))
                        (REATTACHPROMPTWINDOW MAINWINDOW PWINDOW)))
                    (COND
                       ((IGREATERP #LINES (CDR PWINDOWPROP)) (* Window exists, but not big enough)
                        (\PROMPTWINDOW.EXPAND PWINDOWPROP #LINES]
             (T (SETQ PWINDOW (CREATEW [create REGION
                                              LEFT ← 0
                                              BOTTOM ← 0
                                              WIDTH ←(fetch (REGION WIDTH) of (WINDOWREGION 
                                                                                     MAINWINDOW))
                                              HEIGHT ←(SETQ HEIGHT (HEIGHTIFWINDOW
                                                                    (TIMES #LINES (FONTPROP
                                                                                   FONT
                                                                                   (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))
                (\PROMPTWINDOW.SET.HEIGHT PWINDOW HEIGHT)
                (OPENW PWINDOW)))
          (AND PAGEFULLFN (WINDOWPROP PWINDOW (QUOTE PAGEFULLFN)
                                 PAGEFULLFN))
          (RETURN PWINDOW])

(\PROMPTWINDOW.EXPAND
  [LAMBDA (PWINDOWPROP #LINES)                               (* bvm: " 2-May-86 14:59")
          
          (* * Expand the PWINDOWPROP = (window . nlines) to be #LINES high)

    (LET*[(PWINDOW (CAR PWINDOWPROP))
          (HEIGHT (HEIGHTIFWINDOW (TIMES #LINES (FONTPROP PWINDOW (QUOTE HEIGHT]
     (SHAPEW PWINDOW (create REGION using (WINDOWPROP PWINDOW (QUOTE REGION))
                                          HEIGHT ← HEIGHT))
     (RPLACD PWINDOWPROP #LINES)
     (\PROMPTWINDOW.SET.HEIGHT PWINDOW HEIGHT])

(\PROMPTWINDOW.SET.HEIGHT
  [LAMBDA (PWINDOW HEIGHT)                                   (* bvm: " 2-May-86 14:57")
          
          (* * Sets prompt window's height to be HEIGHT --
          makes window inflexible and coerces it onto screen if it is off)

    (LET [(OBSCUREDHEIGHT (IDIFFERENCE SCREENHEIGHT (fetch (REGION TOP) of (WINDOWPROP PWINDOW
                                                                                  (QUOTE REGION]
         [COND
            ((ILESSP OBSCUREDHEIGHT 0)                       (* Promptwindow off screen at top, so 
                                                             slip window group down to make it 
                                                             visible)
             (RELMOVEW (MAINWINDOW PWINDOW)
                    (create POSITION
                           XCOORD ← 0
                           YCOORD ← OBSCUREDHEIGHT]
         (WINDOWPROP PWINDOW (QUOTE MINSIZE)
                (CONS 0 HEIGHT))
         (WINDOWPROP PWINDOW (QUOTE MAXSIZE)
                (CONS 64000 HEIGHT])

(\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])

(\PROMPTWINDOW.PAGEFULLFN
  [LAMBDA (WINDOW)                                           (* bvm: " 2-May-86 14:59")
          
          (* * Called to automatically expand a prompt window)

    (LET*((PWINDOWPROP (WINDOWPROP (MAINWINDOW WINDOW)
                              (QUOTE PROMPTWINDOW)))
          (#LINES (CDR PWINDOWPROP)))
     (AND #LINES (\PROMPTWINDOW.EXPAND PWINDOWPROP (ADD1 #LINES])

(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 (2077 12106 (ATTACHWINDOW 2087 . 5002) (ATTACHEDWINDOWS 5004 . 5846) (ALLATTACHEDWINDOWS
 5848 . 6429) (DETACHWINDOW 6431 . 7986) (DETACHALLWINDOWS 7988 . 8580) (FREEATTACHEDWINDOW 8582 . 
10517) (MAINWINDOW 10519 . 11211) (REMOVEWINDOW 11213 . 11671) (REPOSITIONATTACHEDWINDOWS 11673 . 
12104)) (12107 112747 (ATTACHEDWINDOWREGION 12117 . 12791) (ATTACHEDWINDOWTOTOPFN 12793 . 13345) (
CENTERINHEIGHT 13347 . 13959) (CENTERINWIDTH 13961 . 14567) (CENTRALWINDOW 14569 . 15162) (
CLOSEATTACHEDWINDOWS 15164 . 15845) (DOATTACHEDWINDOWCOM 15847 . 17852) (DOATTACHEDWINDOWCOM2 17854 . 
18298) (DOMAINWINDOWCOMFN 18300 . 18868) (EXPANDATTACHEDWINDOWS 18870 . 19774) (MAKEMAINWINDOW 19776
 . 21940) (MAXATTACHEDWINDOWEXTENT 21942 . 26950) (MAXIMUMMAINWINDOWSIZE 26952 . 27642) (
MAXIMUMWINDOWSIZE 27644 . 28399) (MINATTACHEDWINDOWEXTENT 28401 . 33051) (MINIMUMMAINWINDOWSIZE 33053
 . 33858) (MOVEATTACHEDWINDOWS 33860 . 34443) (MOVEATTACHEDWINDOWTOPLACE 34445 . 42989) (
OPENATTACHEDWINDOWS 42991 . 43941) (RESHAPEALLWINDOWS 43943 . 54755) (\TOTALPROPOSEDSIZE 54757 . 56375
) (SHRINKATTACHEDWINDOWS 56377 . 57169) (TOPATTACHEDWINDOWS 57171 . 57766) (UNMAKEMAINWINDOW 57768 . 
58840) (UPIQUOTIENT 58842 . 59307) (WINDOWPOSITION 59309 . 59655) (WINDOWSIZE 59657 . 60474) (
\ALLOCMINIMUMSIZES 60476 . 72353) (\ALLOCSPACETOGROUPEDWINDOWS 72355 . 72953) (\TOTALFIXEDHEIGHT 72955
 . 73830) (\TOTALFIXEDWIDTH 73832 . 74734) (\ALLOCHEIGHTTOGROUPEDWINDOW 74736 . 80732) (
\ALLOCWIDTHTOGROUPEDWINDOW 80734 . 86346) (\ATWGROUPSIZE 86348 . 87634) (\BREAKAPARTATWSTRUCTURE 87636
 . 88140) (\BUILDATWSTRUCTURE 88142 . 93486) (\LIMITBYMAX 93488 . 93651) (\LIMITBYMIN 93653 . 93912) (
\MAXHEIGHTOFGROUP 93914 . 94694) (\MAXWIDTHOFGROUP 94696 . 95474) (\RESHAPEATTACHEDWINDOWSAROUNDMAINW 
95476 . 103627) (\SETGROUPMIN 103629 . 109009) (\SETWINFOXSIZE 109011 . 110010) (\SETWINFOYSIZE 110012
 . 111396) (\SHAREOFXTRAX 111398 . 112034) (\SHAREOFXTRAY 112036 . 112745)) (112748 127239 (ATTACHMENU
 112758 . 113605) (CREATEMENUEDWINDOW 113607 . 119181) (MENUWINDOW 119183 . 122012) (MENUWMINSIZEFN 
122014 . 123922) (MENUWRESHAPEFN 123924 . 127237)) (127240 134819 (GETPROMPTWINDOW 127250 . 130777) (
\PROMPTWINDOW.EXPAND 130779 . 131343) (\PROMPTWINDOW.SET.HEIGHT 131345 . 132456) (\PROMPTWINDOW.OPENFN
 132458 . 133536) (\PROMPTWINDOW.PAGEFULLFN 133538 . 133962) (REATTACHPROMPTWINDOW 133964 . 134200) (
REMOVEPROMPTWINDOW 134202 . 134817)))))
STOP