






                       _T_h_e PICASSO _A_p_p_l_i_c_a_t_i_o_n _F_r_a_m_e_w_o_r_k|-

                  _L_a_w_r_e_n_c_e _A. _R_o_w_e, _J_o_e _K_o_n_s_t_a_n, _B_r_i_a_n _S_m_i_t_h,
                           _S_t_e_v_e _S_e_i_t_z, _a_n_d _C_h_u_n_g _L_i_u
                         Computer Science Division-EECS
                            University of California
                               Berkeley, CA 94720




                                    _A_b_s_t_r_a_c_t


               PICASSO is a graphical user interface development  sys-
          tem  that  includes  an interface toolkit and an application
          framework.  The application  framework  provides  high-level
          abstractions  including  modal  dialog  boxes  and non-modal
          frames  and  panels  similar  to  conventional   programming
          language procedures and co-routines.  These abstractions can
          be used to define objects that have local variables and that
          can be called with parameters.

               PICASSO also has a constraint system that  is  used  to
          bind  program  variables  to widgets, to implement triggered
          behaviors, and to implement multiple  views  of  data.   The
          system  is  implemented in Common Lisp using the Common Lisp
          Object System and the CLX interface to the X Window System.

          _1.  _I_n_t_r_o_d_u_c_t_i_o_n

               PICASSO is a graphical user interface development  sys-
          tem  that  includes  an interface toolkit and an application
          framework.  The toolkit contains  a  library  of  predefined
          interface  abstractions  (e.g.,  buttons, scrollbars, menus,
          forms, etc.), geometry managers, and  a  constraint  system.
          The  application  framework provides high-level abstractions
          and other  infrastructure  to  support  the  development  of
          graphical user interface applications.

          The PICASSO framework includes five object  types:  applica-
          tions, forms, frames, dialog boxes, and panels.  An _a_p_p_l_i_c_a_-
          _t_i_o_n is composed of a collection of  frames,  dialog  boxes,
          and  panels.   A _f_o_r_m contains fields through which data can
          be displayed, entered, or  edited  by  the  user.   A  _f_r_a_m_e
          ____________________
             |- This research was supported  by  the  National  Science
          Foundation  under grants DCR-85-07256 and MIP-87-15557.  The
          second author was supported by  a  NDSEG  fellowship  admin-
          istered by DARPA.





                                       1










          specifies the primary application interface.  It contains  a
          form and a menu of operations the user can execute. A _d_i_a_l_o_g
          _b_o_x is a modal interface that solicits additional  arguments
          for  an  operation  or  user confirmation before executing a
          possibly dangerous operation (e.g.,  deleting  a  file).   A
          _p_a_n_e_l  is  a  nonmodal dialog box that typically presents an
          alternative view of data in a frame or another panel.

               Figure 1 shows a screen dump of  a  sample  application
          that displays information about employees  and  departments.
          The  frame, shown on the left, displays information about an
          employee.  It contains a form with fields that describe  the
          employee  (e.g.,  name,  age,  etc.).   Above  the form is a
          menu-bar with pull-down menus that  contain  operations  the
          user  can  execute.   The buttons at the bottom of the frame
          allow the user to step through the employees  in  the  data-
          base.  The panel on the right displays information about the
          department to which the employee belongs.  At the top of the
          panel  is a hierarchy browser that lists departments and the
          employees in a selected department.  Information  about  the
          department  that  the  current  employee belongs to is shown

          ____________________________________________________________

























                Figure 1: Example PICASSO application interface.
          ____________________________________________________________





                                       2










          below the browser.  The department information includes  the
          manager  and  a  graphics field that shows a floor plan with
          the selected employee  and  his  or  her  manager's  offices
          highlighted.   If the user selects a button at the bottom of
          the frame to display the previous or next employee and  that
          employee is in a different department, the department infor-
          mation in the panel is automatically changed (i.e., the data
          displayed through the frame and panel are synchronized).

               PICASSO is an  object-oriented  system  implemented  in
          Common  Lisp  that runs on the X Window System [ScG86].  The
          toolkit, framework, and user applications are implemented as
          Common  Lisp  Object  System (CLOS) objects [Kee88].  A CLOS
          class is defined for each type of  framework  object  (e.g.,
          application, frame, form, dialog box, and panel).  Instances
          of these classes are called PICASSO objects (PO's).  Each PO
          type  has a different visualization and control regime.  The
          toolkit widgets that implement the visualization and control
          (e.g., title bars, buttons and menus) are automatically gen-
          erated when a PO is created.

               PO's are similar to procedures and functions in a  con-
          ventional  programming  language.   They  have a name, local
          variables, formal arguments, and a lexical parent.  A PO can
          be  called and arguments passed to it which causes the PO to
          allocate space for its  local  variables  and  to  create  X
          resources  to display the values of selected variables.  The
          user can examine and edit the data or execute code  attached
          to  buttons and menu operations.  Code can be arbitrary Lisp
          expressions that can, for  example,  change  the  values  of
          variables,  call  other  PO's,  return to the calling PO, or
          call a Lisp function.

               PO's are analogous  to  familiar  programming  language
          concepts  (e.g.,  procedures,  functions,  and co-routines).
          Frames are similar to procedures.  Only  one  frame  can  be
          active  at  a  time.   Calling  a frame conceals the current
          frame and displays the new frame.  Returning from the called
          frame  redisplays the calling frame.  Dialog boxes are simi-
          lar to functions.  Calling a dialog box displays it and  the
          user  is forced to respond.  A dialog box returns a value to
          the caller when it returns (e.g., ``ok'').  Panels are simi-
          lar  to  co-routines.   Calling  a  panel  displays  it in a
          separate window and the user can interact  with  it  or  any
          other  frame  or  panel.   The  location of the mouse cursor
          determines which frame or panel receives user inputs.

               Variables can be passed to a PO as  parameters  in  the
          call.   For example, the current employee in the frame above
          is passed to the panel by reference so that the value can be
          changed  in either the frame or panel and the update will be
          propagated to  the  other  PO.   Traditional  _v_a_l_u_e,  _v_a_l_u_e-



                                       3










          _r_e_s_u_l_t,  and  _r_e_f_e_r_e_n_c_e  parameter passing are provided.  In
          addition, two new mechanisms  are  provided  that  implement
          different kinds of synchronization.  _V_a_l_u_e/_u_p_d_a_t_e parameters
          are similar  to  _v_a_l_u_e  parameters  except  that  subsequent
          updates to the actual argument are propagated to the copy in
          the  called   PO.    _V_a_l_u_e-_r_e_s_u_l_t/_u_p_d_a_t_e   is   similar   to
          _v_a_l_u_e/_u_p_d_a_t_e  except the value is copied back to the calling
          environment when the PO returns.   These  parameter  passing
          mechanisms  can  be  used  when changes to a value displayed
          through a panel should not be immediately propagated back to
          the  caller,  but  changes  to the actual argument should be
          propagated into the panel.

               PO's are stored in an external database and loaded into
          the  application  when needed.  They are shared by different
          applications because the database is shared.  Commonly  used
          PO's  (e.g.,  a  file directory browser and an error message
          dialog box) are provided to maintain  interface  consistency
          between different applications.

               PICASSO provides capabilities that are similar to other
          application  frameworks including Garnet [Mye89], InterViews
          [Lin89b], MacApp [Sch86], and  Smalltalk  [Gol83].   PICASSO
          differs  from  these frameworks in that it clearly separates
          the framework layer from the toolkit layer.   The  framework
          provides support for defining and accessing local variables,
          binding variables to fields in a form, and  passing  parame-
          ters to other PO's.  These mechanisms encourage the develop-
          ment of reusable interface components.  Parameter passing is
          used  to  specify  bindings  between variables and different
          views (i.e., dialog boxes, frames, and  panels).   Parameter
          passing  is implemented by a constraint system that is simi-
          lar to the constraint systems in Grow [Bar86],  ThingLab  II
          [Mae89],  and Garnet.  The constraint system is also used to
          specify interface abstractions (e.g., scrollbars) as in Gar-
          net.

               A PICASSO frame is  similar  to  the  Smalltalk  Model-
          View-Controller (MVC) abstraction [KrP88].  A frame contains
          local variables which correspond to the model.  The form  in
          a  frame  is  the view.  And, a frame implicitly defines the
          controller. Multiple views of the same data can  be  created
          by  calling  a panel and passing the appropriate local vari-
          able.  The way a variable is passed  determines  whether  or
          not  and when view updates are propagated back to the frame.
          The Navigator Framework extension to MVC developed at  Parc-
          Place Systems provides a similar capability.

               We believe that using conventional programming language
          abstractions  will  simplify  the  problem  of designing and
          implementing direct manipulation interfaces.   In  addition,
          we  believe the PICASSO framework is easier to learn and use



                                       4










          than the Smalltalk MVC and  Navigator  abstractions  because
          the  application  developer  can  use  familiar  programming
          abstractions (e.g., variables and parameter passing)  rather
          than  unfamiliar  abstractions (e.g., active values and mes-
          sage passing).

               This paper describes the PICASSO framework and program-
          ming  model.  The programming constructs described below are
          shown as extensions to Lisp.  Most users will not see  these
          textual  specifications because a direct manipulation inter-
          face builder is being developed to create and modify  appli-
          cations.   The  interface  builder can be used to define any
          PO.  Forms are defined by selecting widgets from  a  palette
          and  placing  them  at the desired location in a window with
          the mouse.  Field attributes (e.g., border, default  values,
          etc.)  can be changed interactively.  Similar interfaces are
          provided to define other PO types and code.  The toolkit and
          interface  builder are extensible so that developers can add
          new interface abstractions to the system.  The  toolkit  and
          interface builder are described elsewhere [Koe90].

               The remainder of the paper  is  organized  as  follows.
          Section  2  describes  a  sample  tool  used  to  illustrate
          features of the application framework.  Section 3  describes
          the  framework  model  and sections 4 through 6 describe the
          different types of PO's.  Section 7 describes  the  program-
          ming  constructs  used  to  implement operations.  Section 8
          discusses the implementation of PICASSO and describes appli-
          cations  written  with  it.  Lastly, section 9 concludes the
          paper.

          _2.  _A_n _E_x_a_m_p_l_e _A_p_p_l_i_c_a_t_i_o_n

               The personnel browser shown in figure 1 will be used to
          illustrate  how  an  application  is  defined using PICASSO.
          Figure 2 shows the initial frame in  the  application.   The
          user  can scroll through the employees by using the Previous
          and Next buttons in the form.

               The Search menu shown in figure 3  contains  operations
          that  let  the  user search for an employee on any attribute
          (e.g., age or department).  For example,  selecting  the  By
          Age...  menu  operation calls the dialog box shown in figure
          4.  The user enters the desired age in the type-in field and
          presses  the Ok button which returns from the dialog box and
          changes the display to the employee closest in  age  to  the
          value entered. The Previous and Next buttons now search for-
          wards and backwards by age.  This search order can  also  be
          changed by using the pop-up menu as shown in figure 5.

               Department information can be  displayed  by  selecting
          the Department... operation in the Show menu which calls the



                                       5











          ____________________________________________________________






















                             Figure 2:  Tool Window
          ____________________________________________________________





























                                       6










          ____________________________________________________________




















                             Figure 3:  Search Menu
          ____________________________________________________________


          ____________________________________________________________




















                          Figure 4:  Search Dialog Box
          ____________________________________________________________


          department panel shown in figure 1. This  panel  contains  a
          hierarchy  browser, textual information, and a floor plan of



                                       7










          the department. If the user  selects  a  department  in  the
          hierarchy  browser,  the  employees  in  that department are
          displayed.  The floor plan highlights  the  offices  of  the
          current employee and his or her manager.  The buttons on the
          right allow the user to change the current  employee  either
          to  the  selected  employee  in the hierarchy browser or the
          current employee's manager or to close the  panel.  Changing
          the  current  employee  causes the data in the frame and the
          panel to be changed.

          _3.  _T_h_e PICASSO _P_r_o_g_r_a_m_m_i_n_g _M_o_d_e_l

               A PICASSO application, called a _t_o_o_l, is composed of  a
          collection of frames, dialog boxes, and panels. This section
          describes these PO's and provides an overview  of  the  pro-
          gramming  constructs used to implement the semantics of but-
          tons and menu operations.

               A form is an input/output abstraction that  corresponds
          to  a paper form.  It contains fields through which data can
          be displayed and edited by the user. Data can  be  displayed
          in  a field using text in different fonts, images, and draw-
          ings.  Each form maintains a field visit order  and  current
          field  and  manages  the keyboard focus. When the user moves
          the mouse into the form, the  keyboard  is  focused  to  the
          current  field.  The  user  can  change the current field by
          selecting another field with the mouse or by using  keyboard

          ____________________________________________________________



















                          Figure 5:  Search Order Menu
          ____________________________________________________________





                                       8










          commands to move to the next or previous field.

               Forms also contain display-only labels  and  decorative
          trim  (e.g., lines and backgrounds).  Fields are implemented
          by widgets  and  trim  is  implemented  by  gadgets  in  the
          toolkit.   Widgets are input/output abstractions and gadgets
          are  output-only  abstractions.   In  addition,  a  geometry
          manager  for  the  form  must  be  specified.   The geometry
          manager is responsible  for  repositioning  the  fields  and
          labels when a form is resized.

               Forms can be used in frames, panels, and dialog  boxes.
          Alternatively,  an  implicitly  defined  form  can  be  used
          instead by specifying the widgets and gadgets and a geometry
          manager.   The widgets and gadgets are called _c_h_i_l_d_r_e_n.  The
          term widget is used below to refer to  a  field,  label,  or
          trim in a form.

               A frame is a  control  abstraction  that  implements  a
          major tool mode or operation.  It contains a form and opera-
          tions the user can execute. Pull-down menus at  the  top  of
          the  frame  hold  the  operations which can perform computa-
          tions, change values displayed through the  form,  and  call
          dialog  boxes,  panels, or other frames.  A tool may contain
          many frames, but only one is active at any time.

               A dialog box is a control abstraction that requires  an
          immediate  response  from  the  user. It requests additional
          information needed to complete an operation or notifies  the
          user  about  an error that has occurred or might occur.  The
          dialog box is displayed in a separate window that  is  posi-
          tioned  on top of the PO that called it.  Moreover, the user
          is forced to enter data into it.  A dialog  box  contains  a
          form and a list of operations that are displayed in a column
          of buttons down the right side of the dialog box.

               A panel is a non-modal control abstraction that is used
          to  view  or  edit  data.   It contains a form and a list of
          operations that can be displayed either in a menu-bar at the
          top of the panel like a frame or in a column of buttons down
          the right side  like  a  dialog  box.   The  data  displayed
          through  the  form is typically displayed in a different way
          in the frame or another panel. For example,  the  department
          information displayed in the panel in the sample application
          also displays information about the current employee.   Many
          panels  may  be  active  at once.  The location of the mouse
          cursor determines whether one of the  panels  or  the  frame
          receives  input.  Several  copies  of  the same panel can be
          active at the same time. For example, a word processor might
          use  a panel to allow the user to edit style properties of a
          block of text (e.g., font, typeface, etc.).  The same  panel
          can  be  called  with different text blocks so that the user



                                       9










          can edit style properties of the blocks at the same time.

               Static and dynamic variables can be declared in any PO.
          These  variables  hold  data displayed to the user through a
          form as well as other internal data for used by the applica-
          tion.  Static  variables persist between calls to a PO. They
          are allocated when the PO is created.  Dynamic variables are
          allocated  each  time a PO is called and deallocated when it
          returns.[1] Named constants can also be declared.

               PICASSO uses lexical scoping. The lexical parent  of  a
          PO is the object in which it is declared.  A variable refer-
          ence that cannot be resolved locally is searched for in  the
          parent.  For example, if a variable is referenced in a form,
          but not defined there, the parent is searched for the  vari-
          able, followed by the parent's parent and so forth until the
          tool is reached.  If the variable is not found in the  tool,
          an error is signaled.

               Variables can be used in left- or right-value  contexts
          by  using  the  Lisp  function  value.   For  example, given
          PICASSO variables x and y, the following code assigns  y  to
          x:

              (setf (value 'x) (value 'y))

          A Lisp reader macro #! is provided  to  simplify  the  code.
          The previous example is normally specified by

              (setf #!x #!y)

          Another reader macro  (#?)  is  provided  that  returns  the
          address of a PICASSO variable.  This macro is needed so that
          PICASSO variables can be passed by reference.   The  use  of
          reference variables is described below.

               Parameter passing is used to pass values to other  PO's
          when  they  are  called.   A dynamic variable is created for
          each formal parameter.   The  parameter  passing  mechanisms
          provided  include: value, value/update, value-result, value-
          result/update,  and  reference.  Value,  value-result,   and
          reference  are  the  parameter  passing  mechanisms found in
          traditional programming languages.  Value/update  parameters
          are  passed  by  value.  Changes to the actual parameter are
          propagated   to   the   local   copy.    Value-result/update
          ____________________
             [1] Actually, dynamic variables are not deallocated  when
          a  PO  returns  because it takes a long time to re-establish
          bindings defined on them.  It is more efficient to reuse the
          same variable on subsequent calls after re-initializing it.





                                       10










          parameters have the same semantics, except the local copy is
          copied  back  to the actual parameter in the caller when the
          PO returns.  These parameter types are useful when  display-
          ing  different  views  of  a data structure through a panel,
          frame, or dialog box. A PO that implements an editable  view
          is  passed the data by reference so that changes are immedi-
          ately propagated to the caller.   A  PO  that  implements  a
          non-editable   view   is   passed   the  data  by  value  or
          value/update depending on whether changes made to  the  data
          through  other  views  should  be  propagated  to this view.
          Updates  to  data   passed   by   value-result   or   value-
          result/update are deferred until the user executes an opera-
          tion that returns from the PO.

               The design of PICASSO  encourages  the  development  of
          reusable  interface  abstractions.   We expect that general-
          purpose panels and dialog boxes (e.g.,  table  browsers  and
          prompters)  will  be  developed  and reused in many applica-
          tions. Similarly, forms can be reused in  different  panels,
          dialog  boxes,  and frames. They can also be reused in other
          forms.  For example, a standard name and address block for a
          person  can  be reused in any form that displays information
          about a person.  To encourage reuse, each PO  has  a  unique
          external  name. This name is composed of three parts each of
          which is a Lisp string:

              (_p_a_c_k_a_g_e _n_a_m_e . _s_u_f_f_i_x)

          A package is a collection of related PO's. The optional suf-
          fix  is  used to identify the type of the PO. External names
          can be used to specify  a  PO  stored  in  the  database  or
          already loaded into main memory.

               Most PO's are referenced by name in the  definition  of
          their  lexical  parent which automatically loads it when the
          parent is called. A shorter internal name can  be  specified
          for  the  PO  to  simplify  the code.  In addition, internal
          names facilitate changing to a different PO since  only  the
          internal name binding has to be changed.  A function is pro-
          vided that allows an application to load a PO at run-time.

               Procedural code is used to  specify  the  semantics  of
          button  presses, menu operations, or set-up, initialization,
          or termination of a PO.  In the current implementation, this
          code is specified in Lisp.  It can reference PICASSO or Lisp
          variables and call PO's or Lisp functions or macros.

          _4.  _T_o_o_l_s

               A tool is the outermost object in an application.   The
          window  through  which the tool is displayed is managed by a
          window manager.  Iconifying this window causes all  children



                                       11










          to be concealed.

               A tool maintains a list of packages that  are  searched
          when  looking for partially-specified PO's. For example, the
          package search  list  in  the  sample  application  contains
          "paper"  and  "picasso".   The  "paper" package contains the
          PO's that define the application. The "picasso"  package  is
          automatically  included  in  all search lists by the system.
          It contains built-in PO's such as dialog boxes to prompt for
          a  file  name and to confirm a destructive operation used by
          all PICASSO applications.

               The sample application was defined by the deftool  call
          shown in figure 6.  The first line  specifies  the  external
          name and formal arguments for the tool.  The  second line is
          a documentation string.  The  remaining  lines  specify  the
          title,  package  search  list, frames, start frame, and ini-
          tialization and exit code.  The title is  displayed  in  the
          tool's  title  bar.  The  frames clause specifies the frames
          used in this application.  This tool  has  only  one  frame,
          named ("demo" . "frame"), that is bound to the internal name
          main-frame.  The frame can be found in the  "paper"  package
          so  the  external  name does not need to be fully qualified.
          The start-frame clause specifies the frame to call when  the
          application is executed.  This default can be changed by the
          initialization code.  The init-code  and  exit-code  clauses
          specify  the  code  to  be executed when the tool is run and
          when it is executed.  The sample tool opens and  closes  the
          database in these clauses.

          _5.  _F_o_r_m_s

               Forms are used in frames, panels, or dialog  boxes.   A
          form that can be reused in more than one PO, called a _p_l_u_g_g_-
          _a_b_l_e  _f_o_r_m,  is  defined  using   the   defform   _c_o_n_s_t_r_u_c_t.

          ____________________________________________________________


                         (deftool ("paper" "demo" . "tool") ()
                           "Picasso framework demo tool."
                           (title "Demo Tool")
                           (package-search-list ("paper"))
                           (frames (main-frame ("demo" . "frame")))
                           (start-frame main-frame)
                           (init-code (open-database))
                           (exit-code (close-database)))

                           Figure 6:  Tool definition
          ____________________________________________________________





                                       12










          _P_l_u_g_g_a_b_l_e _f_o_r_m_s _t_y_p_i_c_a_l_l_y _h_a_v_e _l_o_c_a_l _v_a_r_i_a_b_l_e_s  _a_n_d  _p_a_r_a_m_e_-
          _t_e_r_s _a_n_d  _l_i_k_e _a_n_y _P_O, _t_h_e_y _m_a_y _h_a_v_e _i_n_i_t_i_a_l_i_z_a_t_i_o_n _a_n_d _t_e_r_-
          _m_i_n_a_t_i_o_n _c_l_a_u_s_e_s _t_h_a_t _s_p_e_c_i_f_y _c_o_d_e _t_o _b_e _e_x_e_c_u_t_e_d  _w_h_e_n  _t_h_e
          _P_O _t_h_a_t _h_o_l_d_s _t_h_e _f_o_r_m _i_s _c_a_l_l_e_d _a_n_d _e_x_i_t_e_d, _r_e_s_p_e_c_t_i_v_e_l_y.

               The form used to browse  employee  information  in  the
          sample  tool was written as a pluggable form. The definition
          is shown in figure 7.  The form name is ("paper"  "employee"
          .  "form").   _T_h_e _c_l_a_u_s_e_s _i_n _t_h_e _f_o_r_m _d_e_f_i_n_i_t_i_o_n _s_p_e_c_i_f_y _t_h_e
          _c_h_i_l_d_r_e_n, _g_e_o_m_e_t_r_y _m_a_n_a_g_e_r _a_n_d _s_e_t-_u_p  _c_o_d_e.   _T_h_e  _c_h_i_l_d_r_e_n
          clause  specifies  the  fields and labels in the form.  Each
          "make-" _c_a_l_l _i_n_s_t_a_n_t_i_a_t_e_s _a _w_i_d_g_e_t _w_h_i_c_h _c_a_n _b_e _a _p_r_e_d_e_f_i_n_e_d
          _w_i_d_g_e_t  _o_r  _g_a_d_g_e_t _i_n _t_h_e PICASSO _t_o_o_l_k_i_t _o_r _a _n_e_w _w_i_d_g_e_t _o_r
          _g_a_d_g_e_t _d_e_f_i_n_e_d _b_y _t_h_e _u_s_e_r.  _A _f_i_e_l_d _o_r _l_a_b_e_l  _s_p_e_c_i_f_i_c_a_t_i_o_n
          _i_s  _p_r_e_c_e_d_e_d _b_y _a _s_y_m_b_o_l _i_n _s_o_m_e _c_a_s_e_s _t_o _d_e_c_l_a_r_e _a _v_a_r_i_a_b_l_e
          _b_o_u_n_d _t_o _t_h_a_t _w_i_d_g_e_t. _F_o_r _e_x_a_m_p_l_e, _d_e_p_t-_f_i_e_l_d  is  bound  to
          the  text  gadget  that  displays the name of the employee's
          department.  A gadget is used rather than a  widget  because
          the  application  does  not  allow  the  user  to change the
          department.

               The buttons at the bottom of the form (e.g.,  Previous,
          Name,  and Next) are also specified.  They are combined into
          a collection gadget so they will be arranged horizontally.

               The gm clause specifies the geometry manager which lays
          out  the  widgets  in  the form.  Many geometry managers are
          provided by the PICASSO toolkit.  Each takes a set of  widg-
          ets and optional layout parameters, called _g_e_o_m_e_t_r_y _s_p_e_c_i_f_i_-
          _c_a_t_i_o_n_s, and calculates an xy-offset for each widget  within
          its parent.

               The setup-code clause specifies code that is to be exe-
          cuted when the PO is created.  In this case, the code estab-
          lishes bindings between the variables that hold the data and
          fields  in the form through which it is displayed.  Bindings
          are also established for the buttons at the  bottom  of  the
          form that will dim Previous and Next if records do not exist
          and that reset the variable #!key to hold the search  attri-
          bute.   Recall  that  #!key  is  declared in the frame.  The
          functions used to define the bindings are described in  sec-
          tion 7.3.

               Sometimes forms are only used in a single frame, panel,
          or dialog box.  It complicates the application specification
          if the developer has to create a separately  named  form  so
          the  developer  can  specify  the  children  and  other form
          clauses directly in the frame, panel or dialog box  specifi-
          cation.  These forms are called _i_m_p_l_i_c_i_t _f_o_r_m_s and they can-
          not have local variables or parameters.  They can,  however,
          access  variables  and  parameters  in their lexical parent.
          Examples of implicit forms are presented below.



                                       13











          ____________________________________________________________


          (defform ("paper" "employee" . "form") ()
            "This form displays an employee record"
            (children
              ((make-gadget :value "Employee"
                            :geom-spec '(:top 50)
                            :font (make-font :name "gallant.r.19"))
               (make-null-gadget :geom-spec '(:top 20))
               (make-collection-gadget :geom-spec (:top 100) :gm 'rubber-gm
                 :children
                   '((picture-gadget
                     (make-image-gadget :geom-spec '(.55 0 .45 .99 :center)))
                     (make-null-gadget :geom-spec '(:top 20))
                     (name-field
                       (make-text-gadget :label "Name: " :geom-spec '(:top 30)))
                     (age-field
                       (make-text-gadget :label "Age: " :geom-spec '(:top 30)))
                     (dept-field
                       (make-text-gadget :label "Dept: " :geom-spec '(:top 30)))))
               (make-collection-gadget :geom-spec '(:bottom 0) :gm 'rubber-gm
                 :children
                   '((pb (make-button :value "Previous"
                                      :release-func '(get-emp :dir :prev)
                                      :base-size '(100 40)
                                      :geom-spec '(0 0 .5 .47 :center)))
                     (kb (make-pop-button :value "Name"
                                          :label "Search Key"
                                          :label-type :bottom
                                          :geom-spec '(.4 0 .2 1 :center)
                                          :items '("Name" "Age" "Dept")))
                     (nb (make-button :value "Next"
                                      :release-func '(get-emp :dir :next)
                                      :base-size '(100 40)
                                      :geom-spec '(0 .52 .5 .47 :center)))))))
            (gm 'packed-gm)
            (setup-code
              (progn (bind-slot 'value #!name-field '(var name #!employee))
                     (bind-slot 'value #!age-field '(var age #!employee))
                     (bind-slot 'value #!picture-gadget '(var #!picture))
                     (bind-slot 'value #!dept-field '(var #!dname))
                     (bind-slot 'dimmed #!pb `(prev-exists #!employee #!key))
                     (bind-var #!key `(make-keyword (var value ,#!kb)))
                     (bind-slot 'dimmed #!nb `(next-exists #!employee #!key)))))

                           Figure 7:  Form Definition
          ____________________________________________________________






                                       14










          _6.  _F_r_a_m_e_s, _D_i_a_l_o_g _B_o_x_e_s, _a_n_d _P_a_n_e_l_s

               Frames, dialog boxes, and  panels  are  callable  PO's.
          They  are  typically  called  in  response  to a user action
          (e.g., a menu selection or button press) as follows:

              (call _P_O :arg-1 _v_a_l_u_e :_a_r_g-_2 _v_a_l_u_e ...)

          The _P_O is specified by an expression  that  evaluates  to  a
          pointer that references the appropriate PICASSO object.  The
          expression is usually the internal PO name.  Parameters  are
          passed using Lisp keyword-value pairs.

               The semantics of calling a PO are:

          (1)  Fetch the PO from the database, if it is not already in
               memory.

          (2)  Bind the actual arguments to the formal arguments.

          (3)  Allocate and initialize local variables.

          (4)  Fetch the lexical children  of  the  PO  (e.g.,  forms,
               frames, etc.), if they are not already in memory.

          (5)  Execute the init-code for the PO.

          (6)  Display the object on the screen.

          (7)  Enter an event loop.

          PO's are cached in main memory to avoid the delays  inherent
          in  accessing  the  database.   Lexical children are fetched
          when the PO is called to improve the performance  of  subse-
          quent calls.  Recall that dynamic variables are allocated on
          each call and static variables are allocated when the PO  is
          created.  The event loop dispatches all events (e.g., mouse,
          keyboard, redraw, etc.) to the appropriate event handlers.

               The following code is executed to return from a PO:

              (ret _P_O _o_p_t_i_o_n_a_l-_r_e_t_u_r_n-_v_a_l_u_e)

          This code is executed in response to a user action (e.g.,  a
          menu  selection or button press) or because a lexical parent
          is cleaning up its children before exiting. The semantics of
          returning from a PO are:

          (1)  Force active lexical children to execute a return.

          (2)  Execute the exit-code.




                                       15











          ____________________________________________________________


          (defframe ("paper" "demo" . "frame") ()
            "This is the only frame of the Paper Demo application"
            (static-variables (employee department key))
            (panels ((dept-panel ("department" . "panel"))))
            (dialogs ((search-dialog ("search" . "dialog"))))
            (form (emp-form ("employee" . "form")))
            (menu-bar
              (("Show" "Show Joined Information"
                (dept-entry
                  ("Department"
                    (progn (call #!dept-panel :emp #?employee :dept #?department)
                           (setf (me-dimmed #!dept-entry) t))))
                  ("Others" nil :dimmed t))
                  ("Search" "Search Employee"
                    ("by Name..."
                      (setf #!employee
                            (get-emp :name (call #!search-dialog
                                                 :entity "name"))))
                    ("by Age..."
                      (setf #!employee
                            (get-emp :age (call #!search-dialog
                                                 :entity "age"))))
                    ("by Department..."
                      (setf #!employee
                            (get-emp :department (call #!search-dialog
                                                       :entity "department")))))))
            (setup-code
              (progn
                (setf #!employee (get-first-emp))
                (bind-var #?department `(department (var #!employee))))))

                          Figure 8:  Frame Definition
          ____________________________________________________________


          (3)  Conceal the PO which erases it from the screen.

          (4)  Copy result arguments back to the actual arguments.

          (5)  Re-enter the event loop of the calling PO.

               The remainder of this section, describes  how  callable
          PO's are defined.

          _6._1.  _F_r_a_m_e_s

               A frame can specify a named form or a set  of  children
          widgets  through  which  data will be displayed to the user.



                                       16










          Variables defined in  the  frame,  called  _f_r_a_m_e  _v_a_r_i_a_b_l_e_s,
          store  the  data on which the frame operates. Forms, panels,
          and dialog boxes in  the  frame  can  access  this  data  by
          referencing  the  frame variables or the frame can pass data
          to them as arguments.

               A frame is defined using the defframe construct. Figure
          9 shows the code that defines the frame in the sample appli-
          cation.  Two variables, two menus, a form, a  panel,  and  a
          dialog  box  are  defined  in  this  frame.   The  variables
          employee and department point to CLOS objects that represent
          an employee and his or her department.

               The menu-bar clause defines two menus: Show and Search.
          A  menu  specification  includes:  1)  the  menu name (e.g.,
          Search), 2) a long name that will be displayed at the top of
          the menu if it is torn off (e.g., Search Employee), and 3) a
          list of operation specifications.  An  operation  specifica-
          tion  includes:  1)  an  optional variable name for the menu
          (e.g., dept-entry in the Department operation  in  the  Show
          menu), 2) an operation name, 3) the code to execute when the
          operation is  selected,  and  4)  operation  options  (e.g.,
          dimmed,  left  or  right  string,  etc.).  The PICASSO menu,
          automatically supplied by the system, is the  leftmost  menu
          in  the  menu-bar.   It  contains operations that are useful
          everywhere (e.g., Help, PrintWindow, Quit, etc.).

               The Department operation in the  Show  menu  calls  the
          department  panel  and  passes  the  employee and department
          objects to it.  They are passed by reference so that changes
          made  in  the frame will be propagated to the panel and vice
          versa.  The operations in the Search menu change  the  order
          in which records are scanned.

          _6._2.  _D_i_a_l_o_g _B_o_x_e_s

               Dialog boxes are defined using the defdialog construct.
          The  code shown in figure 9 defines the search dialog box in
          the sample application.  The dialog box has a  single  value
          parameter,  named entity, that is set to a Lisp keyword that
          indicates the type of search being  performed  (e.g.,  :age)
          and a  variable, named  prompt-text, that is set to a string
          that indicates the type  (e.g., ``age'').   The  dialog  box
          has  an implicit form so it has children and gm clauses. Two
          buttons are specified: Ok and Cancel.  The set-up code binds
          prompt-text to type-in so the current sort attribute will be
          displayed.  The rest of the defdialog structure  is  similar
          to the other PO definitions.







                                       17











          ____________________________________________________________


               (defdialog ("paper" "search" . "dialog") (entity)
                 (dynamic-variables
                   ((prompt-text (concatenate 'string "Desired " #!entity))))
                 (children
                   ((type-in (make-entry-widget :value ""
                                                :self-adjusting t
                                                :geom-spec '(0 0 1 1 :center)))))
                 (buttons
                   (("Ok" (ret self (if (eql (value #!type-in) "")
                                    nil
                                    (value #!type-in)))
                     :default t)
                    ("Cancel" (ret self nil))))
                 (gm 'rubber-gm :conform 'grow-shrink)
                 (init-code (setf (value #!type-in) ""))
                 (setup-code
                   (progn (bind-slot 'label #!type-in `(var #!prompt-text)))))

                        Figure 9:  Dialog Box Definition
          ____________________________________________________________


          _6._3.  _P_a_n_e_l_s

               Panels are defined using the defpanel command. The code
          shown  in figure 10 defines the department panel in the sam-
          ple application.  The panel takes  two  reference  arguments
          (i.e.,  emp and dept) that point to the current employee and
          the employee's department.  Changes made to these  variables
          in  the panel are propagated to the variables in the calling
          frame.  Moreover, if the panel is active,  changes  made  to
          the frame variables are propagated to the panel.

               The remainder of the  definition  specifies  the  panel
          buttons  (e.g.,  Select Employee, Select Manager and Close),
          an implicit form, and bindings between the  variables,  form
          widgets, and menu operations.

          _7.  _P_r_o_g_r_a_m_m_i_n_g _C_o_n_s_t_r_u_c_t_s

               This section describes the programming constructs added
          to Lisp to simplify the development of PICASSO applications.
          Topics discussed include:  procedural  code,  variables  and
          constants, and bindings.







                                       18











          ____________________________________________________________


          (defpanel ("paper" "department" . "panel") (&ref emp dept)
            (title "Department Panel")
            (children
              ((bw
                 (make-browse-widget :geom-spec '(:top 100)
                                     :col-widths '(1 1.5)
                                     :sort-keys (list (cons "Department" #'dname)
                                                      (cons "Employee" #'name))
                                     :data *all_employees*))
               (make-collection-widget :gm 'rubber-gm :geom-spec '(:bottom 0)
                 :children
                   '((gg (make-image-gadget :geom-spec '(.55 0 .45 .99 :center)))
                     (dname-field
                       (make-text-gadget :label "Name:    "
                                         :geom-spec '(.25 0 .25 .33 :center-y)))
                     (floor-field
                       (make-text-gadget :label "Floor:   "
                                         :geom-spec '(.25 .33 .25 .34 :center-y)))
                     (manager-field
                       (make-text-gadget :label "Manager: "
                                         :geom-spec '(.25 .67 .25 .33 :center-y)))))))
            (gm 'packed-gm)
            (buttons
              ((sel-emp ('("Select" "Employee")
                          (get-emp :name (name (car (current-selection #!bw))))))
               (sel-mgr ('("Select" "Manager")
                          (get-emp :name (mgr #!emp))))
               (close   ("Close"
                          (progn (setf (me-dimmed #!dept-entry) nil)
                                 (ret #!po))))))
            (setup-code
              (progn
                (bind-slot 'dimmed #!sel-emp `(null (var current-selection ,#!bw)))
                (bind-slot 'dimmed #!sel-mgr `(null (var current-selection ,#!bw)))
                (bind-slot 'value #!dname-field '(var dname #!dept))
                (bind-slot 'value #!floor-field '(var floor #!dept))
                (bind-slot 'value #!manager-field '(var mgr #!dept))
                (bind-slot 'value #!gg `(var floor-plan #!emp))
                (bind-slot 'current-selection #!bw
                           `(progn (var #!dept) (var #!emp) nil)))))

                          Figure 10:  Panel Definition
          ____________________________________________________________


          _7._1.  _P_r_o_c_e_d_u_r_a_l _C_o_d_e





                                       19










               The environment in which procedural code is executed is
          defined by the PO that contains it (e.g., the frame for menu
          operations).  This  environment  includes   two   implicitly
          defined  Lisp  variables:  self and event.  Self is bound to
          the object that holds the code (e.g., the button, menu pane,
          or PO) and event is bound to a description of the event that
          caused the code to be executed  (e.g.,  a  ``button  press''
          event).  All PICASSO variable lookups are performed relative
          to the value of self.  For example, the code in the  Depart-
          ment  operation  in  the  Show  menu  in the frame calls the
          department panel as follows:

              (call #!dept-panel :emp #?employee :dept #?department)

          This code references three  PICASSO  variables:  dept-panel,
          employee,  and  department.   The  value  of dept-panel is a
          pointer to the panel object.  The addresses of employee  and
          department are passed to the panel because both arguments to
          the panel are reference parameters.[2]

          _7._2.  _V_a_r_i_a_b_l_e_s _a_n_d _C_o_n_s_t_a_n_t_s

               Variables  are  created  automatically  when  a  PO  is
          created  or  called.  All PO definitions can have clauses to
          define static- or dynamic-variables.   Static-variables  are
          created  when  the  PO is created.  Different invocations of
          the PO reference the same variables.  Dynamic-variables  are
          created when the PO is called.  Different invocations refer-
          ence different variables.

               Static-variables can be created by the  application  at
          run-time using the add-var function.  For example,

              (add-var _v_a_r_i_a_b_l_e-_n_a_m_e _p_l_a_c_e)

          creates a static-variable  named  _v_a_r_i_a_b_l_e-_n_a_m_e  in  the  PO
          specified  by  _p_l_a_c_e. The variable is immediately visible to
          lexical children of the PO.

               Named constants can be  specified  with  the  constants
          clause.   They  behave just like variables, except the value
          cannot be changed.  Named  constants  can  also  be  created
          implicitly in other clauses of a PO definition. For example,
          all lexical children of a PO (i.e., PO's  specified  in  the
          frames,  forms,  panels, or dialogs clauses) are given names
          ____________________
             [2] Most languages do not require the program to  specify
          the  address of reference parameters at the call.  This non-
          standard usage was required because our implementation  uses
          the Lisp evaluator to evaluate code.





                                       20










          that are constants in the parent PO. For  example,  emp-form
          and dept-panel are constants in the sample frame.

               Widgets specified in the children clause of a PO defin-
          ition  can also be bound to named constants by replacing the
          widget definition

              (make-widget _a_r_g_s)

          with a pair

              (_c_o_n_s_t_a_n_t-_n_a_m_e (make-widget _a_r_g_s))

          This construct creates a name  that  references  the  widget
          when  the PO is instantiated. The same technique can be used
          with buttons specified in panels and dialog boxes  and  with
          menus specified in frames or panels.

               Variables and constants are  referenced  by  using  the
          ``#!''  macro. The value of the variable is looked up in the
          current  environment.   As  described  above,  the   current
          environment  depends  on which PO is active and the location
          of the mouse cursor.  The setup, initialization, and  termi-
          nation  code is always executed in the context of the defin-
          ing PO.

               Once the current environment is  established,  variable
          lookup  proceeds  in a lexical fashion. The variables in the
          PO referenced by self are searched first, followed by the PO
          that  is the parent of self. Parent links are followed up to
          the tool. For ease of use, #!po always refers to the closest
          PO.  For example, it is the PO itself if the current lexical
          environment (i.e., self) points to a PO.  Otherwise,  it  is
          the  closest enclosing PO.  The variable #!po can be used in
          button or menu code to locate the enclosing  PO  since  self
          points to the button or menu entry.

               Sometimes it is necessary to specify where to look  for
          a  variable.   For  example,  a  frame's initialization code
          might define bindings between frame variables and widgets in
          the  enclosing form.  The syntax ``#!variable@place'' evalu-
          ates _p_l_a_c_e to find a starting point for the search for _v_a_r_i_-
          _a_b_l_e.  More  complicated  search  paths  can also be used to
          reference variables in different environments.  For example,
          the expression

              #!start-frame@(current-tool)/x

          references x _i_n _t_h_e _s_t_a_r_t-_f_r_a_m_e in the  current  tool.   Any
          number  of ``/''-_s_e_p_a_r_a_t_e_d _n_a_m_e_s _m_a_y _o_c_c_u_r. _T_h_e ``@'' clause
          can only be used on the  first  variable,  since  the  other
          names  are  located  based  on  the  value  of the preceding



                                       21










          expression. Notice that the location specifier in the  ``@''
          _c_l_a_u_s_e _c_a_n _b_e _a_n_y _L_i_s_p _e_x_p_r_e_s_s_i_o_n, _i_n_c_l_u_d_i_n_g _a _c_a_l_l, _i_n _t_h_i_s
          _c_a_s_e, _t_o _t_h_e _f_u_n_c_t_i_o_n _c_u_r_r_e_n_t-_t_o_o_l.

               Figure 11 shows a partial list of the variables defined
          in  the  sample tool and how they can be referenced when the
          current environment is the department panel.


          ____________________________________________________________






































                   Figure 11:  Non-local Variable References
          ____________________________________________________________





                                       22










          _7._3.  _B_i_n_d_i_n_g_s

               Bindings are used to maintain consistency between vari-
          ables  and values displayed to the user and to trigger other
          events when a variable is changed.  A function can be  bound
          to  any  PICASSO  variable  or  CLOS  object  slot that will
          automatically update the variable or slot when the value  of
          the  function  changes.  Selected variables and slots refer-
          enced in the functions are defined as varying.  The variable
          or  object  slot  is updated when one of these varying vari-
          ables or slots is changed.  For  example,  a  program  might
          have  variables that hold the first and last names of a per-
          son. A text widget can be used to display the full  name  by
          asserting

              (bind-slot 'value my-text-widget
                         `(concatenate 'string (var #!first-name)
                                               " "
                                               (var #!last-name)))

          This binding specifies that the  slot  named  value  in  the
          widget  my-text-widget should be bound to the result of con-
          catenating a person's first name, a space, and  his  or  her
          last name. Both names are marked as varying by the var func-
          tion.  The widget is updated whenever either name changes.

               a binding is a one-way  constraint.  A  change  in  the
          widget  does  not  update  the  variables. However, multiple
          bindings can be defined to implement a two  way  constraint.
          In  this  case, #!first-name can be bound to a function that
          extracts the first part  of  the  name  in  the  widget  and
          #!last-name  can  be  bound  to a function that extracts the
          last part of the name. Cycles in bindings are implemented by
          iterating  to  a fixed point value. The iteration terminates
          when the new value assigned to a variable  or  slot  is  the
          same as the current value.

               This binding mechanism is relatively simple, but it has
          proven extremely valuable in implementing user interfaces.

          _8.  _D_i_s_c_u_s_s_i_o_n

               This section describes our experiences implementing the
          PICASSO  framework,  some sample applications that have been
          implemented using it, and the current status of the system.

               It has taken approximately ten man-years  over  a  four
          year  period  to design and implement the framework.  During
          that time, we have implemented:

          (1)  a foreign function interface to X10 (XCL) [Mar87],




                                       23










          (2)  CLOS abstractions for X entities such as displays, win-
               dows, fonts, and colors (XCLOS) [Mar88],

          (3)  a low-level POSTGRES interface (libpq) [Wen89],

          (4)  a persistent CLOS interface to POSTGRES (SOH) [Wan88],

          (5)  two INGRES query language  interfaces  (CLING/QUEL  and
               CLING/SQL) [ChR89],

          (6)  two versions of the toolkit, and

          (7)  two versions of the framework.

          The first version of the toolkit used a heavyweight abstrac-
          tion  for a field that was implemented by one or more X win-
          dows.  For example, a labeled, type-in field used two X win-
          dows: one for the label and one for the field.  A third win-
          dow was created that contained these two  windows  when  the
          form  was  being  edited  so the user could select the field
          with a mouse and move it to a new location.   Unfortunately,
          this abstraction and implementation were too inefficient.

               The current toolkit provides widget and gadget abstrac-
          tions  that  can  be  used to implement fields.  Gadgets are
          used to implement display-only entities which  significantly
          reduces  the number of X windows that have to be created and
          mapped when calling a PO.  Decorative trim is an example  of
          a  display-only  entity (e.g., the floor plan in the depart-
          ment panel).  A label abstraction was added to  widgets  and
          gadgets  that stored the appropriate data about the label in
          one slot.  The label is represented by  a  display  function
          parameter  list  to  minimize  the  overhead of printing the
          label.  In addition, the geometry management abstraction and
          constraint system were implemented in this version.

               The first version of the application framework  treated
          fields  and variables as separate entities and implemented a
          customized propagation system to synchronize them.  And,  an
          interpreter  was  required  to  execute procedural code. The
          system was too slow.  This problem was accentuated  by  per-
          formance  problems  that we encountered in early implementa-
          tions of PCL which implements CLOS and the inherent speed of
          the  Sun-3/75's  and DEC Microvax-II's that we were using at
          the time.

               The current framework treats field names as  variables,
          directly  executes procedural code, and uses a better imple-
          mentation of PICASSO objects.  The parameter  passing  model
          was also introduced in this version.  Of course, performance
          was helped by the improved implementations of  PCL  and  the
          move  to Sun SPARCStation's and DECStation 3100's.  Run-time



                                       24










          space is currently a problem since  Common  Lisp  has  never
          been  particularly  space  efficient  and RISC architectures
          have almost doubled the code size.  However, we believe  the
          trade-off  of space for CPU speed is reasonable since memory
          prices are rapidly decreasing.  The  current  implementation
          requires 16 to 32 megabytes of main memory for most applica-
          tions.

               PICASSO has been used to implement several applications
          including:

          (1)  a facility management tool (FMTOOL) [RoS89],

          (2)  a  recipe  generator  for  process  engineers  (RGTOOL)
               [Lin89a],

          (3)  an educational tool to teach Lisp programming  (Robbie-
               the-Robot), and

          (4)  a direct manipulation forms editor.

          A screen dump of the facility management tool  is  shown  in
          figure 12.  The frame in the upper left corner shows a floor
          plan of the Berkeley Microlab.  The panel in the upper right
          corner contains two  hierarchical  browsers  that  list  the
          equipment  in the laboratory.  Users can select equipment by
          pointing at it with the mouse in the frame or  by  selecting
          it  in the panel and pressing the Add button.  The frame and
          panel are synchronized so that the equipment is  highlighted
          in  the  frame and moved to the hierarchical browser labeled
          ``Selected:'' regardless of how it is selected.  The  panels
          on  the  bottom  contain  lists  of utilities (e.g., oxygen,
          electrical, and water  lines)  and  lots  processed  in  the
          laboratory.   The  novel feature of the interface is that it
          allows arbitrary queries to be entered and executed  without
          requiring the user to type commands in a query language like
          SQL.  For example, the query ``list lots processed by equip-
          ment  connected  to  the  oxygen  line'' can be specified by
          selecting the oxygen line in the  utility  panel,  selecting
          the  equipment connected to it by an operation in the Select
          menu, and selecting lots  processed  by  that  equipment  by
          another  operation  in the same menu.  All data is stored in
          an INGRES database.  This application requires approximately
          3,000  lines  of  code in PICASSO.  It was written by one of
          the authors (Smith) in approximately two weeks.

               The PICASSO toolkit  and  framework  contains  approxi-
          mately  35,000  lines of Lisp code of which only 3,000 lines
          are required to implement the framework.  We  have  recently
          ported the system to X11 and are now using the CLX interface
          [ScL89].  The system is  being  distributed  to  adventurous
          users at other sites.



                                       25











          ____________________________________________________________





































              Figure 12: A Semiconductor Facility Management Tool.
          ____________________________________________________________


          _9.  _C_o_n_c_l_u_s_i_o_n

               The PICASSO application framework provides higher level
          abstractions  for  creating  user interfaces.  Familiar pro-
          gramming language constructs (e.g., lexically  scoped  vari-
          ables,  call/return  semantics,  and  parameter passing) are
          used to specify procedural code and control-flow.  A  simple
          constraint  system  is used to synchronize variables and the
          toolkit widgets through which they are displayed to the user



                                       26










          and  to trigger other code when appropriate.  Several appli-
          cations have  been  developed  using  the  toolkit  and  our
          experience thus far has been positive.


                                Acknowledgements


          Many people have worked on the design and implementation  of
          PICASSO.  Dave Martin developed the XCL package and the ori-
          ginal CLOS abstractions for the  X  Window  System.   Donald
          Chinn,  Ken  Whaley,  and  Scott  Hauck  worked on the early
          infrastructure and the first version of the toolkit.   Scott
          Luebking extended the toolkit and implemented the first ver-
          sion of the framework.  The current version of  the  toolkit
          and  framework are major revisions of these earlier systems.
          We also want to thank our  early  users,  including  Beverly
          Becker, Jeff Goh, William Hunter, K.K. Lin, and Lay-Peng Ong
          who have suffered from  a  buggy,  slow  system  that  never
          seemed to work as well for them as it did for us.



































                                       27










                                   _R_e_f_e_r_e_n_c_e_s



          [Bar86]   P.  S.  Barth,  "An  Object-Oriented  Approach  to
                    Graphical Interfaces", _A_C_M _T_r_a_n_s. _o_n _G_r_a_p_h_i_c_s _5, 2
                    (Apr. 1986).

          [ChR89]   D. Charness and L. Rowe, _C_L_I_N_G/_S_Q_L -  _C_o_m_m_o_n  _L_I_S_P
                    _t_o _I_N_G_R_E_S/_S_Q_L _I_n_t_e_r_f_a_c_e, Computer Science Division
                    - EECS, U.C. Berkeley, Dec. 1989.

          [Gol83]   A.   Goldberg,   _S_m_a_l_l_t_a_l_k-_8_0:   _T_h_e   _I_n_t_e_r_a_c_t_i_v_e
                    _P_r_o_g_r_a_m_m_i_n_g  _E_n_v_i_r_o_n_m_e_n_t, Addison Wesley, Reading,
                    MA, May 1983.

          [Kee88]   S. Keene, _O_b_j_e_c_t-_O_r_i_e_n_t_e_d  _P_r_o_g_r_a_m_m_i_n_g  _i_n  _C_o_m_m_o_n
                    _L_i_s_p, Addison-Wesley, 1988.

          [Koe90]   J. Konstan and et. al., PICASSO _R_e_f_e_r_e_n_c_e  _M_a_n_u_a_l,
                    Computer  Science  Division - EECS, U.C. Berkeley,
                    May 1990.

          [KrP88]   G. E. Krasner and S. T. Pope, _A _D_e_s_c_r_i_p_t_i_o_n _o_f _t_h_e
                    _M_o_d_e_l-_V_i_e_w-_C_o_n_t_r_o_l_l_e_r  _U_s_e_r  _I_n_t_e_r_f_a_c_e _P_a_r_a_d_i_g_m _i_n
                    _t_h_e _S_m_a_l_l_t_a_l_k-_8_0 _S_y_s_t_e_m_s, ParcPlace Systems,  Aug.
                    1988.

          [Lin89a]  K. K. Lin, personal communication, Nov. 1989.

          [Lin89b]  M. A.  Linton,  "Composing  User  Interfaces  with
                    InterViews", _I_E_E_E _C_o_m_p_u_t_e_r, Feb. 1989.

          [Mae89]   J. H. Maloney and et. al., "Constraint  Technology
                    for  User-Interface  Construction in Thinglab II",
                    _P_r_o_c. _O_O_P_S_L_A '_8_9, New Orleans, LA , Oct. 1989.

          [Mar87]   D. C.  Martin,  _X_C_L  -  _C_o_m_m_o_n  _L_I_S_P  _X  _I_n_t_e_r_f_a_c_e
                    (_P_r_o_t_o_c_o_l _V_e_r_s_i_o_n _1_0), Computer Science Division -
                    EECS, U.C. Berkeley, Apr. 1987.

          [Mar88]   D.  C.  Martin,  _X/_C_o_m_m_o_n   _L_I_S_P   _O_b_j_e_c_t   _S_y_s_t_e_m
                    _I_n_t_e_r_f_a_c_e,  Computer Science Division - EECS, U.C.
                    Berkeley, June 1988.

          [Mye89]   B. Myers and et. al., _T_h_e _G_a_r_n_e_t _T_o_o_l_k_i_t _R_e_f_e_r_e_n_c_e
                    _M_a_n_u_a_l_s: _S_u_p_p_o_r_t _f_o_r _H_i_g_h_l_y _I_n_t_e_r_a_c_t_i_v_e, _G_r_a_p_h_i_c_a_l
                    _U_s_e_r _I_n_t_e_r_f_a_c_e_s _i_n  _L_i_s_p,  Technical  Report  CMU,
                    Pittsburgh,      PA-CS-89-196,     Carnegie-Mellon
                    University, Nov. 1989.





                                       28










          [RoS89]   L. A. Rowe and B. Smith,  "A  Facility  Management
                    Tool (Video Tape)", _D_A_R_P_A/_S_R_C _C_I_M-_I_C _W_o_r_k_s_h_o_p, Ann
                    Arbor, MI, Aug. 1989.

          [ScG86]   R. W. Scheifler  and  J.  Gettys,  "The  X  Window
                    System", _A_C_M _T_r_a_n_s. _o_n _G_r_a_p_h_i_c_s _5, 2 (Apr. 1986).

          [ScL89]   R. W. Scheifler and O.  LaMott,  _C_L_X  _P_r_o_g_r_a_m_m_e_r'_s
                    _R_e_f_e_r_e_n_c_e, Texas Instruments, 1989.

          [Sch86]   K.   J.   Schmucker,   "MacApp:   An   Application
                    Framework", _B_y_t_e, Aug. 1986.

          [Wan88]   Y. Wang, _T_h_e _P_i_c_a_s_s_o _S_h_a_r_e_d _O_b_j_e_c_t  _H_i_e_r_a_r_c_h_y,  MS
                    Report,  Computer  Science  Division  - EECS, U.C.
                    Berkeley, June 1988.

          [Wen89]   S.   Wensel,    "POSTGRES    Reference    Manual",
                    _E_l_e_c_t_r_o_n_i_c_s  _R_e_s_e_a_r_c_h _L_a_b. _T_e_c_h_n_i_c_a_l _R_e_p_o_r_t _M_8_8/_2_0
                    (_R_e_v_i_s_e_d), Apr. 1989.



































                                       29



